⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pixeldrawing.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		for(Iterator<Export> it = ni.getExports(); it.hasNext();)		{			Export exp = it.next();			PortInst pi = exp.getOriginalPort();            Export e = (Export)pi.getPortProto();            if (!e.isAlwaysDrawn())            	shownPorts[pi.getPortIndex()] = true;		}		int portDisplayLevel = User.getPortDisplayLevel();		for(int i = 0; i < numPorts; i++)		{			if (shownPorts[i]) continue;			Export pp = (Export)ni.getProto().getPort(i);			Poly portPoly = ni.getShapeOfPort(pp);			if (portPoly == null) continue;			portPoly.transform(trans);			Color portColor = col;			if (portColor == null) portColor = pp.getBasePort().getPortColor();			portGraphics.setColor(portColor);			if (portDisplayLevel == 2)			{				// draw port as a cross				drawCross(portPoly, portGraphics, false);			} else			{				// draw port as text				if (User.isTextVisibilityOnPort())				{					// combine all features of port text with color of the port					TextDescriptor descript = portPoly.getTextDescriptor();					TextDescriptor portDescript = pp.getTextDescriptor(Export.EXPORT_NAME).withColorIndex(descript.getColorIndex());					Poly.Type type = descript.getPos().getPolyType();					String portName = pp.getName();					if (portDisplayLevel == 1)					{						// use shorter port name						portName = pp.getShortName();					}					databaseToScreen(portPoly.getCenterX(), portPoly.getCenterY(), tempPt1);					Rectangle rect = new Rectangle(tempPt1);					drawText(rect, type, portDescript, portName, null, portGraphics, false);				}			}		}	}	private void drawUnexpandedCell(NodeInst ni, Poly poly)	{		// draw the instance outline		Point2D [] points = poly.getPoints();		for(int i=0; i<points.length; i++)		{			int lastI = i - 1;			if (lastI < 0) lastI = points.length - 1;			Point2D lastPt = points[lastI];			Point2D thisPt = points[i];			databaseToScreen(lastPt.getX(), lastPt.getY(), tempPt1);			databaseToScreen(thisPt.getX(), thisPt.getY(), tempPt2);			drawLine(tempPt1, tempPt2, null, instanceGraphics, 0, false);		}		// draw the instance name		if (canDrawText && User.isTextVisibilityOnInstance())		{			Rectangle2D bounds = poly.getBounds2D();			Rectangle rect = databaseToScreen(bounds);			TextDescriptor descript = ni.getTextDescriptor(NodeInst.NODE_PROTO);			NodeProto np = ni.getProto();			drawText(rect, Poly.Type.TEXTBOX, descript, np.describe(false), null, textGraphics, false);		}	}	private void drawTinyLayers(Iterator<Layer> layerIterator, int x, int y)	{		for(Iterator<Layer> it = layerIterator; it.hasNext(); )		{			Layer layer = it.next();			if (layer == null) continue;			byte [][] layerBitMap = null;			int col = 0;			EGraphics graphics = layer.getGraphics();			if (graphics != null)			{				if (nowPrinting != 0 ? graphics.isPatternedOnPrinter() : graphics.isPatternedOnDisplay())				{					int [] pattern = graphics.getPattern();					if (pattern != null)					{						int pat = pattern[y&15];						if (pat == 0 || (pat & (0x8000 >> (x&15))) == 0) continue;					}				}				int layerNum = graphics.getTransparentLayer() - 1;				if (layerNum < numLayerBitMaps) layerBitMap = getLayerBitMap(layerNum);				col = graphics.getRGB();			}			// set the bit			if (layerBitMap == null)			{				int index = y * sz.width + x;				int alpha = (opaqueData[index] >> 24) & 0xFF;				if (alpha == 0xFF) opaqueData[index] = col;			} else			{				layerBitMap[y][x>>3] |= (1 << (x&7));			}		}	}	private void drawTinyArc(Iterator<Layer> layerIterator, Point head, Point tail)	{		for(Iterator<Layer> it = layerIterator; it.hasNext(); )		{			Layer layer = it.next();			if (layer == null) continue;			EGraphics graphics = layer.getGraphics();			byte [][] layerBitMap = null;			if (graphics != null)			{				int layerNum = graphics.getTransparentLayer() - 1;				if (layerNum < numLayerBitMaps) layerBitMap = getLayerBitMap(layerNum);			}			drawLine(head, tail, layerBitMap, graphics, 0, layer.isDimmed());		}	}	// ************************************* CELL CACHING *************************************	/**	 * @return true if the cell is properly handled and need no further processing.	 * False to render the contents recursively.	 */	private boolean expandedCellCached(Cell subCell, Orientation orient, AffineTransform origTrans, Cell topCell, Rectangle2D drawLimitBounds, boolean fullInstantiate)	{		// if there is no global for remembering cached cells, do not cache		if (expandedCells == null) return false;		// do not cache icons: they can be redrawn each time		if (subCell.isIcon()) return false;        ExpandedCellKey expansionKey = new ExpandedCellKey(subCell, orient);		ExpandedCellInfo expandedCellCount = expandedCells.get(expansionKey);		if (expandedCellCount != null)		{			// if this combination is not used multiple times, do not cache it			if (expandedCellCount.singleton && expandedCellCount.instanceCount < 2 && expandedCellCount.offscreen == null)			{				if (numberToReconcile > 0)				{					numberToReconcile--;					expandedCellCount.singleton = false;				} else return false;			}		}		if (expandedCellCount == null || expandedCellCount.offscreen == null)		{            // compute the cell's location on the screen            Rectangle2D cellBounds = new Rectangle2D.Double();            cellBounds.setRect(subCell.getBounds());            Rectangle2D textBounds = subCell.getTextBounds(dummyWnd);            if (textBounds != null)                cellBounds.add(textBounds);            AffineTransform rotTrans = orient.pureRotate();            DBMath.transformRect(cellBounds, rotTrans);            int lX = (int)Math.floor(cellBounds.getMinX()*scale);            int hX = (int)Math.ceil(cellBounds.getMaxX()*scale);            int lY = (int)Math.floor(cellBounds.getMinY()*scale);            int hY = (int)Math.ceil(cellBounds.getMaxY()*scale);            Rectangle screenBounds = new Rectangle(lX, lY, hX - lX, hY - lY);            if (screenBounds.width <= 0 || screenBounds.height <= 0) return true;			// do not cache if the cell is too large (creates immense offscreen buffers)			if (screenBounds.width >= topSz.width/2 && screenBounds.height >= topSz.height/2)				return false;			// if this is the first use, create the offscreen buffer			if (expandedCellCount == null)			{				expandedCellCount = new ExpandedCellInfo();				expandedCells.put(expansionKey, expandedCellCount);			}            expandedCellCount.offscreen = new PixelDrawing(scale, screenBounds);			expandedCellCount.offscreen.drawCell(subCell, null, fullInstantiate, orient, rotTrans, topCell);			offscreensCreated++;            offscreenPixelsCreated += expandedCellCount.offscreen.total;		}		// copy out of the offscreen buffer into the main buffer        databaseToScreen(origTrans.getTranslateX(), origTrans.getTranslateY(), tempPt1);		copyBits(expandedCellCount.offscreen, tempPt1.x, tempPt1.y);		offscreensUsed++;        offscreenPixelsUsed += expandedCellCount.offscreen.total;		return true;	}	/**	 * Recursive method to count the number of times that a cell-transformation is used	 */	private void countCell(Cell cell, Rectangle2D drawLimitBounds, boolean fullInstantiate, Orientation orient, AffineTransform prevTrans)	{		// look for subcells		for(Iterator<NodeInst> nodes = cell.getNodes(); nodes.hasNext(); )		{			NodeInst ni = nodes.next();			if (!ni.isCellInstance()) continue;			// 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)) return;			}			countNode(ni, drawLimitBounds, fullInstantiate, orient, prevTrans);		}	}	/**	 * Recursive method to count the number of times that a cell-transformation is used	 */	private void countNode(NodeInst ni, Rectangle2D drawLimitBounds, boolean fullInstantiate, Orientation orient, AffineTransform trans)	{		// if the node is tiny, it will be approximated		double objWidth = Math.max(ni.getXSize(), ni.getYSize());		if (objWidth < maxObjectSize) return;		// transform into the subcell        Orientation subOrient = orient.concatenate(ni.getOrient());		AffineTransform subTrans = ni.transformOut(trans);		// compute where this cell lands on the screen		NodeProto np = ni.getProto();		Cell subCell = (Cell)np;		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) return;		if (screenBounds.x > sz.width || screenBounds.x+screenBounds.width < 0) return;		if (screenBounds.y > sz.height || screenBounds.y+screenBounds.height < 0) return;		// only interested in expanded instances		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;					}				}			}		}		if (!expanded) return;		if (screenBounds.width < sz.width/2 || screenBounds.height <= sz.height/2)		{			// construct the cell name that combines with the transformation			ExpandedCellKey expansionKey = new ExpandedCellKey(subCell, subOrient);			ExpandedCellInfo expansionCount = expandedCells.get(expansionKey);			if (expansionCount == null)			{				expansionCount = new ExpandedCellInfo();				expansionCount.instanceCount = 1;				expandedCells.put(expansionKey, expansionCount);			} else			{				expansionCount.instanceCount++;				if (expansionCount.instanceCount > 1) return;			}		}		// now recurse		countCell(subCell, null, fullInstantiate, subOrient, subTrans);	}	public static void forceRedraw(Cell cell)	{        synchronized (changedCells) {            changedCells.add(cell.getId());        }	}	private static void forceRedraw(Set<CellId> changedCells)	{		// if there is no global for remembering cached cells, do not cache		if (expandedCells == null) return;		List<ExpandedCellKey> keys = new ArrayList<ExpandedCellKey>();		for(ExpandedCellKey eck : expandedCells.keySet() )			keys.add(eck);		for(ExpandedCellKey expansionKey : keys)		{            if (changedCells.contains(expansionKey.cell.getId()))				expandedCells.remove(expansionKey);		}	}	/**	 * Method to copy the offscreen bits for a cell into the offscreen bits for the entire screen.	 */	private void copyBits(PixelDrawing srcOffscreen, int centerX, int centerY)	{		if (srcOffscreen == null) return;		Dimension dim = srcOffscreen.sz;        int cornerX = centerX - (int)srcOffscreen.originX;        int cornerY = centerY - (int)srcOffscreen.originY;        int minSrcX = Math.max(0, clipLX - cornerX);        int maxSrcX = Math.min(dim.width - 1, clipHX - cornerX);        int minSrcY = Math.max(0, clipLY - cornerY);        int maxSrcY = Math.min(dim.height - 1, clipHY - cornerY);        if (minSrcX > maxSrcX || minSrcY > maxSrcY) return;        if (Job.getDebug() && numLayerBitMaps != srcOffscreen.numLayerBitMaps)            System.out.println("Possible mixture of technologies in PixelDrawing.copyBits");		// copy the opaque and transparent layers        for (int srcY = minSrcY; srcY <= maxSrcY; srcY++) {            int destY = srcY + cornerY;            assert destY >= clipLY && destY <= clipHY;            if (destY < 0 || destY >= sz.height) continue;            int srcBase = srcY * dim.width;            int destBase = destY * sz.width;            for (int srcX = minSrcX; srcX <= maxSrcX; srcX++) {                int destX = srcX + cornerX;                assert destX >= clipLX && destX <= clipHX;                if (destX < 0 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -