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

📄 postscript.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: PostScript.java * Input/output tool: PostScript output * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2004 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.DBMath;import com.sun.electric.database.geometry.EGraphics;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;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.Connection;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.io.IOTool;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.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;/** * This class writes files in PostScript format. */public class PostScript extends Output{	/** scale factor for PostScript */				private static final int    PSSCALE        =  4;//	/** scale factor for PostScript text */			private static final double PSTEXTSCALE    =  0.45;	/** scale factor for PostScript text */			private static final double PSTEXTSCALE    =  0.75;	/** size of text in the corner */				private static final int    CORNERDATESIZE = 14;	/** default text plain font */					private static final String DEFAULTFONT = "Times-Roman";	/** default text bold font */					private static final String DEFAULTFONTBOLD = "Times-Bold";	/** default text italic font */					private static final String DEFAULTFONTITALIC = "Times-Italic";	/** default text bold-italic font */			private static final String DEFAULTFONTBI = "Times-BoldItalic";	/** write macros for dot drawing */				private static final int HEADERDOT      =  1;	/** write macros for line drawing */			private static final int HEADERLINE     =  2;	/** write macros for polygon drawing */			private static final int HEADERPOLYGON  =  3;	/** write macros for filled polygon drawing */	private static final int HEADERFPOLYGON =  4;	/** write macros for text drawing */			private static final int HEADERSTRING   =  5;	/** true if the "dot" header code has been written. */				private boolean putHeaderDot;	/** true if the "line" header code has been written. */				private boolean putHeaderLine;	/** true if the "polygon" header code has been written. */			private boolean putHeaderPolygon;	/** true if the "filled polygon" header code has been written. */	private boolean putHeaderFilledPolygon;	/** true if the "string" header code has been written. */			private boolean putHeaderString;	/** true to generate color PostScript. */							private boolean psUseColor;	/** true to generate merged color PostScript. */					private boolean psUseColorMerge;	/** the Cell being written. */										private Cell cell;	private Rectangle2D printBounds;	/** list of Polys to use instead of cell contents. */				private List<PolyBase> override;	/** the EditWindow_ in which the cell resides. */					private EditWindow_ wnd;	/** number of patterns emitted so far. */							private int psNumPatternsEmitted;	/** list of patterns emitted so far. */								private HashMap<EGraphics,Integer> patternsEmitted;	/** current layer number (-1: do all; 0: cleanup). */				private int currentLayer;	/** the last color written out. */									private int lastColor;	/** the normal width of lines. */									private int lineWidth;	/** true to plot date information in the corner. */					private boolean plotDates;	/** matrix from database units to PS units. */						private AffineTransform matrix;	/** fake layer for drawing outlines and text. */					private static Layer blackLayer = Layer.newInstanceFree(null, "black",		new EGraphics(false, false, null, 0, 100,100,100,1.0,true, new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));	/**	 * Main entry point for PostScript output.	 * @param cell the top-level cell to write.	 * @param filePath the disk file to create.	 * @param override a list of overriding polygons to write.	 */	public static void writePostScriptFile(Cell cell, String filePath, List<PolyBase> override)	{		// just do this file		writeCellToFile(cell, filePath, override);	}	/**	 * Internal method for PostScript output.	 * @param cell the top-level cell to write.	 * @param filePath the disk file to create.	 * @param override a list of overriding polygons to write.	 */	private static boolean writeCellToFile(Cell cell, String filePath, List<PolyBase> override)	{		boolean error = false;		PostScript out = new PostScript(cell, override);		if (out.openTextOutputStream(filePath)) error = true; else		{			// write out the cell			if (cell.getView().isTextView())			{				// text cell				out.printWriter.println("Library: " + cell.getLibrary().getName() + "   Cell: " + cell.noLibDescribe());				if (User.isIncludeDateAndVersionInOutput())				{					out.printWriter.println("   Created: " + TextUtils.formatDate(cell.getCreationDate()) +						"   Revised: " + TextUtils.formatDate(cell.getRevisionDate()));				}				out.printWriter.println("\n\n");				// print the text of the cell				Variable var = cell.getVar(Cell.CELL_TEXT_KEY);				if (var != null)				{					String [] strings = (String [])var.getObject();					for(int i=0; i<strings.length; i++)						out.printWriter.println(strings[i]);				}			} else			{				// layout/schematics cell				if (out.start())				{					out.scanCircuit();					out.done();				}			}			if (out.closeTextOutputStream()) error = true;		}		if (!error)		{			System.out.println(filePath + " written");		}		return error;	}	/**	 * PostScript constructor.	 */	private PostScript(Cell cell, List<PolyBase> override)	{		this.cell = cell;		this.override = override;	}	/**	 * Method to initialize for writing a cell.	 * @return false to abort the process.	 */	private boolean start()	{		// find the edit window		UserInterface ui = Job.getUserInterface();		wnd = ui.getCurrentEditWindow_();		if (wnd != null && wnd.getCell() != cell) wnd = null;		// clear flags that tell whether headers have been included		putHeaderDot = false;		putHeaderLine = false;		putHeaderPolygon = false;		putHeaderFilledPolygon = false;		putHeaderString = false;		// get control options		psUseColor = psUseColorMerge = false;		switch (IOTool.getPrintColorMethod())		{			case 1:		// color				psUseColor = true;				break;			case 2:		// color stippled				psUseColor = true;				break;			case 3:		// color merged				psUseColor = psUseColorMerge = true;				break;		}		boolean usePlotter = IOTool.isPrintForPlotter();		plotDates = IOTool.isPlotDate();		boolean epsFormat = IOTool.isPrintEncapsulated();		double pageWid = IOTool.getPrintWidth() * 75;		double pageHei = IOTool.getPrintHeight() * 75;		double pageMarginPS = IOTool.getPrintMargin() * 75;		double pageMargin = pageMarginPS;		// not right!!!		// determine the area of interest		printBounds = null;		if (override != null)		{			double lX=0, hX=0, lY=0, hY=0;			boolean first = true;			for(PolyBase poly : override)			{				Point2D [] points = poly.getPoints();				for(int i=0; i<points.length; i++)				{					double x = points[i].getX();					double y = points[i].getY();					if (first)					{						first = false;						lX = hX = x;						lY = hY = y;					} else					{						if (x < lX) lX = x;						if (x > hX) hX = x;						if (y < lY) lY = y;						if (y > hY) hY = y;					}				}			}			printBounds = new Rectangle2D.Double(lX, lY, hX-lX, hY-lY);		} else		{			printBounds = getAreaToPrint(cell, false, wnd);		}		if (printBounds == null) return false;		boolean rotatePlot = false;		switch (IOTool.getPrintRotation())		{			case 1:		// rotate 90 degrees				rotatePlot = true;				break;			case 2:		// auto-rotate				if (((pageHei > pageWid || usePlotter) && printBounds.getWidth() > printBounds.getHeight()) ||					(pageWid > pageHei && printBounds.getHeight() > printBounds.getWidth()))						rotatePlot = true;				break;		}		// if plotting, compute height from width		if (usePlotter)		{			if (rotatePlot)			{				pageHei = pageWid * printBounds.getWidth() / printBounds.getHeight();			} else			{				pageHei = pageWid * printBounds.getHeight() / printBounds.getWidth();			}		}		// for pure color plotting, use special merging code		if (psUseColorMerge && override == null)		{			PostScriptColor.psColorPlot(this, cell, epsFormat, usePlotter, pageWid, pageHei, pageMarginPS);			return false;		}		// PostScript: compute the transformation matrix		double cX = printBounds.getCenterX();		double cY = printBounds.getCenterY();		double unitsX = (pageWid-pageMargin*2) * PSSCALE;		double unitsY = (pageHei-pageMargin*2) * PSSCALE;		if (epsFormat)		{			double scale = IOTool.getPrintEPSScale(cell);			if (scale != 0)			{				unitsX *= scale;				unitsY *= scale;			}		}		double i, j;		if (usePlotter)		{			i = unitsX / printBounds.getWidth();			j = unitsX / printBounds.getHeight();		} else		{			i = Math.min(unitsX / printBounds.getWidth(), unitsY / printBounds.getHeight());			j = Math.min(unitsX / printBounds.getHeight(), unitsY / printBounds.getWidth());		}		if (rotatePlot) i = j;		double matrix00 = i;   double matrix01 = 0;		double matrix10 = 0;   double matrix11 = i;		double matrix20 = - i * cX + unitsX / 2 + pageMarginPS * PSSCALE;		double matrix21;		if (usePlotter)		{			matrix21 = - i * printBounds.getMinY() + pageMarginPS * PSSCALE;		} else		{			matrix21 = - i * cY + unitsY / 2 + pageMarginPS * PSSCALE;		}		matrix = new AffineTransform(matrix00, matrix01, matrix10, matrix11, matrix20, matrix21);		// write PostScript header		if (epsFormat) printWriter.println("%!PS-Adobe-2.0 EPSF-2.0"); else			printWriter.println("%!PS-Adobe-1.0");		printWriter.println("%%Title: " + cell.describe(false));		if (User.isIncludeDateAndVersionInOutput())		{			printWriter.println("%%Creator: Electric VLSI Design System version " + Version.getVersion());			Date now = new Date();			printWriter.println("%%CreationDate: " + TextUtils.formatDate(now));		} else		{			printWriter.println("%%Creator: Electric VLSI Design System");		}		if (epsFormat) printWriter.println("%%Pages: 0"); else			printWriter.println("%%Pages: 1");		emitCopyright("% ", "");		// transform to PostScript units		double bblx = printBounds.getMinX();		double bbhx = printBounds.getMaxX();		double bbly = printBounds.getMinY();		double bbhy = printBounds.getMaxY();		Point2D bbCorner1 = psXform(new Point2D.Double(bblx, bbly));		Point2D bbCorner2 = psXform(new Point2D.Double(bbhx, bbhy));		bblx = bbCorner1.getX();		bbly = bbCorner1.getY();		bbhx = bbCorner2.getX();		bbhy = bbCorner2.getY();		if (rotatePlot)		{			/*			 * fiddle with the bbox if image rotated on page			 * (at this point, bbox coordinates are absolute printer units)			 */			double t1 = bblx;			double t2 = bbhx;			bblx = -bbhy + pageHei * 300 / 75;			bbhx = -bbly + pageHei * 300 / 75;			bbly = t1 + pageMargin*2 * 300 / 75;		// this may not work because "pageMargin" is badly defined			bbhy = t2 + pageMargin*2 * 300 / 75;		}		if (bblx > bbhx) { double s = bblx;  bblx = bbhx;  bbhx = s; }		if (bbly > bbhy) { double s = bbly;  bbly = bbhy;  bbhy = s; }		bblx = bblx / (PSSCALE * 75.0) * 72.0 * (bblx>=0 ? 1 : -1);		bbly = bbly / (PSSCALE * 75.0) * 72.0 * (bbly>=0 ? 1 : -1);		bbhx = bbhx / (PSSCALE * 75.0) * 72.0 * (bbhx>=0 ? 1 : -1);		bbhy = bbhy / (PSSCALE * 75.0) * 72.0 * (bbhy>=0 ? 1 : -1);		/*		 * Increase the size of the bbox by one "pixel" to		 * prevent the edges from being obscured by some drawing tools		 */		printWriter.println("%%BoundingBox: " + (int)(bblx-1) + " " + (int)(bbly-1) + " " + (int)(bbhx+1) + " " + (int)(bbhy+1));		printWriter.println("%%DocumentFonts: " + DEFAULTFONT);		printWriter.println("%%EndComments");		if (!epsFormat) printWriter.println("%%Page: 1 1");		// PostScript: add some debugging info		if (cell != null)		{			Rectangle2D bounds = cell.getBounds();			printWriter.println("% cell dimensions: " + bounds.getWidth() + " wide x " + bounds.getHeight() + " high (database units)");			printWriter.println("% origin: " + bounds.getMinX() + " " + bounds.getMinY());		}		// disclaimers		if (epsFormat)		{			printWriter.println("% The EPS header should declare a private dictionary.");		} else		{			printWriter.println("% The non-EPS header does not claim conformance to Adobe-2.0");			printWriter.println("% because the structure may not be exactly correct.");		}		printWriter.println("%");		// set the page size if this is a plotter		if (usePlotter)		{			printWriter.println("<< /PageSize [" + (int)(pageWid * 72 / 75) + " " + (int)(pageHei * 72 / 75) + "] >> setpagedevice");		}		// make the scale be exactly equal to one page pixel		printWriter.println("72 " + PSSCALE*75 + " div 72 " + PSSCALE*75 + " div scale");		// set the proper typeface		printWriter.println("/DefaultFont /" + DEFAULTFONT + " def");		printWriter.println("/scaleFont {");		printWriter.println("    DefaultFont findfont");		printWriter.println("    exch scalefont setfont} def");		// make the line width proper		lineWidth = (int)(PSSCALE/2 * IOTool.getPrintPSLineWidth());		printWriter.println(lineWidth + " setlinewidth");		// make the line ends look right		printWriter.println("1 setlinecap");		// rotate the image if requested		if (rotatePlot)		{			if (usePlotter)			{				printWriter.println((pageWid/75) + " 300 mul " + ((pageHei-pageWid)/2/75) + " 300 mul translate 90 rotate");			} else			{				printWriter.println((pageHei+pageWid)/2/75 + " 300 mul " + (pageHei-pageWid)/2/75 + " 300 mul translate 90 rotate");			}		}		// initialize list of EGraphics modules that have been put out		patternsEmitted = new HashMap<EGraphics,Integer>();		psNumPatternsEmitted = 0;		return true;	}	/**	 * Method to clean-up writing a cell.	 */	private void done()	{		// draw the grid if requested		if (psUseColor) printWriter.println("0 0 0 setrgbcolor");		if (wnd != null && wnd.isGrid())		{			int gridx = (int)wnd.getGridXSpacing();			int gridy = (int)wnd.getGridYSpacing();			int lx = (int)cell.getBounds().getMinX();			int ly = (int)cell.getBounds().getMinY();			int hx = (int)cell.getBounds().getMaxX();			int hy = (int)cell.getBounds().getMaxY();			int gridlx = lx / gridx * gridx;			int gridly = ly / gridy * gridy;			// adjust to ensure that the first point is inside the range			if (gridlx > lx) gridlx -= (gridlx - lx) / gridx * gridx;			if (gridly > ly) gridly -= (gridly - ly) / gridy * gridy;			while (gridlx < lx) gridlx += gridx;			while (gridly < ly) gridly += gridy;			// PostScript: write the grid loop			double matrix00 = matrix.getScaleX();			double matrix01 = matrix.getShearX();			double matrix10 = matrix.getShearY();

⌨️ 快捷键说明

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