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

📄 vectordrawing.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			result.y = (int)(scrY >= 0 ? scrY + 0.5 : scrY - 0.5);		}	}	/**	 * Method to draw a tiny box on the screen in a given color.	 * Done when the object is too small to draw in full detail.	 * @param lX the low X coordinate of the box.	 * @param hX the high X coordinate of the box.	 * @param lY the low Y coordinate of the box.	 * @param hY the high Y coordinate of the box.	 * @param col the color to draw.	 */	private void drawTinyBox(int lX, int hX, int lY, int hY, int col, VectorCache.VectorCell greekedCell)	{		if (lX < screenLX) lX = screenLX;		if (hX >= screenHX) hX = screenHX-1;		if (lY < screenLY) lY = screenLY;		if (hY >= screenHY) hY = screenHY-1;		if (User.isUseCellGreekingImages())		{			if (greekedCell != null && greekedCell.fadeImageColors != null)			{				int backgroundColor = User.getColor(User.ColorPrefType.BACKGROUND);				int backgroundRed = (backgroundColor >> 16) & 0xFF;				int backgroundGreen = (backgroundColor >> 8) & 0xFF;				int backgroundBlue = backgroundColor & 0xFF;				// render the icon properly with scale				int greekWid = greekedCell.fadeImageWid;				int greekHei = greekedCell.fadeImageHei;				int wid = hX - lX;				int hei = hY - lY;				float xInc = greekWid / (float)wid;				float yInc = greekHei / (float)hei;				float yPos = 0;				for(int y=0; y<hei; y++)				{					float yEndPos = yPos + yInc;					int yS = (int)yPos;					int yE = (int)yEndPos;					float xPos = 0;					for(int x=0; x<wid; x++)					{						float xEndPos = xPos + xInc;						int xS = (int)xPos;						int xE = (int)xEndPos;						float r = 0, g = 0, b = 0;						float totalArea = 0;						for(int yGrab = yS; yGrab <= yE; yGrab++)						{							if (yGrab >= greekHei) continue;							float yArea = 1;							if (yGrab == yS) yArea = (1 - (yPos - yS));							if (yGrab == yE) yArea *= (yEndPos-yE);							for(int xGrab = xS; xGrab <= xE; xGrab++)							{								if (xGrab >= greekWid) continue;								int index = xGrab + yGrab*greekedCell.fadeImageWid;								if (greekedCell.fadeImageColors==null || index >= greekedCell.fadeImageColors.length)									continue;								int value = greekedCell.fadeImageColors[index];								int red = (value >> 16) & 0xFF;								int green = (value >> 8) & 0xFF;								int blue = value & 0xFF;								float area = yArea;								if (xGrab == xS) area *= (1 - (xPos - xS));								if (xGrab == xE) area *= (xEndPos-xE);								if (area <= 0) continue;								r += red * area;								g += green * area;								b += blue * area;								totalArea += area;							}						}						if (totalArea > 0)						{							int red = (int)(r / totalArea);							if (red > 255) red = 255;							int green = (int)(g / totalArea);							if (green > 255) green = 255;							int blue = (int)(b / totalArea);							if (blue > 255) blue = 255;							if (Math.abs(backgroundRed-red) > 2 || Math.abs(backgroundGreen-green) > 2 ||								Math.abs(backgroundBlue-blue) > 2)							{								offscreen.drawPoint(lX+x, lY+y, null, (red << 16) | (green << 8) | blue);							}						}						xPos = xEndPos;					}					yPos = yEndPos;				}				if (DEBUGIMAGES)				{					for(int y=0; y<greekedCell.fadeImageHei; y++)					{						for(int x=0; x<greekedCell.fadeImageWid; x++)						{							int valToSet = greekedCell.fadeImageColors[x+y*greekedCell.fadeImageWid];							topVD.offscreen.drawPoint(greekedCell.fadeOffsetX+x+1, greekedCell.fadeOffsetY+y+1, null, valToSet);						}						topVD.offscreen.drawPoint(greekedCell.fadeOffsetX, greekedCell.fadeOffsetY+y+1, null, 0);						topVD.offscreen.drawPoint(greekedCell.fadeOffsetX+greekedCell.fadeImageWid+1, greekedCell.fadeOffsetY+y+1, null, 0);					}					for(int x=0; x<greekedCell.fadeImageWid; x++)					{						topVD.offscreen.drawPoint(greekedCell.fadeOffsetX+x, greekedCell.fadeOffsetY, null, 0);						topVD.offscreen.drawPoint(greekedCell.fadeOffsetX+x, greekedCell.fadeOffsetY+greekedCell.fadeImageHei+1, null, 0);					}				}				return;			}		}		// no greeked image: just use the greeked color		for(int y=lY; y<=hY; y++)		{			for(int x=lX; x<=hX; x++)				offscreen.drawPoint(x, y, null, col);		}	}	/**	 * Method to determine whether a cell has tiny contents.	 * Recursively examines the cache of this and all subcells to see if the	 * maximum feature sizes are all below the global threshold "maxObjectSize".	 * @param cell the Cell in question.	 * @param vc the cached representation of the cell.	 * @param trans the Orientation of the cell.	 * @return true if the cell has all tiny contents.	 */	private boolean isContentsTiny(Cell cell, VectorCache.VectorCell vc, Orientation trans, VarContext context)		throws AbortRenderingException	{		if (vc.maxFeatureSize > maxObjectSize) return false;		for(VectorCache.VectorSubCell vsc : vc.subCells)		{			NodeInst ni = cell.getNodeById(vsc.n.nodeId);			VectorCache.VectorCell subVC = VectorCache.theCache.findVectorCell(vsc.subCellId, vc.orient.concatenate(vsc.n.orient));			if (ni.isExpanded() || fullInstantiate)			{				Orientation thisOrient = ni.getOrient();				Orientation recurseTrans = trans.concatenate(thisOrient);				VarContext subContext = context.push(ni);				Cell subCell = (Cell)ni.getProto();				VectorCache.VectorCell subVC_ = drawCell(subCell, recurseTrans, subContext);				assert subVC_ == subVC;				boolean subCellTiny = isContentsTiny(subCell, subVC, recurseTrans, subContext);				if (!subCellTiny) return false;				continue;			}			if (subVC.vcg.cellMinSize > maxObjectSize) return false;		}		return true;	}	private void makeGreekedImage(VectorCache.VectorCell subVC)		throws AbortRenderingException	{		if (subVC.fadeImage) return;		if (!User.isUseCellGreekingImages()) return;		// determine size and scale of greeked cell image		Rectangle2D cellBounds = subVC.vcg.bounds;		Rectangle2D ownBounds = new Rectangle2D.Double(cellBounds.getMinX(), cellBounds.getMinY(), cellBounds.getWidth(), cellBounds.getHeight());		AffineTransform trans = subVC.orient.rotateAbout(0, 0);		DBMath.transformRect(ownBounds, trans);		double greekScale = MAXGREEKSIZE / ownBounds.getHeight();		if (ownBounds.getWidth() > ownBounds.getHeight())			greekScale = MAXGREEKSIZE / ownBounds.getWidth();		int lX = (int)Math.floor(cellBounds.getMinX()*greekScale);		int hX = (int)Math.ceil(cellBounds.getMaxX()*greekScale);		int lY = (int)Math.floor(cellBounds.getMinY()*greekScale);		int hY = (int)Math.ceil(cellBounds.getMaxY()*greekScale);		if (hX <= lX) hX = lX + 1;		int greekWid = hX - lX;		if (hY <= lY) hY = lY + 1;		int greekHei = hY - lY;		Rectangle screenBounds = new Rectangle(lX, lY, greekWid, greekHei);		// construct the offscreen buffers for the greeked cell image		PixelDrawing offscreen = new PixelDrawing(greekScale, screenBounds);		Point2D cellCtr = new Point2D.Double(ownBounds.getCenterX(), ownBounds.getCenterY());		VectorDrawing subVD = new VectorDrawing();		subVC.fadeOffsetX = debugXP;		subVC.fadeOffsetY = debugYP;		debugXP += MAXGREEKSIZE + 5;		if (topVD != null)		{			if (debugXP + MAXGREEKSIZE+2 >= topVD.offscreen.getSize().width)			{				debugXP = 0;				debugYP += MAXGREEKSIZE + 5;			}		}		// set rendering information for the greeked cell image		subVD.offscreen = offscreen;		subVD.screenLX = 0;   subVD.screenHX = greekWid;		subVD.screenLY = 0;   subVD.screenHY = greekHei;		subVD.szHalfWidth = greekWid / 2;		subVD.szHalfHeight = greekHei / 2;		subVD.maxObjectSize = 0;		subVD.maxTextSize = 0;		subVD.scale = (float)greekScale;		subVD.scale_ = (float)(greekScale/DBMath.GRID);		subVD.factorX = (float)(cellCtr.getX()*DBMath.GRID - subVD.szHalfWidth/subVD.scale_);		subVD.factorY = (float)(cellCtr.getY()*DBMath.GRID + subVD.szHalfHeight/subVD.scale_);		subVD.factorX_ = (int)subVD.factorX;		subVD.factorY_ = (int)subVD.factorY;		subVD.scale_int = (int)(subVD.scale_ * (1 << SCALE_SH));		subVD.fullInstantiate = true;		subVD.takingLongTime = true;		// render the greeked cell		subVD.offscreen.clearImage(null);		subVD.render(subVC, 0, 0, VarContext.globalContext, -1);		subVD.offscreen.composite(null);		// remember the greeked cell image		int[] img = offscreen.getOpaqueData();		subVC.fadeImageWid = greekWid;		subVC.fadeImageHei = greekHei;		subVC.fadeImageColors = new int[subVC.fadeImageWid * subVC.fadeImageHei];		int i = 0;		for(int y=0; y<subVC.fadeImageHei; y++)		{			for(int x=0; x<subVC.fadeImageWid; x++)			{				int value = img[i];				subVC.fadeImageColors[i++] = value & 0xFFFFFF;			}		}		subVC.fadeImage = true;	}	/**	 * Method to determine the "fade" color for a cached cell.	 * Fading is done when the cell is too tiny to draw (or all of its contents are too tiny).	 * Instead of drawing the cell contents, the entire cell is painted with the "fade" color.	 * @param vc the cached cell.	 * @return the fade color (an integer with red/green/blue).	 */	private int getFadeColor(VectorCache.VectorCell vc, VarContext context)		throws AbortRenderingException	{		if (vc.hasFadeColor) return vc.fadeColor;		// examine all shapes		Map<Layer,MutableDouble> layerAreas = new HashMap<Layer,MutableDouble>();		gatherContents(vc, layerAreas, context);		// now compute the color		Set<Layer> keys = layerAreas.keySet();		double totalArea = 0;		for(Layer layer : keys)		{			MutableDouble md = layerAreas.get(layer);			totalArea += md.doubleValue();		}		double r = 0, g = 0, b = 0;		if (totalArea != 0)		{			for(Layer layer : keys)			{				MutableDouble md = layerAreas.get(layer);				double portion = md.doubleValue() / totalArea;				EGraphics desc = layer.getGraphics();				Color col = desc.getColor();				r += col.getRed() * portion;				g += col.getGreen() * portion;				b += col.getBlue() * portion;			}		}		if (r < 0) r = 0;   if (r > 255) r = 255;		if (g < 0) g = 0;   if (g > 255) g = 255;		if (b < 0) b = 0;   if (b > 255) b = 255;		vc.fadeColor = (((int)r) << 16) | (((int)g) << 8) | (int)b;		vc.hasFadeColor = true;		return vc.fadeColor;	}	/**	 * Helper method to recursively examine a cached cell and its subcells and compute	 * the coverage of each layer.	 * @param vc the cached cell to examine.	 * @param layerAreas a HashMap of all layers and the areas they cover.	 */	private void gatherContents(VectorCache.VectorCell vc, Map<Layer,MutableDouble> layerAreas, VarContext context)		throws AbortRenderingException	{		for(VectorCache.VectorBase vb : vc.filledShapes)		{			Layer layer = vb.layer;			if (layer == null) continue;			Layer.Function fun = layer.getFunction();			if (fun.isImplant() || fun.isSubstrate()) continue;			// handle each shape			double area = 0;			if (vb instanceof VectorCache.VectorManhattan)			{				VectorCache.VectorManhattan vm = (VectorCache.VectorManhattan)vb;				for (int i = 0; i < vm.coords.length; i += 4) {					double c1X = vm.coords[i];					double c1Y = vm.coords[i + 1];					double c2X = vm.coords[i + 2];					double c2Y = vm.coords[i + 3];					area += (c1X-c2X) * (c1Y-c2Y);				}			} else if (vb instanceof VectorCache.VectorPolygon)			{				VectorCache.VectorPolygon vp = (VectorCache.VectorPolygon)vb;				area = GenMath.getAreaOfPoints(vp.points);			} else if (vb instanceof VectorCache.VectorCircle)			{				VectorCache.VectorCircle vci = (VectorCache.VectorCircle)vb;				double radius = new Point2D.Double(vci.cX, vci.cY).distance(new Point2D.Double(vci.eX, vci.eY));				area = radius * radius * Math.PI;			}			if (area == 0) continue;			MutableDouble md = layerAreas.get(layer);			if (md == null)			{				md = new MutableDouble(0);				layerAreas.put(layer, md);			}			md.setValue(md.doubleValue() + area);		}		Cell cell = VectorCache.theCache.database.getCell(vc.vcg.cellId);		for(VectorCache.VectorSubCell vsc : vc.subCells)		{			VectorCache.VectorCellGroup vcg = VectorCache.theCache.findCellGroup(vsc.subCellId);			VectorCache.VectorCell subVC = vcg.getAnyCell();			NodeInst ni = cell.getNodeById(vsc.n.nodeId);			VarContext subContext = context.push(ni);			if (subVC == null)				subVC = drawCell((Cell)ni.getProto(), Orientation.IDENT, subContext);			gatherContents(subVC, layerAreas, subContext);		}	}	// ************************************* CACHE CREATION *************************************	/**	 * Method to cache the contents of a cell.	 * @param cell the Cell to cache	 * @param prevTrans the orientation of the cell (just a rotation, no offsets here).	 * @return a cached cell object for the given Cell.	 */	private VectorCache.VectorCell drawCell(Cell cell, Orientation prevTrans, VarContext context)		throws AbortRenderingException	{		// caching the cell: check for abort and delay reporting		if (stopRendering) throw new AbortRenderingException();		if (!takingLongTime)		{			long currentTime = System.currentTimeMillis();			if (currentTime - startTime > 1000)			{				System.out.print("Display caching, please wait...");				TopLevel.setBusyCursor(true);				takingLongTime = true;			}		}		return VectorCache.theCache.drawCell(cell.getId(), prevTrans, context, scale);	}}

⌨️ 快捷键说明

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