📄 pixeldrawing.java
字号:
this.offscreen = offscreen_ = new PixelDrawing(sz); this.da = da; offscreen_.drawImage(this, fullInstantiate, bounds); } @Override public void abortRendering() { if (User.getDisplayAlgorithm() > 0) vd.abortRendering(); } } // ************************************* TOP LEVEL ************************************* /** * Constructor creates an offscreen PixelDrawing object. * @param sz the size of an offscreen PixelDrawinf object. */ public PixelDrawing(Dimension sz) { this.sz = new Dimension(sz); clipLX = 0; clipHX = sz.width - 1; clipLY = 0; clipHY = sz.height - 1; // allocate pointer to the opaque image img = new BufferedImage(sz.width, sz.height, BufferedImage.TYPE_INT_RGB); WritableRaster raster = img.getRaster(); DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer(); opaqueData = dbi.getData(); total = sz.height * sz.width; numBytesPerRow = (sz.width + 7) / 8; renderedWindow = true; } public PixelDrawing(double scale, Rectangle screenBounds) { this.scale = scale; this.originX = -screenBounds.x; this.originY = screenBounds.y + screenBounds.height; this.sz = new Dimension(screenBounds.width, screenBounds.height); clipLX = 0; clipHX = sz.width - 1; clipLY = 0; clipHY = sz.height - 1; // allocate pointer to the opaque image img = null; total = sz.height * sz.width; opaqueData = new int[total]; numBytesPerRow = (sz.width + 7) / 8; // initialize the data clearImage(null); } void initOrigin(double scale, double offx, double offy) { this.scale = scale; this.originX = sz.width/2 - offx*scale; this.originY = sz.height/2 + offy*scale; } void initDrawing(double scale) { clearImage(null); initOrigin(scale, 0, 0); } /** * Method to set the printing mode used for all drawing. * @param mode the printing mode: 0=color display (default), 1=color printing, 2=B&W printing. */ public void setPrintingMode(int mode) { nowPrinting = mode; } /** * Method to override the background color. * Must be called before "drawImage()". * This is used by printing, which forces the background to be white. * @param bg the background color to use. */ public void setBackgroundColor(Color bg) { backgroundColor = bg.getRGB() & 0xFFFFFF; } /** * Method for obtaining the rendered image after "drawImage" has finished. * @return an Image for this edit window. */ public BufferedImage getBufferedImage() { return img; } /** * Method for obtaining the RGB array of the rendered image after "drawImage" has finished. * @return an RGB array for this edit window. */ int[] getOpaqueData() { return opaqueData; } /** * Method for obtaining the size of the offscreen bitmap. * @return the size of the offscreen bitmap. */ public Dimension getSize() { return sz; } /** * Method to clear the cache of expanded subcells. * This is used by layer visibility which, when changed, causes everything to be redrawn. */ public static void clearSubCellCache() { expandedCells = new HashMap<ExpandedCellKey,ExpandedCellInfo>(); } /** * This is the entry point for rendering. * It displays a cell in this offscreen window. * @param fullInstantiate true to display to the bottom of the hierarchy (for peeking). * @param drawLimitBounds the area in the cell to display (null to show all). * The rendered Image can then be obtained with "getImage()". */ private void drawImage(Drawing drawing, boolean fullInstantiate, Rectangle2D drawLimitBounds) { long startTime = 0; long initialUsed = 0; if (TAKE_STATS) { startTime = System.currentTimeMillis(); initialUsed = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); tinyCells = tinyPrims = totalCells = renderedCells = totalPrims = tinyArcs = linedArcs = totalArcs = 0; offscreensCreated = offscreenPixelsCreated = offscreensUsed = offscreenPixelsUsed = cellsRendered = 0; } if (fullInstantiate != lastFullInstantiate) { clearSubCellCache(); lastFullInstantiate = fullInstantiate; } EditWindow wnd = drawing.wnd; Cell cell = wnd.getInPlaceEditTopCell(); inPlaceNodePath = wnd.getInPlaceEditNodePath(); double width = sz.width/scale; double height = sz.height/scale; drawBounds = new Rectangle2D.Double(drawing.da.offX - width/2, drawing.da.offY - height/2, width, height); // set colors to use textColor = new Color(User.getColor(User.ColorPrefType.TEXT)); textGraphics.setColor(textColor); gridGraphics.setColor(new Color(User.getColor(User.ColorPrefType.GRID))); instanceGraphics.setColor(new Color(User.getColor(User.ColorPrefType.INSTANCE))); // initialize the cache of expanded cell displays if (expandedScale != drawing.da.scale) { clearSubCellCache(); expandedScale = drawing.da.scale; } varContext = wnd.getVarContext(); initOrigin(expandedScale, drawing.da.offX, drawing.da.offY); canDrawText = expandedScale > 1; maxObjectSize = 2 / expandedScale; halfMaxObjectSize = maxObjectSize / 2; // remember the true window size (since recursive calls may cache individual cells that are smaller) topSz = sz; // see if any layers are being highlighted/dimmed highlightingLayers = false; for(Iterator<Layer> it = Technology.getCurrent().getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (layer.isDimmed()) { highlightingLayers = true; break; } } // initialize rendering into the offscreen image Rectangle renderBounds = null; if (drawLimitBounds != null) { renderBounds = databaseToScreen(drawLimitBounds); clipLX = Math.max(renderBounds.x, 0); clipHX = Math.min(renderBounds.x + renderBounds.width, sz.width) - 1; clipLY = Math.max(renderBounds.y, 0); clipHY = Math.min(renderBounds.y + renderBounds.height, sz.height) - 1; } else { clipLX = 0; clipHX = sz.width - 1; clipLY = 0; clipHY = sz.height - 1; } clearImage(renderBounds); periodicRefresh = true; this.wnd = wnd; objectCount = 0; lastRefreshTime = System.currentTimeMillis(); Set<CellId> changedCellsCopy; synchronized (changedCells) { changedCellsCopy = new HashSet<CellId>(changedCells); changedCells.clear(); } forceRedraw(changedCellsCopy); VectorCache.theCache.forceRedraw(); if (User.getDisplayAlgorithm() == 0) { // reset cached cell counts numberToReconcile = SINGLETONSTOADD; for(ExpandedCellInfo count : expandedCells.values()) count.instanceCount = 0; // determine which cells should be cached (must have at least 2 instances) countCell(cell, drawLimitBounds, fullInstantiate, Orientation.IDENT, DBMath.MATID); // now render it all drawCell(cell, drawLimitBounds, fullInstantiate, Orientation.IDENT, DBMath.MATID, wnd.getCell()); } else { drawing.vd.render(this, scale, new Point2D.Double(drawing.da.offX, drawing.da.offY), cell, fullInstantiate, inPlaceNodePath, wnd.getCell(), renderBounds, varContext); } // merge transparent image into opaque one synchronized(img) { // if a grid is requested, overlay it if (cell != null && wnd.isGrid()) drawGrid(wnd, drawing.da); // combine transparent and opaque colors into a final image composite(renderBounds); } if (TAKE_STATS && User.getDisplayAlgorithm() == 0) { long endTime = System.currentTimeMillis(); long curUsed = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); long memConsumed = curUsed - initialUsed; System.out.println("Took "+com.sun.electric.database.text.TextUtils.getElapsedTime(endTime-startTime)+ ", rendered "+cellsRendered+" cells, used "+offscreensUsed+" ("+offscreenPixelsUsed+" pixels) cached cells, created "+ offscreensCreated+" ("+offscreenPixelsCreated+" pixels) new cell caches (my size is "+total+" pixels), memory used="+memConsumed); System.out.println(" Cells ("+totalCells+") "+tinyCells+" are tiny;"+ " Primitives ("+totalPrims+") "+tinyPrims+" are tiny;"+ " Arcs ("+totalArcs+") "+tinyArcs+" are tiny, "+linedArcs+" are lines"); } } /** * This is the entry point for rendering. * It displays a cell in this offscreen window. * The rendered Image can then be obtained with "getImage()". */ public void printImage(double scale, Point2D offset, Cell cell, VarContext varContext) { clearSubCellCache(); lastFullInstantiate = false; expandedScale = this.scale = scale; // set colors to use textColor = new Color(User.getColor(User.ColorPrefType.TEXT)); textGraphics.setColor(textColor); gridGraphics.setColor(new Color(User.getColor(User.ColorPrefType.GRID))); instanceGraphics.setColor(new Color(User.getColor(User.ColorPrefType.INSTANCE))); if (wnd != null) varContext = wnd.getVarContext(); initOrigin(scale, offset.getX(), offset.getY()); canDrawText = expandedScale > 1; maxObjectSize = 2 / expandedScale; halfMaxObjectSize = maxObjectSize / 2; // remember the true window size (since recursive calls may cache individual cells that are smaller) topSz = sz; // see if any layers are being highlighted/dimmed highlightingLayers = false; for(Iterator<Layer> it = Technology.getCurrent().getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (layer.isDimmed()) { highlightingLayers = true; break; } } // initialize rendering into the offscreen image clipLX = 0; clipHX = sz.width - 1; clipLY = 0; clipHY = sz.height - 1; clearImage(null); Set<CellId> changedCellsCopy; synchronized (changedCells) { changedCellsCopy = new HashSet<CellId>(changedCells); changedCells.clear(); } forceRedraw(changedCellsCopy); VectorCache.theCache.forceRedraw(); if (User.getDisplayAlgorithm() == 0) { // reset cached cell counts numberToReconcile = SINGLETONSTOADD; for(ExpandedCellInfo count : expandedCells.values()) count.instanceCount = 0; // determine which cells should be cached (must have at least 2 instances) countCell(cell, null, false, Orientation.IDENT, DBMath.MATID); // now render it all drawCell(cell, null, false, Orientation.IDENT, DBMath.MATID, cell); } else { VectorDrawing vd = new VectorDrawing(); vd.render(this, scale, offset, cell, false, null, null, null, varContext); } // merge transparent image into opaque one synchronized(img) { // combine transparent and opaque colors into a final image composite(null); } } // ************************************* INTERMEDIATE CONTROL LEVEL ************************************* /** * Method to erase the offscreen data in this PixelDrawing. * This is called before any rendering is done. * @param bounds the area of the image to actually draw (null to draw all). */ public void clearImage(Rectangle bounds) { // pickup new technology if it changed initForTechnology(); backgroundColor = User.getColor(User.ColorPrefType.BACKGROUND) & 0xFFFFFF; backgroundValue = backgroundColor | 0xFF000000; // erase the transparent bitmaps for(int i=0; i<numLayerBitMaps; i++) { byte [][] layerBitMap = layerBitMaps[i]; if (layerBitMap == null) continue; for(int y=0; y<sz.height; y++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -