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

📄 postscriptcolor.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* -*- tab-width: 4 -*- * Electric(tm) VLSI Design System * * File: PostScriptColor.java * Input/output tool: PostScript color merged output * Written by: David Harris, 4/20/01 (David_Harris@hmc.edu) * Translated to Java by Steven Rubin: 12/05 * * Copyright (c) 2005 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.io.output;import com.sun.electric.database.geometry.EGraphics;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.prototype.NodeProto;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.text.Version;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.technology.Layer;import com.sun.electric.technology.Technology;import com.sun.electric.tool.Job;import com.sun.electric.tool.user.User;import java.awt.Color;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.PrintWriter;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;/** * This class writes files in PostScript format. * It handles color better than existing freely available * postscript generators.  It does not handle arbitrary rotations. * * Limitations: *  the code to handle quad trees is rather messy now * * Ideas: * 	center port labels * 	give options about aspect ratio / page size * 	put date on caption * 	print layers on caption * 	draw outlines around edges * 	handle black & white mode * * Things still to do: *    circles and arcs *    rotation of the plot *    eps */public class PostScriptColor{	// Constants	private static final int    MAXLAYERS = 1000;	private static final int    TREETHRESHOLD = 500;	private static final double SMALL_NUM = 0.000001;	private static final String FONTNAME = "Helvetica";	private static class PsPoly	{		double [] coords;		int       layer;	};	private static class PsBox	{		double [] pos = new double[4];  // 0: dx, 1: dy, 2: left, 3: bot		int       layer;		boolean   visible;	};	private static class PsLabel	{		String         label;		double []      pos = new double[4];		Poly.Type      style;		TextDescriptor descript;	};	private static class PsCell	{		int	             cellNum;		List<PsBox>      boxes;		List<PsPoly>     polys;		List<PsLabel>    labels;		List<PsCellInst> inst;	};	private static class PsCellInst	{		double []  transform = new double[9];		PsCell     inst;	};	private static class PsBoxElement	{		double [] pos = new double[4]; // 0: dx, 1: dy, 2: left, 3: bot		int       layer;		boolean   visible;	};	private static class PxBoxQuadTree	{		int             numBoxes;		PsBoxElement [] boxes;		double []       bounds = new double[4]; // 0: dx, 1: dy, 2: left, 3: bot		PxBoxQuadTree   tl;		PxBoxQuadTree   tr;		PxBoxQuadTree   bl;		PxBoxQuadTree   br;		PxBoxQuadTree   parent;		int             level;	};	private static class LayerMap	{		Layer      layer;		int        mix1, mix2; // layer made from mix of previous layers, or -1 if not		double     r, g, b;		double     opacity;		boolean    foreground;	};	// Globals	private double []            psBoundaries = new double[4];	private List<PsCell>         allCells;	private LayerMap  []         allLayers = new LayerMap[MAXLAYERS];	private List<ArrayList<PsBox>>flattenedBoxes = new ArrayList<ArrayList<PsBox>>();	private PxBoxQuadTree []     quadTrees = new PxBoxQuadTree[MAXLAYERS];	private List<ArrayList<PsPoly>>flattenedPolys = new ArrayList<ArrayList<PsPoly>>();	private int                  numLayers;	private int                  totalBoxes = 0;	private int                  totalCells = 0;	private int                  totalPolys = 0;	private int                  totalInstances = 0;	private int                  cellNumber;	private boolean              curveWarning;	private Set<Technology>      techsSetup;	private Map<Cell,PsCell>     cellStructs;	private PostScript           psObject;	private PostScriptColor(PostScript psObject)	{		this.psObject = psObject;	}	/**	 * Main entry point for color PostScript output.	 * @param psObject the PostScript writer object.	 * @param cell the Cell being written.	 * @param epsFormat true to write encapsulated PostScript.	 * @param usePlotter true for an infinitely-tall plotter, where page height is not a consideration.	 * @param pageWid the paper width (in 1/75 of an inch).	 * @param pageHei the paper height (in 1/75 of an inch).	 * @param pageMargin the inset margins (in 1/75 of an inch).	 */	public static void psColorPlot(PostScript psObject, Cell cell, boolean epsFormat, boolean usePlotter,		double pageWid, double pageHei, double pageMargin)	{		PostScriptColor psc = new PostScriptColor(psObject);		psc.doPrinting(cell, epsFormat, usePlotter, pageWid, pageHei, pageMargin);	}	private void doPrinting(Cell cell, boolean epsFormat, boolean usePlotter,		double pageWid, double pageHei, double pageMargin)	{		totalBoxes = totalCells = totalPolys = totalInstances = 0;		psBoundaries[0] = 1<<30;		psBoundaries[1] = 1<<30;		psBoundaries[2] = -1<<30;		psBoundaries[3] = -1<<30;		for (int i=0; i<MAXLAYERS; i++)			quadTrees[i] = null;		cellNumber = 1;		// initialize layer maps for the current technology		numLayers = 0;		techsSetup = new HashSet<Technology>();		// mark all cells as "not written"		cellStructs = new HashMap<Cell,PsCell>();		getLayerMap(Technology.getCurrent());		curveWarning = false;		allCells = new ArrayList<PsCell>();		extractDatabase(cell);		mergeBoxes();		flatten();		genOverlapShapesAfterFlattening();		writePS(cell, usePlotter, pageWid, pageHei, pageMargin);//		printStatistics();	}	/**	 * Method to get the print colors and load them into the layer map.	 */	private void getLayerMap(Technology tech)	{		// see if this technology has already been done		if (techsSetup.contains(tech)) return;		techsSetup.add(tech);		// read layer map		int startLayer = numLayers;		List<Layer> layerSorts = new ArrayList<Layer>();		for(int i=0; i<tech.getNumLayers(); i++)		{			Layer layer = tech.getLayer(i);			if (layer.isPseudoLayer()) continue;			layerSorts.add(layer);		}		// sort by layer height		Collections.sort(layerSorts, new LayersByDepth());		// load the layer information		for(int i=0; i<layerSorts.size(); i++)		{			if (numLayers >= MAXLAYERS)			{				System.out.println("More than " + MAXLAYERS + " layers");				break;			}			Layer layer = layerSorts.get(i);			allLayers[numLayers] = new LayerMap();			allLayers[numLayers].layer = layer;			EGraphics graph = layer.getGraphics();			allLayers[numLayers].opacity = graph.getOpacity();			allLayers[numLayers].foreground = graph.getForeground();			Color col = graph.getColor();			allLayers[numLayers].r = col.getRed() / 255.0;			allLayers[numLayers].g = col.getGreen() / 255.0;			allLayers[numLayers].b = col.getBlue() / 255.0;			allLayers[numLayers].mix1 = -1;			allLayers[numLayers].mix2 = -1;			if (allLayers[numLayers].opacity < 1)			{				// create new layers to provide transparency				int curLayer = numLayers;				for (int k=startLayer; k < curLayer; k++)				{					if (allLayers[k].foreground)					{						allLayers[++numLayers] = new LayerMap();						allLayers[numLayers].opacity = 1;						allLayers[numLayers].layer = null;						allLayers[numLayers].foreground = true;						allLayers[numLayers].r = allLayers[curLayer].r*allLayers[curLayer].opacity +							allLayers[k].r*(1-allLayers[curLayer].opacity);						allLayers[numLayers].g = allLayers[curLayer].g*allLayers[curLayer].opacity +							allLayers[k].g*(1-allLayers[curLayer].opacity);						allLayers[numLayers].b = allLayers[curLayer].b*allLayers[curLayer].opacity +							allLayers[k].b*(1-allLayers[curLayer].opacity);						allLayers[numLayers].mix1 = k;						allLayers[numLayers].mix2 = curLayer;					}				}			}			numLayers++;		}	}	/**	 * Comparator class for sorting Layers by their height.	 */	private static class LayersByDepth implements Comparator<Layer>	{		/**		 * Method to sort LayerSort by their height.		 */		public int compare(Layer l1, Layer l2)		{			double diff = l1.getDepth() - l2.getDepth();			if (diff == 0.0) return 0;			if (diff < 0.0) return -1;			return 1;		}	}	private void extractDatabase(Cell cell)	{		// check for subcells that haven't been written yet		for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )		{			NodeInst ni = it.next();			if (!ni.isCellInstance()) continue;			if (!ni.isExpanded()) continue;			Cell subCell = (Cell)ni.getProto();			if (cellStructs.get(subCell) != null) continue;			extractDatabase(subCell);		}		// create a cell		PsCell curCell = new PsCell();		curCell.cellNum = cellNumber++;		curCell.boxes = new ArrayList<PsBox>();		curCell.polys = new ArrayList<PsPoly>();		curCell.labels = new ArrayList<PsLabel>();		curCell.inst = new ArrayList<PsCellInst>();		totalCells++;		// add to the lists		allCells.add(curCell);		cellStructs.put(cell, curCell);		// examine all nodes in the cell		for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )		{			NodeInst ni = it.next();			NodeProto np = ni.getProto();			if (ni.isCellInstance())			{				// instance				if (!ni.isExpanded())				{					// look for a black layer					int i = 0;					for( ; i<numLayers; i++)						if (allLayers[i].r == 0 && allLayers[i].g == 0 &&								allLayers[i].b == 0 && allLayers[i].opacity == 1) break;					if (i < numLayers)					{						// draw a box by plotting 4 lines						Rectangle2D niBounds = ni.getBounds();						PsBox curBox = new PsBox();						curBox.layer = i;						curBox.visible = true;						curBox.pos[0] = 1;						curBox.pos[1] = niBounds.getHeight();						curBox.pos[2] = niBounds.getMinX();						curBox.pos[3] = niBounds.getMinY();						curCell.boxes.add(curBox);						curBox = new PsBox();						curBox.layer = i;						curBox.visible = true;						curBox.pos[0] = niBounds.getWidth();						curBox.pos[1] = 1;						curBox.pos[2] = niBounds.getMinX();						curBox.pos[3] = niBounds.getMinY();						curCell.boxes.add(curBox);						curBox = new PsBox();						curBox.layer = i;						curBox.visible = true;						curBox.pos[0] = 1;						curBox.pos[1] = niBounds.getHeight();						curBox.pos[2] = niBounds.getMaxX();						curBox.pos[3] = niBounds.getMinY();						curCell.boxes.add(curBox);						curBox = new PsBox();						curBox.layer = i;						curBox.visible = true;						curBox.pos[0] = niBounds.getWidth();						curBox.pos[1] = 1;						curBox.pos[2] = niBounds.getMinX();						curBox.pos[3] = niBounds.getMaxY();						curCell.boxes.add(curBox);						// add the cell name						PsLabel curLabel = new PsLabel();						curLabel.label = ni.getProto().describe(false);						curLabel.pos[0] = niBounds.getMinX();						curLabel.pos[1] = niBounds.getMaxX();						curLabel.pos[2] = niBounds.getMinY();						curLabel.pos[3] = niBounds.getMaxY();						curLabel.style = Poly.Type.TEXTBOX;						curLabel.descript = ni.getTextDescriptor(NodeInst.NODE_NAME);						curCell.labels.add(curLabel);					}				} else				{					// expanded instance: make the invocation					Cell npCell = (Cell)np;					PsCell subCell = cellStructs.get(npCell);					PsCellInst curInst = new PsCellInst();					curInst.inst = subCell;					newIdentityMatrix(curInst.transform);					// account for instance position					double [] transT = new double[9];					newIdentityMatrix(transT);					Rectangle2D cellBounds = npCell.getBounds();					transT[2*3+0] -= cellBounds.getCenterX();					transT[2*3+1] -= cellBounds.getCenterY();					matrixMul(curInst.transform, curInst.transform, transT);					// account for instance rotation					double [] transR = new double[9];					newIdentityMatrix(transR);					Orientation o = ni.getOrient();					double rotation = o.getCAngle() / 1800.0 * Math.PI;					transR[0*3+0] = Math.cos(rotation); if (Math.abs(transR[0]) < SMALL_NUM) transR[0] = 0;					transR[0*3+1] = Math.sin(rotation); if (Math.abs(transR[1]) < SMALL_NUM) transR[1] = 0;					transR[1*3+0] = -Math.sin(rotation); if (Math.abs(transR[3]) < SMALL_NUM) transR[3] = 0;					transR[1*3+1] = Math.cos(rotation); if (Math.abs(transR[4]) < SMALL_NUM) transR[4] = 0;					matrixMul(curInst.transform, curInst.transform, transR);					// account for instance transposition					if (o.isCTranspose())					{						newIdentityMatrix(transR);						transR[0*3+0] = 0;						transR[1*3+1] = 0;						transR[0*3+1] = -1;						transR[1*3+0] = -1;						matrixMul(curInst.transform, curInst.transform, transR);					}					// account for instance location					newIdentityMatrix(transT);					transT[2*3+0] = ni.getAnchorCenterX();					transT[2*3+1] = ni.getAnchorCenterY();					matrixMul(curInst.transform, curInst.transform, transT);					curCell.inst.add(curInst);				}			} else			{				// primitive: generate its layers				AffineTransform trans = ni.rotateOut();

⌨️ 快捷键说明

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