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

📄 poly.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Poly.java * * Copyright (c) 2003 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.database.geometry;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.DisplayedText;import com.sun.electric.database.variable.EditWindow0;import com.sun.electric.database.variable.ElectricObject;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.AbstractShapeBuilder;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.tool.Job;import java.awt.Font;import java.awt.font.GlyphVector;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Iterator;/** * Class to define a polygon of points. */public class Poly extends PolyBase {    public static final Poly[] NULL_ARRAY = {};	/** the string (if of type TEXT) */						private String string;	/** the text descriptor (if of type TEXT) */			private TextDescriptor descript;	/** the ElectricObject/Variable (if of type TEXT) */	private DisplayedText dt;	/**	 * The constructor creates a new Poly given an array of points.	 * @param points the array of coordinates.	 */	public Poly(Point2D [] points)	{		super(points);	}	/**	 * The constructor creates a new Poly that describes a rectangle.	 * @param cX the center X coordinate of the rectangle.	 * @param cY the center Y coordinate of the rectangle.	 * @param width the width of the rectangle.	 * @param height the height of the rectangle.	 */	public Poly(double cX, double cY, double width, double height)	{		super(cX, cY, width, height);	}	/**	 * The constructor creates a new Poly that describes a rectangle.	 * @param rect the Rectangle2D of the rectangle.	 */	public Poly(Rectangle2D rect)	{		super(rect);	}	/**	 * Method to return the String associated with this Poly.	 * This only applies to text Polys which display a message.	 * @return the String associated with this Poly.	 */	public String getString() { return string; }	/**	 * Method to set the String associated with this Poly.	 * This only applies to text Polys which display a message.	 * @param string the String associated with this Poly.	 */	public void setString(String string) { this.string = string; }	/**	 * Method to return the Text Descriptor associated with this Poly.	 * This only applies to text Polys which display a message.	 * Only the size, face, italic, bold, and underline fields are relevant.	 * @return the Text Descriptor associated with this Poly.	 */	public TextDescriptor getTextDescriptor() { return descript; }	/**	 * Method to set the Text Descriptor associated with this Poly.	 * This only applies to text Polys which display a message.	 * Only the size, face, italic, bold, and underline fields are relevant.	 * @param descript the Text Descriptor associated with this Poly.	 */	public void setTextDescriptor(TextDescriptor descript) { this.descript = descript; }	/**	 * Method to return the DisplayedText associated with this Poly.	 * This only applies to text Polys which display a message.	 * @return the DisplayedText associated with this Poly.	 */	public DisplayedText getDisplayedText() { return dt; }	/**	 * Method to set the DisplayedText associated with this Poly.	 * This only applies to text Polys which display a message.	 * @param dt the DisplayedText associated with this Poly.	 */	public void setDisplayedText(DisplayedText dt) { this.dt = dt; }	/**	 * Method to transformed the points in this Poly.	 * @param af transformation to apply.	 */	public void transform(AffineTransform af)	{		// Nothing to do		if (af.getType() == AffineTransform.TYPE_IDENTITY) return;		// special case for text		if (getStyle().isText() && descript != null)		{			// for quadrant rotations, rotate the text angle too			if ((af.getType() & AffineTransform.TYPE_QUADRANT_ROTATION) != 0)			{				double m00 = af.getScaleX();				double m01 = af.getShearX();				double m11 = af.getScaleY();				double m10 = af.getShearY();				if (m00 == 0 && m11 == 0)				{					// a 90/270 rotation					if (m01 > m10)					{						// 270-degree rotation				        int ang = descript.getRotation().getAngle();				        TextDescriptor.Rotation r = TextDescriptor.Rotation.getRotation((ang + 270) % 360);						descript = descript.withRotation(r);					} else					{						// 90-degree rotation				        int ang = descript.getRotation().getAngle();				        TextDescriptor.Rotation r = TextDescriptor.Rotation.getRotation((ang + 90) % 360);						descript = descript.withRotation(r);					}				}			}		}		super.transform(af);	}    private static final int [] extendFactor = {0,    11459, 5729, 3819, 2864, 2290, 1908, 1635, 1430, 1271, 1143,    1039,  951,  878,  814,  760,  712,  669,  631,  598,  567,    540,  514,  492,  470,  451,  433,  417,  401,  387,  373,    361,  349,  338,  327,  317,  308,  299,  290,  282,  275,    267,  261,  254,  248,  241,  236,  230,  225,  219,  214,    210,  205,  201,  196,  192,  188,  184,  180,  177,  173,    170,  166,  163,  160,  157,  154,  151,  148,  146,  143,    140,  138,  135,  133,  130,  128,  126,  123,  121,  119,    117,  115,  113,  111,  109,  107,  105,  104,  102,  100};	/**	 * Method to return the amount that an arc end should extend, given its width and extension factor.	 * @param width the width of the arc.	 * @param extend the extension factor (from 0 to 90).	 * @return the extension (from 0 to half of the width).	 */    public static double getExtendFactor(double width, int extend) {        return extend <= 0 || extend >= 90 ? width*0.5 : width * 50 / extendFactor[extend];    }	/**	 * Method to construct a Poly for an arc with a given length, width, angle, endpoint, and extension.	 * @param len the length of the arc.	 * @param wid the width of the arc.	 * @param angle the angle of the arc.	 * @param endH the head end of the arc.	 * @param extendH the head end extension distance of the arc.	 * @param endT the tail end of the arc.	 * @param extendT the tail end extension distance of the arc.	 * @param style the style of the polygon (filled, opened, etc.)	 * @return a Poly describing the outline of the arc.	 */	public static Poly makeEndPointPoly(double len, double wid, int angle, Point2D endH, double extendH,		Point2D endT, double extendT, Poly.Type style)	{		double w2 = wid / 2;		double x1 = endH.getX();   double y1 = endH.getY();		double x2 = endT.getX();   double y2 = endT.getY();		Point2D.Double [] points = null;		// somewhat simpler if rectangle is manhattan		if (angle == 900 || angle == 2700)		{			if (angle == 900)//			if (y1 > y2)			{				double temp = y1;   y1 = y2;   y2 = temp;				temp = extendH;   extendH = extendT;   extendT = temp;			}			points = new Point2D.Double[] {				new Point2D.Double(x1 - w2, y1 - extendH),				new Point2D.Double(x1 + w2, y1 - extendH),				new Point2D.Double(x2 + w2, y2 + extendT),				new Point2D.Double(x2 - w2, y2 + extendT)};		} else if (angle == 0 || angle == 1800)		{			if (angle == 0)//			if (x1 > x2)			{				double temp = x1;   x1 = x2;   x2 = temp;				temp = extendH;   extendH = extendT;   extendT = temp;			}			points = new Point2D.Double[] {				new Point2D.Double(x1 - extendH, y1 - w2),				new Point2D.Double(x1 - extendH, y1 + w2),				new Point2D.Double(x2 + extendT, y2 + w2),				new Point2D.Double(x2 + extendT, y2 - w2)};		} else		{			// nonmanhattan arcs cannot have zero length so re-compute it			if (len == 0) len = endH.distance(endT);			double xextra, yextra, xe1, ye1, xe2, ye2;			if (len == 0)			{				double sa = DBMath.sin(angle);				double ca = DBMath.cos(angle);				xe1 = x1 - ca * extendH;				ye1 = y1 - sa * extendH;				xe2 = x2 + ca * extendT;				ye2 = y2 + sa * extendT;				xextra = ca * w2;				yextra = sa * w2;			} else			{				// work out all the math for nonmanhattan arcs				xe1 = x1 - extendH * (x2-x1) / len;				ye1 = y1 - extendH * (y2-y1) / len;				xe2 = x2 + extendT * (x2-x1) / len;				ye2 = y2 + extendT * (y2-y1) / len;					// now compute the corners				xextra = w2 * (x2-x1) / len;				yextra = w2 * (y2-y1) / len;			}			points = new Point2D.Double[] {				new Point2D.Double(yextra + xe1, ye1 - xextra),				new Point2D.Double(xe1 - yextra, xextra + ye1),				new Point2D.Double(xe2 - yextra, xextra + ye2),				new Point2D.Double(yextra + xe2, ye2 - xextra)};		}		if (wid != 0 && style.isOpened())		{			points = new Point2D.Double[] {points[0], points[1], points[2], points[3], points[0]};		}		Poly poly = new Poly(points);		poly.setStyle(style);		return poly;	}	/**	 * Method to convert text Polys to their precise bounds in a given window.	 * @param wnd the window.	 * @param eObj the ElectricObject on which this text resides.	 * If that ElectricObject is a NodeInst and the node is rotated, it affects the text anchor point.	 * @return true if the text is too small to display.	 */	public boolean setExactTextBounds(EditWindow0 wnd, ElectricObject eObj)	{		if (getString() == null) return true;		String theString = getString().trim();		if (theString.length() == 0) return true;		int numLines = 1;		if (dt != null)		{			Variable var = dt.getVariable();			if (var != null)			{				numLines = var.getLength();				if (numLines > 1)				{					Object [] objList = (Object [])var.getObject();					for(int i=0; i<numLines; i++)					{						// empty line						if (objList[i] == null) continue;						String str = objList[i].toString();						if (str.length() > theString.length()) theString = str;					}				}			}		}		Type style = getStyle();		style = rotateType(style, eObj);		Font font = descript != null ? descript.getFont(wnd, 0) : TextDescriptor.getDefaultFont();		if (font == null)		{			UserInterface ui = Job.getUserInterface();			double size = ui.getDefaultTextSize();			if (descript != null) size = descript.getTrueSize(wnd);			size = size/wnd.getScale();			if (size <= 0) size = 1;			double cX = getBounds2D().getCenterX();			double cY = getBounds2D().getCenterY();			double sizeIndent = size / 4;			double fakeWidth = theString.length() * size * 0.75;			Point2D pt = getTextCorner(style, cX, cY, fakeWidth, size);			cX = pt.getX();   cY = pt.getY();			points = new Point2D.Double[] {				new Point2D.Double(cX, cY+sizeIndent),				new Point2D.Double(cX+fakeWidth, cY+sizeIndent),				new Point2D.Double(cX+fakeWidth, cY+size-sizeIndent),				new Point2D.Double(cX, cY+size-sizeIndent)};			this.bounds = null;			return false;		}		Rectangle2D bounds = getBounds2D();		double lX = bounds.getMinX();		double hX = bounds.getMaxX();		double lY = bounds.getMinY();		double hY = bounds.getMaxY();		GlyphVector gv = TextDescriptor.getGlyphs(theString, font);		Rectangle2D glyphBounds = gv.getVisualBounds();		// adjust to place text in the center		double textScale = getTextScale(wnd, gv, style, lX, hX, lY, hY);		double textWidth = glyphBounds.getWidth();		double textHeight = font.getSize();		double scaledWidth = textWidth * textScale;		double scaledHeight = textHeight * textScale;		double cX = (lX + hX) / 2;		double cY = (lY + hY) / 2;		Point2D corner = getTextCorner(style, cX, cY, scaledWidth, scaledHeight);//System.out.println("STRING '"+theString+"' STYLE="+getStyle().name+" ROTSTYLE="+style.name+" FROM ("+cX+","+cY+") HAS CORNER ("+corner.getX()+","+corner.getY()+")");		cX = corner.getX();		cY = corner.getY();		double width = glyphBounds.getWidth() * textScale;		double height = font.getSize() * textScale * numLines;		switch (descript.getRotation().getIndex())		{			case 1:		// rotate 90 counterclockwise				double saveWidth = width;				width = -height;				height = saveWidth;				break;			case 2:		// rotate 180				width = -width;				height = -height;				break;			case 3:		// rotate 90 clockwise				double saveHeight = height;				height = -width;				width = saveHeight;				break;		}		points = new Point2D.Double[] {			new Point2D.Double(cX, cY),			new Point2D.Double(cX+width, cY),			new Point2D.Double(cX+width, cY+height),			new Point2D.Double(cX, cY+height)};		this.bounds = null;        gv = null;  // for GC and glyphBounds		return false;	}	/**	 * Method to return the coordinates of the lower-left corner of text in a window.	 * @param style the anchor information for the text.	 * @param cX the center X bound of the polygon containing the text.	 * @param cY the center Y bound of the polygon containing the text.	 * @param scaledWidth the width of the polygon containing the text.	 * @param scaledHeight the height of the polygon containing the text.	 * @return the coordinates of the lower-left corner of the text.	 */	private Point2D getTextCorner(Poly.Type style, double cX, double cY, double scaledWidth, double scaledHeight)	{		double offX = 0, offY = 0;		if (style == Type.TEXTCENT || style == Type.TEXTBOX)		{			offX = -scaledWidth/2;			offY = -scaledHeight/2;		} else if (style == Type.TEXTTOP)		{			offX = -scaledWidth/2;			offY = -scaledHeight;		} else if (style == Type.TEXTBOT)		{			offX = -scaledWidth/2;		} else if (style == Type.TEXTLEFT)		{			offY = -scaledHeight/2;		} else if (style == Type.TEXTRIGHT)		{			offX = -scaledWidth;			offY = -scaledHeight/2;		} else if (style == Type.TEXTTOPLEFT)		{			offY = -scaledHeight;		} else if (style == Type.TEXTBOTLEFT)		{

⌨️ 快捷键说明

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