📄 layerdrawing.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: LayerDrawing.java * * Copyright (c) 2006 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.user.redisplay;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.EGraphics;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.id.CellId;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.EditWindow0;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.VarContext;import com.sun.electric.technology.Layer;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.ui.EditWindow;import com.sun.electric.tool.user.ui.WindowFrame;import java.awt.Color;import java.awt.Dimension;import java.awt.Font;import java.awt.Graphics2D;import java.awt.Point;import java.awt.Rectangle;import java.awt.RenderingHints;import java.awt.font.FontRenderContext;import java.awt.font.GlyphVector;import java.awt.font.LineMetrics;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.image.BufferedImage;import java.awt.image.DataBufferInt;import java.awt.image.VolatileImage;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.BitSet;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.swing.SwingUtilities;/** * This class manages an offscreen display for an associated EditWindow. * It renders an Image for copying to the display. * <P> * Every offscreen display consists of two parts: the transparent layers and the opaque image. * To tell how a layer is displayed, look at the "transparentLayer" field of its "EGraphics" object. * When this is nonzero, the layer is drawn transparent. * When this is zero, use the "red, green, blue" fields for the opaque color. * <P> * The opaque image is a full-color Image that is the size of the EditWindow. * Any layers that are marked "opaque" are drawn in full color in the image. * Colors are not combined in the opaque image: every color placed in it overwrites the previous color. * For this reason, opaque colors are often stipple patterns, so that they won't completely obscure other * opaque layers. * <P> * The transparent layers are able to combine with each other. * Typically, the more popular layers are made transparent (metal, poly, active, etc.) * For every transparent layer, there is a 1-bit deep bitmap that is the size of the EditWindow. * The bitmap is an array of "byte []" pointers, one for every Y coordinate in the EditWindow. * Each array contains the bits for that row, packed 8 per byte. * All of this information is in the "layerBitMaps" field, which is triply indexed. * <P> * Thus, to find bit (x,y) of transparent layer T, first lookup the appropriate transparent layer, * ("layerBitMaps[T]"). * Then, for that layer, find the array of bytes for the appropriate row * (by indexing the the Y coordinate into the rowstart array, "layerBitMaps[T][y]"). * Next, figure out which byte has the bit (by dividing the X coordinate by 8: "layerBitMaps[T][y][x>>3]"). * Finally, determine which bit to use (by using the low 3 bits of the X coordinate, * layerBitMaps[T][y][x>>3] & (1 << (x&7)) ). * <P> * Transparent layers are not allocated until needed. Thus, if there are 5 possible transparent layers, * but only 2 are used, then only two bitplanes will be created. * <P> * Each technology declares the number of possible transparent layers that it can generate. * In addition, it must provide a color map for describing every combination of transparent layer. * This map is, of course, 2-to-the-number-of-possible-transparent-layers long. * <P> * The expected number of transparent layers is taken from the current technology. If the user switches * the current technology, but draws something from a different technology, then the drawn circuitry * may make use of transparent layers that don't exist in the current technology. In such a case, * the transparent request is made opaque. * <P> * When all rendering is done, the full-color image is composited with the transparent layers to produce * the final image. * This is done by scanning the full-color image for any entries that were not filled-in. * These are then replaced by the transparent color at that point. * The transparent color is computed by looking at the bits in every transparent bitmap and * constructing an index. This is looked-up in the color table and the appropriate color is used. * If no transparent layers are set, the background color is used. * <P> * There are a number of efficiencies implemented here. * <UL> * <LI><B>Setting bits directly into the offscreen memory</B>. * Although Java's Swing package has a rendering model, it was found to be 3 times slower than * setting bits directly in the offscreen memory.</LI> * <LI><B>Tiny nodes and arcs are approximated</B>. * When a node or arc will be only 1 or 2 pixels in size on the screen, it is not necessary * to actually compute the edges of all of its parts. Instead, a single pixel of color is placed. * The color is taken from all of the layers that compose the node or arc. * For arcs that are long but only 1 pixel wide, a line is drawn in the same manner. * This optimization adds another factor of 2 to the speed of display.</LI> * <LI><B>Expanded cell contents are cached</B>. * When a cell is expanded, and its contents is drawn, the contents are preserved so that they * need be rendered only once. Subsequent instances of that expanded cell are able to be instantly drawn. * There are a number of extra considerations here: * <UL> * <LI>Cell instances can appear in any orientation. Therefore, the cache of drawn cells must * include the orientation.</LI> * <LI>Cached cells are retained as long as the current scale is maintained. But when zooming * in and out, the cache is cleared.</LI> * <LI>Cell instances may appear at different levels of the hierarchy, with different other circuitry over * them. For example, an instance may have been rendered at one level of hierarchy, and other items at that * same level then rendered over it. It is then no longer possible to copy those bits when the instance * appears again at another place in the hierarchy because it has been altered by neighboring circuitry. * The same problem happens when cell instances overlap. Therefore, it is necessary to render each expanded * cell instance into its own offscreen map, with its own separate opaque and transparent layers (which allows * it to be composited properly when re-instantiated). Thus, a new PixelDrawing" object is created for each * cached cell.</LI> * <LI>Subpixel alignment may not be the same for each cached instance. This turns out not to be * a problem, because at such zoomed-out scales, it is impossible to see individual objects anyway.</LI> * <LI>Large cell instances should not be cached. When zoomed-in, an expanded cell instance could * be many megabytes in size, and only a portion of it appears on the screen. Therefore, large cell * instances are not cached, but drawn directly. It is assumed that there will be few such instances. * The rule currently is that any cell whose width is greater than half of the display size AND whose * height is greater than half of the display size is too large to cache.</LI> * <LI>If an instance only appears once, it is not cached. This requires a preprocessing step to scan * the hierarchy and count the number of times that a particular cell-transformation is used. During * rendering, if the count is only 1, it is not cached. The exception to this rule is if the screen * is redisplayed without a change of magnification (during panning, for example). In such a case, * all cells will eventually be cached because, even those used once are being displayed with each redraw. </LI> * <LI>Texture patterns don't line-up. When drawing texture pattern to the final buffer, it is easy * to use the screen coordinates to index the pattern map, causing all of them to line-up. * Any two adjoining objects that use the same pattern will have their patterns line-up smoothly. * However, when caching cell instances, it is not possible to know where the contents will be placed * on the screen, and so the texture patterns rendered into the cache cannot be aligned globally. * To solve this, there are additional bitmaps created for every Patterned-Opaque-Layer (POL). * When rendering on a layer that is patterned and opaque, the bitmap is dynamically allocated * and filled (all bits are filled on the bitmap, not just those in the pattern). * When combining lower-level cell images with higher-level ones, these POLs are copied, too. * When compositing at the top level, however, the POLs are converted back to patterns, so that they line-up.</LI> * </UL> * </UL> * */class LayerDrawing{ /** Text smaller than this will not be drawn. */ public static final int MINIMUMTEXTSIZE = 5; /** Number of singleton cells to cache when redisplaying. */ public static final int SINGLETONSTOADD = 5; /** Text size is limited by this. */ public static final int MAXIMUMTEXTSIZE = 200; private static class PolySeg { private int fx,fy, tx,ty, direction, increment; private PolySeg nextedge; private PolySeg nextactive; } // statistics stuff private static final boolean TAKE_STATS = false; private static int tinyCells, tinyPrims, totalCells, renderedCells, totalPrims, tinyArcs, linedArcs, totalArcs; private static int offscreensCreated, offscreenPixelsCreated, offscreensUsed, offscreenPixelsUsed, cellsRendered; private static Set<ExpandedCellKey> offscreensUsedSet = new HashSet<ExpandedCellKey>(); private static int boxArrayCount, boxCount, boxDisplayCount, lineCount, polygonCount, crossCount, circleCount, discCount, arcCount; private static final boolean DEBUG = false; private static class ExpandedCellKey { private Cell cell; private Orientation orient; private ExpandedCellKey(Cell cell, Orientation orient) { this.cell = cell; this.orient = orient; } @Override public boolean equals(Object obj) { if (obj instanceof ExpandedCellKey) { ExpandedCellKey that = (ExpandedCellKey)obj; return this.cell == that.cell && this.orient.equals(that.orient); } return false; } @Override public int hashCode() { return cell.hashCode()^orient.hashCode(); } } /** * This class holds information about expanded cell instances. * For efficiency, Electric remembers the bits in an expanded cell instance * and uses them when another expanded instance appears elsewhere. * Of course, the orientation of the instance matters, so each combination of * cell and orientation forms a "cell cache". The Cell Cache is stored in the * "wnd" field (which has its own PixelDrawing object). */ private static class ExpandedCellInfo { private boolean singleton; private int instanceCount; private boolean tooLarge; private LayerDrawing offscreen; ExpandedCellInfo() { singleton = true; offscreen = null; } } /** the size of the EditWindow */ private final Dimension sz; /** the scale of the EditWindow */ private double scale; /** the VarContext of the EditWindow */ private VarContext varContext; /** the X origin of the cell in display coordinates. */ private double originX; /** the Y origin of the cell in display coordinates. */ private double originY; /** the scale of the EditWindow */ private double scale_; /** the window scale and pan factor */ private float factorX, factorY; /** 0: color display, 1: color printing, 2: B&W printing */ private int nowPrinting; /** whether any layers are highlighted/dimmed */ boolean highlightingLayers; /** true if the last display was a full-instantiate */ private boolean lastFullInstantiate = false; /** A set of subcells being in-place edited. */ private BitSet inPlaceSubcellPath; /** The current cell being in-place edited. */ private Cell inPlaceCurrent; /** true if text can be drawn (not too zoomed-out) */ private boolean canDrawText; /** Threshold for relative text can be drawn */ private double canDrawRelativeText = Double.MAX_VALUE; /** maximum size before an object is too small */ private static double maxObjectSize; /** half of maximum object size */ private static double halfMaxObjectSize; /** temporary objects (saves reallocation) */ private final Point tempPt1 = new Point(), tempPt2 = new Point(); /** temporary objects (saves reallocation) */ private final Point tempPt3 = new Point(), tempPt4 = new Point(); // the full-depth image /** size of the opaque layer of the window */ private final int total; /** list of render text. */ private final ArrayList<RenderTextInfo> renderTextList = new ArrayList<RenderTextInfo>(); /** list of greek text. */ private final ArrayList<GreekTextInfo> greekTextList = new ArrayList<GreekTextInfo>(); /** list of cross text. */ private final ArrayList<CrossTextInfo> crossTextList = new ArrayList<CrossTextInfo>(); // the transparent bitmaps /** the number of ints per row in offscreen maps */ private final int numIntsPerRow; /** the map from layers to layer bitmaps */ private Map<Layer,TransparentRaster> layerRasters = new HashMap<Layer,TransparentRaster>(); /** temporary raster for patterned layers */ private PatternedTransparentRaster currentPatternedTransparentRaster = new PatternedTransparentRaster();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -