📄 cell.java
字号:
// } /** * Method to set the characteristic spacing for this Cell. * The characteristic spacing is used by the Array command to space these cells sensibly. * @param x the characteristic width. * @param y the characteristic height. */// public void setCharacteristicSpacing(double x, double y)// {// Double [] newVals = new Double[2];// newVals[0] = new Double(x);// newVals[1] = new Double(y);// newVar(CHARACTERISTIC_SPACING, newVals);// } /** * Method to indicate that the bounds of this Cell are incorrect because * a node or arc has been created, deleted, or modified. */ public void setDirty() { setDirty(BOUNDS_RECOMPUTE); } /** * Method to indicate that the bounds of this Cell are incorrect because * a node or arc may have been modified. */ public void setGeomDirty() { setDirty(BOUNDS_CORRECT_GEOM); } /** * Debug method to check that bound dirty flag is clear */ void checkBoundsCorrect() { assert boundsDirty == BOUNDS_CORRECT; for (NodeInst ni: nodes) { if (ni.isCellInstance()) { Cell subCell = (Cell)ni.getProto(); assert subCell.boundsDirty == BOUNDS_CORRECT; } } } /** * Method to indicate that the bounds of this Cell are incorrect because * a node or arc has been created, deleted, or modified. */ private void setDirty(byte boundsLevel) { unfreshRTree(); if (boundsDirty == BOUNDS_CORRECT) { boundsDirty = boundsLevel; for (Iterator<CellUsage> it = getUsagesOf(); it.hasNext(); ) { CellUsage u = it.next(); u.getParent().setDirty(BOUNDS_CORRECT_SUB); } } else if (boundsDirty < boundsLevel) boundsDirty = boundsLevel; } /** * Method to return an interator over all RTBounds objects in a given area of this Cell. * @param bounds the specified area to search. * @return an iterator over all of the RTBounds objects in that area. */ public Iterator<RTBounds> searchIterator(Rectangle2D bounds) { return searchIterator(bounds, true); } /** * Method to return an interator over all RTBounds objects in a given area of this Cell that allows * to ignore elements touching the area. * @param bounds the specified area to search. * @param includeEdges true if RTBounds objects along edges are considered in. * @return an iterator over all of the RTBounds objects in that area. */ public Iterator<RTBounds> searchIterator(Rectangle2D bounds, boolean includeEdges) { return topology.searchIterator(bounds, includeEdges); } /** * Method to return the bounds of this Cell. * @return an ERectangle with the bounds of this cell's contents */ public ERectangle getBounds() { if (boundsDirty == BOUNDS_CORRECT || !database.canComputeBounds()) return cellBounds; checkChanging(); if (boundsDirty == BOUNDS_CORRECT_SUB) { boundsDirty = BOUNDS_CORRECT; // Recalculate bounds of subcells. for (Iterator<CellUsage> it = getUsagesIn(); it.hasNext(); ) { CellUsage u = it.next(); u.getProto().getBounds(); } if (boundsDirty == BOUNDS_CORRECT) return cellBounds; } if (boundsDirty == BOUNDS_CORRECT_GEOM) { boundsDirty = BOUNDS_CORRECT; for (NodeInst ni: nodes) ni.getBounds(); for (Iterator<ArcInst> it = topology.getArcs(); it.hasNext(); ) it.next().getBounds(); if (boundsDirty == BOUNDS_CORRECT) return cellBounds; } // recompute bounds unfreshRTree(); assert boundsDirty != BOUNDS_CORRECT; ERectangle newBounds = computeBounds(); if (newBounds != cellBounds) { cellBounds = newBounds; for (Iterator<NodeInst> it = getInstancesOf(); it.hasNext(); ) { NodeInst ni = it.next(); // Fake modify to recalcualte bounds and RTree ni.redoGeometric(); } } boundsDirty = BOUNDS_CORRECT; return cellBounds; } ERectangle computeBounds() { double cellLowX, cellHighX, cellLowY, cellHighY; boolean boundsEmpty = true; cellLowX = cellHighX = cellLowY = cellHighY = 0; // Ensure that all subcells have correct bounds for (Iterator<CellUsage> it = getUsagesIn(); it.hasNext(); ) { CellUsage u = it.next(); u.getProto().getBounds(); } for(int i = 0; i < nodes.size(); i++ ) { NodeInst ni = nodes.get(i); NodeProto np = ni.getProto(); Rectangle2D bounds = ni.getBounds(); // special case: do not include "cell center" primitives from Generic if (np == Generic.tech().cellCenterNode) continue; // special case for invisible pins: do not include if inheritable or interior-only if (np == Generic.tech().invisiblePinNode) { boolean found = false; for(Iterator<Variable> it = ni.getVariables(); it.hasNext(); ) { Variable var = it.next(); if (var.isDisplay()) { TextDescriptor td = var.getTextDescriptor(); if (td.isInterior() || td.isInherit()) { found = true; break; } } } if (found) continue; } double lowx = bounds.getMinX(); double highx = bounds.getMaxX(); double lowy = bounds.getMinY(); double highy = bounds.getMaxY(); if (boundsEmpty) { boundsEmpty = false; cellLowX = lowx; cellHighX = highx; cellLowY = lowy; cellHighY = highy; } else { if (lowx < cellLowX) cellLowX = lowx; if (highx > cellHighX) cellHighX = highx; if (lowy < cellLowY) cellLowY = lowy; if (highy > cellHighY) cellHighY = highy; } } long gridMinX = DBMath.lambdaToGrid(cellLowX); long gridMinY = DBMath.lambdaToGrid(cellLowY); long gridMaxX = DBMath.lambdaToGrid(cellHighX); long gridMaxY = DBMath.lambdaToGrid(cellHighY); topology.computeArcBounds(); ERectangle primitiveBounds = backup().getPrimitiveBounds(); if (primitiveBounds != null) { assert !boundsEmpty; gridMinX = Math.min(gridMinX, primitiveBounds.getGridMinX()); gridMaxX = Math.max(gridMaxX, primitiveBounds.getGridMaxX()); gridMinY = Math.min(gridMinY, primitiveBounds.getGridMinY()); gridMaxY = Math.max(gridMaxY, primitiveBounds.getGridMaxY()); } if (cellBounds != null && gridMinX == cellBounds.getGridMinX() && gridMinY == cellBounds.getGridMinY() && gridMaxX == cellBounds.getGridMaxX() && gridMaxY == cellBounds.getGridMaxY()) return cellBounds; return ERectangle.fromGrid(gridMinX, gridMinY, gridMaxX - gridMinX, gridMaxY - gridMinY); } /** * Method to compute the "essential bounds" of this Cell. * It looks for NodeInst objects in the cell that are of the type * "generic:Essential-Bounds" and builds a rectangle from their locations. * @return the bounding area of the essential bounds. * Returns null if an essential bounds cannot be determined. */ public Rectangle2D findEssentialBounds() { if (essenBounds.size() < 2) return null; double minX = Double.MAX_VALUE; double maxX = Double.MIN_VALUE; double minY = Double.MAX_VALUE; double maxY = Double.MIN_VALUE; for (int i = 0; i < essenBounds.size(); i++) { NodeInst ni = essenBounds.get(i); minX = Math.min(minX, ni.getTrueCenterX()); maxX = Math.max(maxX, ni.getTrueCenterX()); minY = Math.min(minY, ni.getTrueCenterY()); maxY = Math.max(maxY, ni.getTrueCenterY()); } return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY); } /** * Method to determine whether this Cell has a cell center in it. * @return true if this Cell has a Cell-center node in it. */ public boolean alreadyCellCenter() { for(Iterator<NodeInst> it = getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) return true; } return false; } /** * Method adjust this cell when the reference point moves. * This requires renumbering all coordinate values in the Cell. * @param cX coordinate X of new center. * @param cY coordinate Y of new center. */ public void adjustReferencePoint(double cX, double cY) { checkChanging(); // if there is no change, stop now if (cX == 0 && cY == 0) return; // move reference point by (dx,dy)// referencePointNode.modifyInstance(-cX, -cY, 0, 0, 0); // must adjust all nodes by (dx,dy) for(Iterator<NodeInst> it = getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) continue; // move NodeInst "ni" by (dx,dy) ni.move(-cX, -cY); } for(Iterator<ArcInst> it = getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); // move NodeInst "ni" by (dx,dy) ai.modify(-cX, -cY, -cX, -cY); } // adjust all instances of this cell for(Iterator<NodeInst> it = getInstancesOf(); it.hasNext(); ) { NodeInst ni = it.next();// Undo.redrawObject(ni); AffineTransform trans = ni.getOrient().pureRotate();// AffineTransform trans = NodeInst.pureRotate(ni.getAngle(), ni.isMirroredAboutXAxis(), ni.isMirroredAboutYAxis()); Point2D in = new Point2D.Double(cX, cY); trans.transform(in, in); ni.move(in.getX(), in.getY()); } Job.getUserInterface().adjustReferencePoint(this, cX, cY);// // adjust all windows showing this cell// for(Iterator<WindowFrame> it = WindowFrame.getWindows(); it.hasNext(); )// {// WindowFrame wf = it.next();// WindowContent content = wf.getContent();// if (!(content instanceof EditWindow_)) continue;// Cell cell = content.getCell();// if (cell != this) continue;// EditWindow_ wnd = (EditWindow_)content;// Point2D off = wnd.getOffset();// off.setLocation(off.getX()-cX, off.getY()-cY);// wnd.setOffset(off);// } } /** * Class for creating a description of a frame around a schematic cell. */ public static class FrameDescription { public static final double MULTIPAGESEPARATION = 1000; private static final double FRAMESCALE = 18.0; private static final double HASCHXSIZE = ( 8.5 * FRAMESCALE); private static final double HASCHYSIZE = ( 5.5 * FRAMESCALE); private static final double ASCHXSIZE = (11.0 * FRAMESCALE); private static final double ASCHYSIZE = ( 8.5 * FRAMESCALE); private static final double BSCHXSIZE = (17.0 * FRAMESCALE); private static final double BSCHYSIZE = (11.0 * FRAMESCALE); private static final double CSCHXSIZE = (24.0 * FRAMESCALE); private static final double CSCHYSIZE = (17.0 * FRAMESCALE); private static final double DSCHXSIZE = (36.0 * FRAMESCALE); private static final double DSCHYSIZE = (24.0 * FRAMESCALE); private static final double ESCHXSIZE = (48.0 * FRAMESCALE); private static final double ESCHYSIZE = (36.0 * FRAMESCALE); private static final double FRAMEWID = ( 0.15 * FRAMESCALE); private static final double XLOGOBOX = ( 2.0 * FRAMESCALE); private static final double YLOGOBOX = ( 1.0 * FRAMESCALE); private Cell cell; private List<Point2D> lineFromEnd; private List<Point2D> lineToEnd; private List<Point2D> textPoint; private List<Double> textSize; private List<Point2D> textBox; private List<String> textMessage; private int pageNo; /** * Constructor for cell frame descriptions. * @param cell the Cell that is having a frame drawn. */ public FrameDescription(Cell cell, int pageNo) { this.cell = cell; this.pageNo = pageNo; lineFromEnd = new ArrayList<Point2D>(); lineToEnd = new ArrayList<Point2D>(); textPoint = new ArrayList<Point2D>(); textSize = new ArrayList<Double>(); textBox = new ArrayList<Point2D>(); textMessage = new ArrayList<String>();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -