📄 immutablenodeinst.java
字号:
// /**// * Returns flags of this ImmutableNodeInst.// * This flags are defined by ImmutableNodeInst.Flag .// * @return flags of this ImmutableNodeInst.// */// public int getFlags() { return flags; } /** * Tests specific flag is set on this ImmutableNodeInst. * @param flag flag selector. * @return true if specific flag is set, */ public boolean is(Flag flag) { return flag.is(flags); }// /**// * Method to return the Technology-specific value on this ImmutableNodeInst.// * This is mostly used by the Schematics technology which allows variations// * on a NodeInst to be stored.// * For example, the Transistor primitive uses these bits to distinguish nMOS, pMOS, etc.// * @return the Technology-specific value on this ImmutableNodeInst.// */// public byte getTechSpecific() { return techBits; } Variable[] getDefinedParams() { return Variable.NULL_ARRAY; } /** * Writes this ImmutableNodeInst to IdWriter. * @param writer where to write. */ @Override void write(IdWriter writer) throws IOException { writer.writeNodeId(nodeId); writer.writeNodeProtoId(protoId); writer.writeNameKey(name); writer.writeTextDescriptor(nameDescriptor); writer.writeOrientation(orient); writer.writePoint(anchor); writer.writePoint(size); writer.writeInt(flags); writer.writeByte(techBits); writer.writeTextDescriptor(protoDescriptor); for (int i = ports.length - 1; i >= 0; i--) { if (ports[i] == ImmutablePortInst.EMPTY) continue; writer.writeInt(i); ports[i].writeVars(writer); } writer.writeInt(-1); super.write(writer); } /** * Reads ImmutableNodeInst from SnapshotReader. * @param reader where to read. */ static ImmutableNodeInst read(IdReader reader) throws IOException { int nodeId = reader.readNodeId(); NodeProtoId protoId = reader.readNodeProtoId(); Name name = reader.readNameKey(); TextDescriptor nameDescriptor = reader.readTextDescriptor(); Orientation orient = reader.readOrientation(); EPoint anchor = reader.readPoint(); EPoint size = reader.readPoint(); int flags = reader.readInt(); byte techBits = reader.readByte(); TextDescriptor protoDescriptor = reader.readTextDescriptor(); ImmutablePortInst[] ports = ImmutablePortInst.NULL_ARRAY; for (;;) { int i = reader.readInt(); if (i == -1) break; if (i >= ports.length) { ImmutablePortInst[] newPorts = new ImmutablePortInst[i + 1]; System.arraycopy(ports, 0, newPorts, 0, ports.length); Arrays.fill(newPorts, ports.length, newPorts.length, ImmutablePortInst.EMPTY); ports = newPorts; } ports[i] = ImmutablePortInst.read(reader); } boolean hasVars = reader.readBoolean(); Variable[] vars = hasVars ? readVars(reader) : Variable.NULL_ARRAY; Variable[] params = Variable.NULL_ARRAY; if (protoId instanceof CellId && ((CellId)protoId).isIcon()) params = readVars(reader); return newInstance(nodeId, protoId, name, nameDescriptor, orient, anchor, size, flags, techBits, protoDescriptor, vars, ports, params); } /** * Return a hash code value for fields of this object. * Variables of objects are not compared */ public int hashCodeExceptVariables() { return nodeId; } /** * Indicates whether fields of other ImmutableElectricObject are equal to fileds of this object. * Variables of objects are not compared. * @param o other ImmutableElectricObject. * @return true if fields of objects are equal. */ public boolean equalsExceptVariables(ImmutableElectricObject o) { if (this == o) return true; if (!(o instanceof ImmutableNodeInst)) return false; ImmutableNodeInst that = (ImmutableNodeInst)o; return this.nodeId == that.nodeId && this.protoId == that.protoId && this.name == that.name && this.nameDescriptor == that.nameDescriptor && this.orient == that.orient && this.anchor == that.anchor && this.size == that.size && this.flags == that.flags && this.techBits == that.techBits && this.protoDescriptor == that.protoDescriptor; } /** * Checks invariant of this ImmutableNodeInst. * @throws AssertionError if invariant is broken. */ public void check() { super.check(false); assert nodeId >= 0; assert protoId != null; boolean isIcon = protoId instanceof CellId && ((CellId)protoId).isIcon(); assert getClass() == (isIcon ? ImmutableIconInst.class : ImmutableNodeInst.class); assert name != null; assert name.isValid() && !name.hasEmptySubnames(); assert !(name.isTempname() && name.isBus()); assert !name.hasDuplicates(); if (nameDescriptor != null) assert nameDescriptor.isDisplay() && !nameDescriptor.isParam(); assert orient != null; assert anchor != null; assert size != null;// assert size.getGridX() >= 0;// assert size.getGridY() >= 0; assert (flags & ~FLAG_BITS) == 0; assert (techBits & ~(NTECHBITS >> NTECHBITSSH)) == 0; if (protoDescriptor != null) assert protoDescriptor.isDisplay() && !protoDescriptor.isParam(); if (protoId instanceof CellId) { assert size == EPoint.ORIGIN; } if (isCellCenter(protoId)) { assert orient == Orientation.IDENT && anchor == EPoint.ORIGIN && size == EPoint.ORIGIN; } for (int i = 0; i < ports.length; i++) { ImmutablePortInst portInst = ports[i]; if (portInst.getNumVariables() != 0) portInst.check(); else assert portInst == ImmutablePortInst.EMPTY; } if (ports.length > 0) assert ports[ports.length - 1].getNumVariables() > 0; } public static boolean isCellCenter(NodeProtoId protoId) { if (!(protoId instanceof PrimitiveNodeId)) return false; return ((PrimitiveNodeId)protoId).fullName.equals("generic:Facet-Center"); } /** * Returns ELIB user bits of this ImmutableNodeInst in ELIB. * @return ELIB user bits of this ImmutableNodeInst. */ public int getElibBits() { return flags | (techBits << NTECHBITSSH); } /** * Get flag bits from ELIB user bits. * @param elibBits ELIB user bits. * @return flag bits. */ public static int flagsFromElib(int elibBits) { return elibBits & FLAG_BITS; } /** * Get tech specific bits from ELIB user bits. * @param elibBits ELIB user bits. * @return tech specific bits. */ public static int techSpecificFromElib(int elibBits) { return (elibBits & NTECHBITS) >> NTECHBITSSH; } public void computeBounds(NodeInst real, Rectangle2D.Double dstBounds) { // handle cell bounds if (protoId instanceof CellId) { // offset by distance from cell-center to the true center Cell subCell = (Cell)real.getProto(); Rectangle2D bounds = subCell.getBounds(); orient.rectangleBounds(bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY(), anchor.getX(), anchor.getY(), dstBounds); return; } // if zero size, set the bounds directly PrimitiveNode pn = real.getTechPool().getPrimitiveNode((PrimitiveNodeId)protoId); assert pn == real.getProto(); ERectangle full = pn.getFullRectangle(); long gridWidth = size.getGridX() + full.getGridWidth(); long gridHeight = size.getGridY() + full.getGridHeight(); if (gridWidth == 0 && gridHeight == 0) { dstBounds.setRect(anchor.getX(), anchor.getY(), 0, 0); return; } double lambdaWidth = DBMath.gridToLambda(gridWidth); double lambdaHeight = DBMath.gridToLambda(gridHeight); // special case for arcs of circles if (pn == Artwork.tech().circleNode || pn == Artwork.tech().thickCircleNode) { // see if this circle is only a partial one double [] angles = real.getArcDegrees(); if (angles[0] != 0.0 || angles[1] != 0.0) { Point2D [] pointList = Artwork.fillEllipse(anchor, lambdaWidth, lambdaHeight, angles[0], angles[1]); Poly poly = new Poly(pointList); poly.setStyle(Poly.Type.OPENED); poly.transform(orient.rotateAbout(anchor.getX(), anchor.getY())); dstBounds.setRect(poly.getBounds2D()); return; } } // special case for pins that become steiner points if (pn.isWipeOn1or2()) { // schematic bus pins are so complex that only the technology knows their true size if (real.getProto() == Schematics.tech().busPinNode) { Poly [] polys = Schematics.tech().getShapeOfNode(real); if (polys.length > 0) { Rectangle2D bounds = polys[0].getBounds2D(); dstBounds.setRect(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight()); return; } } if (!real.hasExports() && real.pinUseCount())// if (real.getNumExports() == 0 && real.pinUseCount()) { dstBounds.setRect(anchor.getX(), anchor.getY(), 0, 0); return; } } // special case for polygonally-defined nodes: compute precise geometry if (pn.isHoldsOutline() && real.getTrace() != null) { AffineTransform trans = orient.rotateAbout(anchor.getX(), anchor.getY()); Poly[] polys = pn.getTechnology().getShapeOfNode(real); for (int i = 0; i < polys.length; i++) { Poly poly = polys[i]; poly.transform(trans); if (i == 0) dstBounds.setRect(poly.getBounds2D()); else Rectangle2D.union(poly.getBounds2D(), dstBounds, dstBounds); } return; } // normal bounds computation double halfWidth = lambdaWidth*0.5; double halfHeight = lambdaHeight*0.5; orient.rectangleBounds(-halfWidth, -halfHeight, halfWidth, halfHeight, anchor.getX(), anchor.getY(), dstBounds); } /** * Method to return the "outline" information on this ImmutableNodeInst. * Outline information is a set of coordinate points that further * refines the NodeInst description. It is typically used in * Artwork primitives to give them a precise shape. It is also * used by pure-layer nodes in all layout technologies to allow * them to take any shape. It is even used by many MOS * transistors to allow a precise gate path to be specified. * @return an array of EPoint in database coordinates. */ public EPoint [] getTrace() { Variable var = getVar(NodeInst.TRACE); if (var == null) return null; Object obj = var.getObject(); if (obj instanceof EPoint[]) return (EPoint[])obj; return null; } /** * Method to return the length of this serpentine transistor. * @return the transistor's length * Returns -1 if this is not a serpentine transistor, or if the length cannot be found. */ public double getSerpentineTransistorLength() { Variable var = getVar(NodeInst.TRANSISTOR_LENGTH_KEY); if (var == null) return -1; Object obj = var.getObject(); if (obj instanceof Integer) { // C Electric stored this as a "fraction", scaled by 120 return ((Integer)obj).intValue() / 120; } if (obj instanceof Double) { return ((Double)obj).doubleValue(); } if (obj instanceof String) { return TextUtils.atof((String)obj); } return -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -