📄 layoutcell.java
字号:
// Point2D oldTailPt = ai.getTailLocation();// double oldHeadX = oldHeadPt.getX(); double oldHeadY = oldHeadPt.getY();// double oldTailX = oldTailPt.getX(); double oldTailY = oldTailPt.getY(); // now make the change ImmutableArcInst oldD = ai.getD(); ImmutableArcInst d = oldD; d = d.withLocations(EPoint.snap(tailPt), EPoint.snap(headPt)); ai.lowLevelModify(d); if (Layout.DEBUG) System.out.println(ai + " now runs from tail ("+ ai.getTailLocation().getX()+","+ai.getTailLocation().getY()+") to head ("+ ai.getHeadLocation().getX()+","+ai.getHeadLocation().getY()+")"); // if the arc hasn't changed yet, record this change if (oldArcs == null || !oldArcs.containsKey(ai)) { Constraints.getCurrent().modifyArcInst(ai, oldD); // Is it necessary ? setChangeClock(ai, arctyp); } } /** * Method to move the coordinates of the ends of an ArcInst. * If the arc cannot be moved in this way, it will be broken up into 3 jogged arcs. * @param ai the ArcInst to adjust * @param headPt the new coordinates of the head of the ArcInst. * @param tailPt the new coordinates of the tail of the ArcInst. * @param arctyp the nature of the arc: 0 for rigid, 1 for flexible. */ private void doMoveArcInst(ArcInst ai, Point2D headPt, Point2D tailPt, Integer arctyp) { // check for null arcinst motion if (headPt.equals(ai.getHeadLocation()) && tailPt.equals(ai.getTailLocation())) { // only ignore null motion on fixed-angle requests if (arctyp.intValue() != 0) return; } // if the angle is the same or doesn't need to be, simply make the change if (!ai.isFixedAngle() || Layout.isRigid(ai) || headPt.equals(tailPt) || (ai.getAngle() % 1800) == (DBMath.figureAngle(tailPt, headPt) % 1800)) { updateArc(ai, headPt, tailPt, arctyp); return; } // manhattan arcinst becomes nonmanhattan: remember facts about it if (Layout.DEBUG) System.out.println("Jogging arc"); PortInst fpi = ai.getHeadPortInst();// NodeInst fno = fpi.getNodeInst(); PortProto fpt = fpi.getPortProto(); PortInst tpi = ai.getTailPortInst();// NodeInst tno = tpi.getNodeInst(); PortProto tpt = tpi.getPortProto(); ArcProto ap = ai.getProto(); Cell pnt = ai.getParent(); double wid = ai.getLambdaBaseWidth();// double wid = ai.getLambdaFullWidth(); // figure out what nodeinst proto connects these arcs PrimitiveNode np = ap.findOverridablePinProto(); double psx = np.getDefWidth(); double psy = np.getDefHeight(); // replace it with three arcs and two nodes NodeInst no1 = null, no2 = null; if (DBMath.doublesEqual(ai.getHeadLocation().getX(), ai.getTailLocation().getX())) { // arcinst was vertical double oldyA = (tailPt.getY()+headPt.getY()) / 2; double oldyB = oldyA; double oldxA = headPt.getX(); double oldxB = tailPt.getX(); no1 = NodeInst.newInstance(np, new Point2D.Double(oldxB, oldyB),psx, psy, pnt); no2 = NodeInst.newInstance(np, new Point2D.Double(oldxA, oldyA),psx, psy, pnt); } else { // assume horizontal arcinst double oldyA = headPt.getY(); double oldyB = tailPt.getY(); double oldxA = (tailPt.getX()+headPt.getX()) / 2; double oldxB = oldxA; no1 = NodeInst.newInstance(np, new Point2D.Double(oldxB, oldyB),psx, psy, pnt); no2 = NodeInst.newInstance(np, new Point2D.Double(oldxA, oldyA),psx, psy, pnt); } if (no1 == null || no2 == null) { System.out.println("Problem creating jog pins"); return; } PortInst no1pi = no1.getOnlyPortInst(); Rectangle2D no1Bounds = no1pi.getPoly().getBounds2D(); Point2D no1Pt = new Point2D.Double(no1Bounds.getCenterX(), no1Bounds.getCenterY()); PortInst no2pi = no2.getOnlyPortInst(); Rectangle2D no2Bounds = no2pi.getPoly().getBounds2D(); Point2D no2Pt = new Point2D.Double(no2Bounds.getCenterX(), no2Bounds.getCenterY()); int arcFlags = ai.getD().flags; String arcName = ai.getName(); ai.kill(); // !!! See ai2.copyVarsFrom(ai) below int flags1 = ImmutableArcInst.TAIL_NEGATED.set(arcFlags, false); ArcInst ar1 = ArcInst.newInstanceBase(ap, wid, fpi, no2pi, headPt, no2Pt, null, 0, flags1); if (ar1 == null) return;// ar1.copyConstraintsFrom(ai);// if (ai.isHeadNegated()) ar1.setHeadNegated(true); int flags2 = ImmutableArcInst.TAIL_NEGATED.set(arcFlags, false); flags2 = ImmutableArcInst.HEAD_NEGATED.set(flags2, false); ArcInst ar2 = ArcInst.newInstanceBase(ap, wid, no2pi, no1pi, no2Pt, no1Pt, arcName, 0, flags2); if (ar2 == null) return; ar2.copyVarsFrom(ai); // !!! Referencing killed ai may cause problem in future versions ar2.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME);// ar2.copyPropertiesFrom(ai); int flags3 = ImmutableArcInst.HEAD_NEGATED.set(arcFlags, false); ArcInst ar3 = ArcInst.newInstanceBase(ap, wid, no1pi, tpi, no1Pt, tailPt, null, flags3); if (ar3 == null) return;// ar3.copyConstraintsFrom(ai);// if (ai.isTailNegated()) ar3.setTailNegated(true); if (ar1 == null || ar2 == null || ar3 == null) { System.out.println("Problem creating jog arcs"); return; }// ar2.copyVarsFrom(ai);// ar2.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME_TD); setChangeClock(ar1, arctyp); setChangeClock(ar2, arctyp); setChangeClock(ar3, arctyp); // now kill the arcinst// ar2.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME);// ai.kill();// String oldName = ai.getName();// if (oldName != null) ar2.setName(oldName); } /** * Method to return transformation matrix which * transforms old geometry of portinst "pi" to the new one. * * there are only two types of nodeinst changes: internal and external. * The internal changes are scaling and port motion changes that * are usually caused by other changes within the cell. The external * changes are rotation and transposition. These two changes never * occur at the same time. There is also translation change that * can occur at any time and is of no importance here. What is * important is that the transformation matrix "trans" handles * the external changes and internal changes. External changes are already * set by the "makeangle" method and internal changes are * built into the matrix here. */ private AffineTransform transformByPort(PortInst pi) { NodeInst ni = pi.getNodeInst(); ImmutableNodeInst d = getOldD(ni); // Identity transform for newly created nodes if (d == null) return new AffineTransform(); if (!ni.getOrient().equals(d.orient)) { Orientation dOrient = ni.getOrient().concatenate(d.orient.inverse()); return dOrient.rotateAbout(ni.getAnchorCenterX(), ni.getAnchorCenterY(), -d.anchor.getX(), -d.anchor.getY()); } // nodeinst did not rotate or mirror: adjust for port motion or sizing PortProto pp = pi.getPortProto(); Poly oldPoly = Layout.oldPortPosition(pi); Poly curPoly = ni.getShapeOfPort(pp); if (oldPoly == null || pp instanceof PrimitivePort && ((PrimitivePort)pp).isIsolated()) oldPoly = curPoly; double scaleX = 1; double scaleY = 1; // Zero means flat port or artwork. Valid for new technology if (oldPoly.getBounds2D().getWidth() > 0) scaleX = curPoly.getBounds2D().getWidth() / oldPoly.getBounds2D().getWidth(); if (oldPoly.getBounds2D().getHeight() >0) scaleY = curPoly.getBounds2D().getHeight() / oldPoly.getBounds2D().getHeight(); double newX = curPoly.getCenterX() - oldPoly.getCenterX()*scaleX; double newY = curPoly.getCenterY() - oldPoly.getCenterY()*scaleY; return new AffineTransform(scaleX, 0, 0, scaleY, newX, newY); } /*-- Change clock stuff --*/ private void setChangeClock(Geometric geom, Integer typ) {// if (typ != null)// changeClock.put(geom, typ);// else// changeClock.remove(geom); }//// private int getChangeClock(Geometric geom) {// Integer i = changeClock.get(geom);// return i != null ? i.intValue() : Integer.MIN_VALUE;// } /** * Method to announce a change to a NodeInst. * @param ni the NodeInst that was changed. * @param oD the old contents of the NodeInst. */ void modifyNodeInst(NodeInst ni, ImmutableNodeInst oldD) { modified = true; if (!oldNodes.containsKey(ni)) oldNodes.put(ni, oldD); } /** * Method to announce a change to an ArcInst. * @param ai the ArcInst that changed. * @param oD the old contents of the ArcInst. */ void modifyArcInst(ArcInst ai, ImmutableArcInst oldD) { modified = true; if (oldArcs == null) oldArcs = new HashMap<ArcInst,ImmutableArcInst>(); if (!oldArcs.containsKey(ai)) oldArcs.put(ai, oldD); } /** * Method to announce a change to an Export. * @param pp the Export that moved. * @param oldPi the old PortInst on which it resided. */ void modifyExport(Export pp, PortInst oldPi) { exportsModified = true; if (oldExports == null) oldExports = new HashMap<Export,PortInst>(); if (!oldExports.containsKey(pp)) oldExports.put(pp, oldPi); } /** * Method to announce the creation of a new ElectricObject. * @param obj the ElectricObject that was just created. */ void newObject(ElectricObject obj) { if (obj instanceof Export) { if (oldExports == null) oldExports = new HashMap<Export,PortInst>(); assert !oldExports.containsKey(obj); oldExports.put((Export)obj, null); } else if (obj instanceof NodeInst) { assert !oldNodes.containsKey(obj); oldNodes.put((NodeInst)obj, null); } else if (obj instanceof ArcInst) { if (oldArcs == null) oldArcs = new HashMap<ArcInst,ImmutableArcInst>(); assert !oldArcs.containsKey(obj); oldArcs.put((ArcInst)obj, null); } } PortInst getOldOriginalPort(Export e) { if (oldExports == null || !oldExports.containsKey(e)) return e.getOriginalPort(); return oldExports.get(e); } ImmutableNodeInst getOldD(NodeInst ni) { if (oldNodes == null || !oldNodes.containsKey(ni)) return ni.getD(); return oldNodes.get(ni); } boolean arcMoved(ArcInst ai) { if (oldArcs == null || !oldArcs.containsKey(ai)) return false; ImmutableArcInst oldD = oldArcs.get(ai); if (oldD == null) return false; return ai.getHeadLocation() != oldD.headLocation || ai.getTailLocation() != oldD.tailLocation; } private boolean hasExports(NodeInst ni) { return m.hasExports(ni.getD().nodeId); } /** * Method to return an Iterator over all Connections on this NodeInst. * @return an Iterator over all Connections on this NodeInst. */ private Iterator<Connection> getConnections(NodeInst ni) { return new ConnectionIterator(ni.getD().nodeId); } /** * Method to return an Iterator over Connections on this PortInst since portIndex. * @return an Iterator over Connections on this NodeInst since portIndex. */ Iterator<Connection> getConnections(PortInst pi) { return new ConnectionIterator(pi.getNodeInst().getD().nodeId, pi.getPortProto().getId().getChronIndex()); } private class ConnectionIterator implements Iterator<Connection> { private final ImmutableArrayList<ImmutableArcInst> arcs; private final int nodeId; private final int chronIndex; int i; ArcInst nextAi; int nextConnIndex; ConnectionIterator(int nodeId) { arcs = m.getArcs(); chronIndex = -1; this.nodeId = nodeId; i = m.searchConnectionByPort(nodeId, 0); findNext(); } ConnectionIterator(int nodeId, int chronIndex) { arcs = m.getArcs(); this.nodeId = nodeId; this.chronIndex = chronIndex; i = m.searchConnectionByPort(nodeId, chronIndex); findNext(); } public boolean hasNext() { return nextAi != null; } public Connection next() { if (nextAi == null) throw new NoSuchElementException(); Connection con = nextAi.getConnection(nextConnIndex); findNext(); return con; } public void remove() { throw new UnsupportedOperationException(); } private void findNext() { for (; i < m.connections.length; i++) { int con = m.connections[i]; ImmutableArcInst a = arcs.get(con >>> 1); int endIndex = con & 1; int endNodeId = endIndex != 0 ? a.headNodeId : a.tailNodeId; if (endNodeId != nodeId) break; if (chronIndex >= 0) { PortProtoId endProtoId = endIndex != 0 ? a.headPortId : a.tailPortId; if (endProtoId.getChronIndex() != chronIndex) break; } ArcInst ai = cell.getArcById(a.arcId); if (ai != null) { nextAi = ai; nextConnIndex = endIndex; i++; return; } } nextAi = null; } }}// private HashMap/*<NodeInst,RigidCluster>*/ makeRigidClusters() {// TransitiveRelation rel = new TransitiveRelation();// for (Iterator it = cell.getArcs(); it.hasNext(); ) {// ArcInst ai = it.next();// if (Layout.isRigid(ai))// rel.theseAreRelated(ai.getHeadPortInst().getNodeInst(), ai.getTailPortInst().getNodeInst());// }// HashMap/*<NodeInst,RigidCluster>*/ nodeClusters = new HashMap/*<NodeInst,RigidCluster>*/();// for (Iterator it = cell.getNodes(); it.hasNext(); ) {// NodeInst ni = it.next();// rel.theseAreRelated(ni, ni);// RigidCluster rc = nodeClusters.get(ni);// if (rc == null) {// rc = new RigidCluster();// for (Iterator rIt = rel.getSetsOfRelatives(); rIt.hasNext(); ) {// NodeInst rNi = rIt.next();// rc.add(rNi);// nodeClusters.put(rNi, rc);// }// }// ImmutableNodeInst d = ni.getOldD();// if (d != null && !(d.anchor.equals(ni.getAnchorCenter()) && d.orient.equals(ni.getOrient()))) {// rc.touched = true;// rc.locked = true;// }// if (ni.isCellInstance()) {// LayoutCell ci = Layout.getCellInfo((Cell)ni.getProto());// if (ci.exportsModified) rc.touched = true;// } else if (d != null && (d.width != ni.getXSize() || d.height != ni.getYSize())) {// rc.touched = true;// }// }// return nodeClusters;// }////class RigidCluster {// boolean touched;// boolean locked;// HashSet/*<NodeInst>*/ nodes = new HashSet/*<NodeInst>*/();//// void add(NodeInst ni) { nodes.add(ni); }//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -