📄 pixeldrawing.java
字号:
double lowX = Math.min(low.getX(), high.getX()); double lowY = Math.min(low.getY(), high.getY()); double sizeX = Math.abs(high.getX()-low.getX()); double sizeY = Math.abs(high.getY()-low.getY()); Rectangle2D bounds = new Rectangle2D.Double(lowX, lowY, sizeX, sizeY); return bounds; } private void initForTechnology() { // allocate pointers to the overlappable layers Technology tech = Technology.getCurrent(); if (tech == null) return; if (tech == curTech) return; int transLayers = tech.getNumTransparentLayers(); if (transLayers != 0) { techWithLayers = curTech = tech; } if (curTech == null) curTech = techWithLayers; if (curTech == null) return; numLayerBitMaps = curTech.getNumTransparentLayers(); layerBitMaps = new byte[numLayerBitMaps][][]; compositeRows = new byte[numLayerBitMaps][]; for(int i=0; i<numLayerBitMaps; i++) layerBitMaps[i] = null; numLayerBitMapsCreated = 0; } private void periodicRefresh() { // handle refreshing if (periodicRefresh) { objectCount++; if (objectCount > 100) { objectCount = 0; long currentTime = System.currentTimeMillis(); if (currentTime - lastRefreshTime > 1000) { wnd.repaint(); } } } } // ************************************* HIERARCHY TRAVERSAL ************************************* /** * Method to draw the contents of a cell, transformed through "prevTrans". */ private void drawCell(Cell cell, Rectangle2D drawLimitBounds, boolean fullInstantiate, Orientation orient, AffineTransform prevTrans, Cell topCell) { renderedCells++; renderPolyTime = 0; renderTextTime = 0; // draw all arcs for(Iterator<ArcInst> arcs = cell.getArcs(); arcs.hasNext(); ) { ArcInst ai = arcs.next(); // if limiting drawing, reject when out of area if (drawLimitBounds != null) { Rectangle2D curBounds = ai.getBounds(); Rectangle2D bounds = new Rectangle2D.Double(curBounds.getX(), curBounds.getY(), curBounds.getWidth(), curBounds.getHeight()); DBMath.transformRect(bounds, prevTrans); if (!DBMath.rectsIntersect(bounds, drawLimitBounds)) continue; } drawArc(ai, prevTrans, false); } // draw all nodes for(Iterator<NodeInst> nodes = cell.getNodes(); nodes.hasNext(); ) { NodeInst ni = nodes.next(); // if limiting drawing, reject when out of area if (drawLimitBounds != null) { Rectangle2D curBounds = ni.getBounds(); Rectangle2D bounds = new Rectangle2D.Double(curBounds.getX(), curBounds.getY(), curBounds.getWidth(), curBounds.getHeight()); DBMath.transformRect(bounds, prevTrans); if (!DBMath.rectsIntersect(bounds, drawLimitBounds)) continue; } drawNode(ni, orient, prevTrans, topCell, drawLimitBounds, fullInstantiate, false); } // show cell variables if at the top level boolean topLevel = true; if (topCell != null) topLevel = (cell == topCell); if (canDrawText && topLevel && User.isTextVisibilityOnCell()) { // show displayable variables on the instance Poly[] polys = cell.getDisplayableVariables(CENTERRECT, dummyWnd, true); drawPolys(polys, prevTrans, false); } if (DEBUGRENDERTIMING) { System.out.println("Total time to render polys: "+TextUtils.getElapsedTime(renderPolyTime)); System.out.println("Total time to render text: "+TextUtils.getElapsedTime(renderTextTime)); } } /** * Method to draw a NodeInst into the offscreen image. * @param ni the NodeInst to draw. * @param trans the transformation of the NodeInst to the display. * @param topCell the Cell at the top-level of display. * @param drawLimitBounds bounds in which to draw. * @param fullInstantiate true to draw to the bottom of the hierarchy ("peek" mode). * @param forceVisible true if layer visibility information should be ignored and force the drawing */ private void drawNode(NodeInst ni, Orientation orient, AffineTransform trans, Cell topCell, Rectangle2D drawLimitBounds, boolean fullInstantiate, boolean forceVisible) { NodeProto np = ni.getProto(); AffineTransform localTrans = ni.rotateOut(trans); boolean topLevel = true; if (topCell != null) topLevel = (ni.getParent() == topCell); // draw the node if (ni.isCellInstance()) { // cell instance totalCells++;// if (objWidth < maxObjectSize)// {// tinyCells++;// return;// } // see if it is on the screen Cell subCell = (Cell)np; Orientation subOrient = orient.concatenate(ni.getOrient()); AffineTransform subTrans = ni.translateOut(localTrans); Rectangle2D cellBounds = subCell.getBounds(); Poly poly = new Poly(cellBounds); poly.transform(subTrans); cellBounds = poly.getBounds2D(); Rectangle screenBounds = databaseToScreen(cellBounds); if (screenBounds.width <= 0 || screenBounds.height <= 0) { tinyCells++; return; } if (screenBounds.x >= sz.width || screenBounds.x+screenBounds.width <= 0) return; if (screenBounds.y >= sz.height || screenBounds.y+screenBounds.height <= 0) return; boolean expanded = ni.isExpanded(); if (fullInstantiate) expanded = true; // if not expanded, but viewing this cell in-place, expand it if (!expanded) { if (inPlaceNodePath != null) { for(int pathIndex=0; pathIndex<inPlaceNodePath.size(); pathIndex++) { NodeInst niOnPath = inPlaceNodePath.get(pathIndex); if (niOnPath.getProto() == subCell) { expanded = true; break; } } } } // two ways to draw a cell instance if (expanded) { // show the contents of the cell if (!expandedCellCached(subCell, subOrient, subTrans, topCell, drawLimitBounds, fullInstantiate)) { // just draw it directly cellsRendered++; varContext = varContext.push(ni); drawCell(subCell, drawLimitBounds, fullInstantiate, subOrient, subTrans, topCell); varContext.pop(); } if (canDrawText) showCellPorts(ni, trans, Color.BLACK); } else { // draw the black box of the instance drawUnexpandedCell(ni, poly); if (canDrawText) showCellPorts(ni, trans, null); } // draw any displayable variables on the instance if (canDrawText && User.isTextVisibilityOnNode()) { Poly[] polys = ni.getDisplayableVariables(dummyWnd); drawPolys(polys, localTrans, false); } } else { // primitive: see if it can be drawn if (topLevel || (!ni.isVisInside() && np != Generic.tech().cellCenterNode)) { // see if the node is completely clipped from the screen Point2D ctr = ni.getTrueCenter(); trans.transform(ctr, ctr); double halfWidth = Math.max(ni.getXSize(), ni.getYSize()) / 2; double ctrX = ctr.getX(); double ctrY = ctr.getY(); if (renderedWindow && drawBounds != null) { Rectangle2D databaseBounds = drawBounds; if (ctrX + halfWidth < databaseBounds.getMinX()) return; if (ctrX - halfWidth > databaseBounds.getMaxX()) return; if (ctrY + halfWidth < databaseBounds.getMinY()) return; if (ctrY - halfWidth > databaseBounds.getMaxY()) return; } PrimitiveNode prim = (PrimitiveNode)np; totalPrims++; if (!prim.isCanBeZeroSize() && halfWidth < halfMaxObjectSize && !forceVisible) { // draw a tiny primitive by setting a single dot from each layer tinyPrims++; databaseToScreen(ctrX, ctrY, tempPt1); if (tempPt1.x >= 0 && tempPt1.x < sz.width && tempPt1.y >= 0 && tempPt1.y < sz.height) { drawTinyLayers(prim.getLayerIterator(), tempPt1.x, tempPt1.y); } return; } EditWindow0 nodeWnd = dummyWnd; if (!forceVisible && (!canDrawText || !User.isTextVisibilityOnNode())) nodeWnd = null; if (prim == Generic.tech().invisiblePinNode) { if (!User.isTextVisibilityOnAnnotation()) nodeWnd = null; } Technology tech = prim.getTechnology(); drawPolys(tech.getShapeOfNode(ni, false, false, null), localTrans, forceVisible); drawPolys(ni.getDisplayableVariables(nodeWnd), localTrans, forceVisible); } } // draw any exports from the node if (canDrawText && topLevel && User.isTextVisibilityOnExport()) { int exportDisplayLevel = User.getExportDisplayLevel(); Iterator<Export> it = ni.getExports(); while (it.hasNext()) { Export e = it.next(); if (np instanceof PrimitiveNode && !((PrimitiveNode)np).isVisible()) continue; Poly poly = e.getNamePoly(); poly.transform(trans); Rectangle2D rect = (Rectangle2D)poly.getBounds2D().clone(); if (exportDisplayLevel == 2) { // draw port as a cross drawCross(poly, textGraphics, false); } else { // draw port as text TextDescriptor descript = poly.getTextDescriptor(); Poly.Type type = descript.getPos().getPolyType(); String portName = e.getName(); if (exportDisplayLevel == 1) { // use shorter port name portName = e.getShortName(); } databaseToScreen(poly.getCenterX(), poly.getCenterY(), tempPt1); Rectangle textRect = new Rectangle(tempPt1); type = Poly.rotateType(type, ni); drawText(textRect, type, descript, portName, null, textGraphics, false); } // draw variables on the export Poly[] polys = e.getDisplayableVariables(rect, dummyWnd, true); drawPolys(polys, localTrans, false); } } } /** * Method to render an ArcInst into the offscreen image. * @param ai the ArcInst to draw. * @param trans the transformation of the ArcInst to the display. * @param forceVisible true to ignore layer visibility and draw all layers. */ private void drawArc(ArcInst ai, AffineTransform trans, boolean forceVisible) { // if the arc is tiny, just approximate it with a single dot Rectangle2D arcBounds = ai.getBounds(); double arcSize = Math.max(arcBounds.getWidth(), arcBounds.getHeight()); totalArcs++; if (!forceVisible) { if (arcSize < maxObjectSize) { tinyArcs++; return; } if (ai.getGridFullWidth() > 0) { arcSize = Math.min(arcBounds.getWidth(), arcBounds.getHeight()); if (arcSize < maxObjectSize) { linedArcs++; // draw a tiny arc by setting a single dot from each layer Point2D headEnd = new Point2D.Double(ai.getHeadLocation().getX(), ai.getHeadLocation().getY()); trans.transform(headEnd, headEnd); databaseToScreen(headEnd.getX(), headEnd.getY(), tempPt1); Point2D tailEnd = new Point2D.Double(ai.getTailLocation().getX(), ai.getTailLocation().getY()); trans.transform(tailEnd, tailEnd); databaseToScreen(tailEnd.getX(), tailEnd.getY(), tempPt2); ArcProto prim = ai.getProto(); drawTinyArc(prim.getLayerIterator(), tempPt1, tempPt2); return; } } } // see if the arc is completely clipped from the screen Rectangle2D dbBounds = new Rectangle2D.Double(arcBounds.getX(), arcBounds.getY(), arcBounds.getWidth(), arcBounds.getHeight()); Poly p = new Poly(dbBounds); p.transform(trans); dbBounds = p.getBounds2D(); if (drawBounds != null && !DBMath.rectsIntersect(drawBounds, dbBounds)) return; // draw the arc ArcProto ap = ai.getProto(); Technology tech = ap.getTechnology(); drawPolys(tech.getShapeOfArc(ai), trans, forceVisible); if (canDrawText && User.isTextVisibilityOnArc()) drawPolys(ai.getDisplayableVariables(dummyWnd), trans, forceVisible); } private void showCellPorts(NodeInst ni, AffineTransform trans, Color col) { // show the ports that are not further exported or connected int numPorts = ni.getProto().getNumPorts(); boolean[] shownPorts = new boolean[numPorts]; for(Iterator<Connection> it = ni.getConnections(); it.hasNext();) { Connection con = it.next(); PortInst pi = con.getPortInst(); Export e = (Export)pi.getPortProto(); if (!e.isAlwaysDrawn()) shownPorts[pi.getPortIndex()] = true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -