📄 vectorcache.java
字号:
Map<Orientation,VectorCell> orientations = new HashMap<Orientation,VectorCell>(); List<VectorCellExport> exports; VectorCellGroup(CellId cellId) { this.cellId = cellId; init(); updateExports(); } private void init() { updateBounds(database.backup()); CellBackup cellBackup = database.backup().getCell(cellId); if (this.cellBackup == cellBackup) return; this.cellBackup = cellBackup; clear(); isParameterized = isCellParameterized(cellBackup.cellRevision); } private boolean updateBounds(Snapshot snapshot) { ERectangle newBounds = snapshot.getCellBounds(cellId); if (newBounds == bounds) return false; bounds = newBounds; if (bounds != null) { cellArea = (float)(bounds.getWidth()*bounds.getHeight()); cellMinSize = (float)Math.min(bounds.getWidth(), bounds.getHeight()); } else { cellArea = 0; cellMinSize = 0; } for (VectorCell vc: orientations.values()) vc.updateBounds(); return true; } private boolean changedExports() { Cell cell = database.getCell(cellId); if (cell == null) return exports != null; if (exports == null) return true; Iterator<VectorCellExport> cIt = exports.iterator(); for(Iterator<Export> it = cell.getExports(); it.hasNext(); ) { Export e = it.next(); if (!cIt.hasNext()) return true; VectorCellExport vce = cIt.next(); if (!vce.exportName.equals(e.getName())) return true; Poly poly = e.getOriginalPort().getPoly(); if (vce.exportCtr.getX() != poly.getCenterX() || vce.exportCtr.getY() != poly.getCenterY()) return true; } return cIt.hasNext(); } private void updateExports() { for (VectorCell vc : orientations.values()) { vc.clearExports(); } Cell cell = database.getCell(cellId); if (DEBUG) { System.out.println("updateExports " + cellId); } if (cell == null) { exports = null; return; } // save export centers to detect hierarchical changes later exports = new ArrayList<VectorCellExport>(); for (Iterator<Export> it = cell.getExports(); it.hasNext();) { Export e = it.next(); VectorCellExport vce = new VectorCellExport(e); exports.add(vce); } } List<VectorCellExport> getPortShapes() { if (exports == null) updateExports(); return exports; } void clear() { for (VectorCell vc: orientations.values()) vc.clear(); if (exports != null) exports = null; if (DEBUG) System.out.println("clear " + cellId); } VectorCell getAnyCell() { for (VectorCell vc: orientations.values()) { if (vc.valid) return vc; } return null; } } VectorCellGroup findCellGroup(CellId cellId) { int cellIndex = cellId.cellIndex; while (cellIndex >= cachedCells.size()) cachedCells.add(null); VectorCellGroup vcg = cachedCells.get(cellIndex); if (vcg == null) { vcg = new VectorCellGroup(cellId); cachedCells.set(cellIndex, vcg); } return vcg; } /** * Class which defines the exports on a cell (used to tell if they changed) */ static class VectorCellExport { String exportName; Point2D exportCtr; private ImmutableExport e; /** the text style */ Poly.Type style; /** the descriptor of the text */ TextDescriptor descript; /** the text height (in display units) */ float height; private Color portColor; VectorCellExport(Export e) { this.e = e.getD(); exportName = e.getName(); this.descript = this.e.nameDescriptor; Poly portPoly = e.getNamePoly(); assert portPoly.getPoints().length == 1; exportCtr = portPoly.getPoints()[0]; style = Poly.Type.TEXTCENT; height = 1; if (descript != null) {// portDescript = portDescript.withColorIndex(descript.getColorIndex()); style = descript.getPos().getPolyType(); TextDescriptor.Size tds = descript.getSize(); if (!tds.isAbsolute()) height = (float)tds.getSize(); } this.e = e.getD(); portColor = e.getBasePort().getPortColor(); } int getChronIndex() { return e.exportId.chronIndex; } String getName(boolean shortName) { String name = e.name.toString(); if (shortName) { int len = name.length(); for (int i = 0; i < len; i++) { char ch = name.charAt(i); if (TextUtils.isLetterOrDigit(ch)) { continue; } return name.substring(0, i); } } return name; } Color getPortColor() { return portColor; } } /** * Class which defines a cached cell in a single orientation. */ class VectorCell { final VectorCellGroup vcg; final Orientation orient; int[] outlinePoints = new int[8]; int lX, lY, hX, hY; int[] portCenters; boolean valid; ArrayList<VectorBase> filledShapes = new ArrayList<VectorBase>(); ArrayList<VectorBase> shapes = new ArrayList<VectorBase>(); private ArrayList<VectorBase> topOnlyShapes; ArrayList<VectorSubCell> subCells = new ArrayList<VectorSubCell>(); boolean hasFadeColor; int fadeColor; float maxFeatureSize; boolean fadeImage; int fadeOffsetX, fadeOffsetY; int [] fadeImageColors; int fadeImageWid, fadeImageHei; VectorCell(VectorCellGroup vcg, Orientation orient) { this.vcg = vcg; this.orient = orient; updateBounds(); } // Constructor for TechPalette private VectorCell() { vcg = null; orient = null; } private void init(Cell cell) { long startTime = DEBUG ? System.currentTimeMillis() : 0; vcg.init(); updateBounds(); clear(); maxFeatureSize = 0; AffineTransform trans = orient.pureRotate(); vcg.updateExports(); for (VectorManhattanBuilder b: boxBuilders) b.clear(); for (VectorManhattanBuilder b: pureBoxBuilders) b.clear(); // draw all arcs for(Iterator<ArcInst> arcs = cell.getArcs(); arcs.hasNext(); ) { ArcInst ai = arcs.next(); drawArc(ai, trans, this); } // draw all nodes for(Iterator<NodeInst> nodes = cell.getNodes(); nodes.hasNext(); ) { NodeInst ni = nodes.next(); boolean hideOnLowLevel = false; if (!ni.isCellInstance()) hideOnLowLevel = ni.isVisInside() || ni.getProto() == Generic.tech().cellCenterNode; if (!hideOnLowLevel) drawNode(ni, trans, this); } // add in anything "snuck" onto the cell CellId cellId = cell.getId(); List<VectorBase> addThesePolys = addPolyToCell.get(cellId); if (addThesePolys != null) { for(VectorBase vb : addThesePolys) filledShapes.add(vb); } List<VectorLine> addTheseInsts = addInstToCell.get(cellId); if (addTheseInsts != null) { for(VectorLine vl : addTheseInsts) shapes.add(vl); } addBoxesFromBuilder(this, cell.getTechnology(), boxBuilders, false); addBoxesFromBuilder(this, cell.getTechnology(), pureBoxBuilders, true); Collections.sort(filledShapes, shapeByLayer); Collections.sort(shapes, shapeByLayer); // icon cells should not get greeked because of their contents if (cell.isIcon()) maxFeatureSize = 0; valid = true; if (DEBUG) { long stopTime = System.currentTimeMillis(); System.out.println((stopTime - startTime) + " init " + vcg.cellId + " " + orient); } } private void updateBounds() { lX = lY = Integer.MAX_VALUE; hX = hY = Integer.MIN_VALUE; ERectangle bounds = vcg.bounds; if (bounds == null) return; double[] points = new double[8]; points[0] = points[6] = bounds.getMinX(); points[1] = points[3] = bounds.getMinY(); points[2] = points[4] = bounds.getMaxX(); points[5] = points[7] = bounds.getMaxY(); orient.pureRotate().transform(points, 0, points, 0, 4); for (int i = 0; i < 4; i++) { int x = databaseToGrid(points[i*2]); int y = databaseToGrid(points[i*2 + 1]); lX = Math.min(lX, x); lY = Math.min(lY, y); hX = Math.max(hX, x); hY = Math.max(hY, y); outlinePoints[i*2] = x; outlinePoints[i*2+1] = y; } } private void clear() { clearExports(); valid = hasFadeColor = fadeImage = false; filledShapes.clear(); shapes.clear(); subCells.clear(); fadeImageColors = null; } private void clearExports() { portCenters = null; topOnlyShapes = null; } int[] getPortCenters() { if (portCenters == null) initPortCenters(); return portCenters; } private void initPortCenters() { List<VectorCellExport> portShapes = vcg.getPortShapes(); portCenters = new int[portShapes.size()*2]; AffineTransform trans = orient.pureRotate(); Point2D.Double tmpPt = new Point2D.Double(); for(int i = 0, numPorts = portShapes.size(); i < numPorts; i++) { VectorCellExport vce = portShapes.get(i); trans.transform(vce.exportCtr, tmpPt); portCenters[i*2] = databaseToGrid(tmpPt.getX()); portCenters[i*2 + 1] = databaseToGrid(tmpPt.getY()); } } ArrayList<VectorBase> getTopOnlyShapes() { if (topOnlyShapes == null) initTopOnlyShapes(); return topOnlyShapes; } private void initTopOnlyShapes() { Cell cell = database.getCell(vcg.cellId); topOnlyShapes = new ArrayList<VectorBase>(); // show cell variables Poly[] polys = cell.getDisplayableVariables(CENTERRECT, dummyWnd, true); drawPolys(polys, DBMath.MATID, this, true, VectorText.TEXTTYPECELL, false); // draw nodes visible only inside AffineTransform trans = orient.pureRotate(); for(Iterator<NodeInst> nodes = cell.getNodes(); nodes.hasNext(); ) { NodeInst ni = nodes.next(); if (ni.isCellInstance()) continue; boolean hideOnLowLevel = ni.isVisInside() || ni.getProto() == Generic.tech().cellCenterNode; if (hideOnLowLevel) drawNode(ni, trans, this); } // draw exports and their variables for (Iterator<Export> it = cell.getExports(); it.hasNext(); ) { Export e = it.next(); Poly poly = e.getNamePoly(); Rectangle2D rect = (Rectangle2D)poly.getBounds2D().clone(); TextDescriptor descript = poly.getTextDescriptor(); Poly.Type style = descript.getPos().getPolyType(); style = Poly.rotateType(style, e.getOriginalPort().getNodeInst()); VectorText vt = new VectorText(poly.getBounds2D(), style, descript, e.getName(), VectorText.TEXTTYPEEXPORT, e, null, null); topOnlyShapes.add(vt); // draw variables on the export polys = e.getDisplayableVariables(rect, dummyWnd, true); drawPolys(polys, trans, this, true, VectorText.TEXTTYPEEXPORT, false); } Collections.sort(topOnlyShapes, shapeByLayer); }// private void clearTopOnlyShapes() {// topOnlyShapes = null;// } } /** Creates a new instance of VectorCache */ public VectorCache(EDatabase database) { this.database = database;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -