📄 poly.java
字号:
} else if (style == Type.TEXTTOPRIGHT) { offX = -scaledWidth; offY = -scaledHeight; } else if (style == Type.TEXTBOTRIGHT) { offX = -scaledWidth;// } if (style == Poly.Type.TEXTBOX)// {// offX = -(textWidth * textScale) / 2;// offY = -(textHeight * textScale) / 2; } int rotation = getTextDescriptor().getRotation().getIndex(); if (rotation != 0) { double saveOffX = offX; switch (rotation) { case 1: offX = -offY; offY = saveOffX; break; case 2: offX = -offX; offY = -offY; break; case 3: offX = offY; offY = -saveOffX; break; } } return new Point2D.Double(cX+offX, cY+offY); } /** * Returns new instance of Poly builder to build shapes in lambda units. * @return new instance of Poly builder. */ public static Builder newLambdaBuilder() { return new Builder(true); } /** * Returns new instance of Poly builder to build shapes in grid units. * @return new instance of Poly builder. */ public static Builder newGridBuilder() { return new Builder(false); } /** * Returns thread local instance of Poly builder to build shapes in lambda units. * @return thread local instance of Poly builder. */ public static Builder threadLocalLambdaBuilder() { return threadLocalLambdaBuilder.get(); } private static ThreadLocal<Poly.Builder> threadLocalLambdaBuilder = new ThreadLocal<Poly.Builder>() { protected Poly.Builder initialValue() { return Poly.newLambdaBuilder(); } }; /** * This class builds shapes of nodes and arcs in lambda units as Poly arrays. */ public static class Builder extends AbstractShapeBuilder { private final boolean inLambda; private boolean isChanging; private final ArrayList<Poly> lastPolys = new ArrayList<Poly>(); private Builder(boolean inLambda) { this.inLambda = inLambda; } /** * Returns the polygons that describe node "ni". * @param ni the NodeInst that is being described. * The prototype of this NodeInst must be a PrimitiveNode and not a Cell. * @return an iterator on Poly objects that describes this NodeInst graphically. */ public Iterator<Poly> getShape(NodeInst ni) { Poly[] polys = ((PrimitiveNode)ni.getProto()).getTechnology().getShapeOfNode(ni, electrical, reasonable, onlyTheseLayers); lastPolys.clear(); for (Poly poly: polys) { if (!inLambda) poly.lambdaToGrid(); lastPolys.add(poly); } return lastPolys.iterator(); } /** * Returns the polygons that describe arc "ai". * @param ai the ArcInst that is being described. * @return an iterator on Poly objects that describes this ArcInst graphically. */ public Iterator<Poly> getShape(ArcInst ai) { isChanging = true; setup(ai.getParent()); lastPolys.clear(); genShapeOfArc(ai.getD()); if (inLambda) { for (int i = 0; i < lastPolys.size(); i++) lastPolys.get(i).gridToLambda(); } isChanging = false; return lastPolys.iterator(); } /** * Returns the polygons that describe arc "ai". * @param ai the ArcInst that is being described. * @return an array of Poly objects that describes this ArcInst graphically. */ public Poly [] getShapeArray(ArcInst ai) { isChanging = true; setup(ai.getParent()); lastPolys.clear(); genShapeOfArc(ai.getD()); if (lastPolys.isEmpty()) { isChanging = false; return Poly.NULL_ARRAY; } Poly[] polys = new Poly[lastPolys.size()]; if (inLambda) { for (int i = 0; i < polys.length; i++) { Poly poly = lastPolys.get(i); poly.gridToLambda(); polys[i] = poly; } } else { for (int i = 0; i < polys.length; i++) polys[i] = lastPolys.get(i); } isChanging = false; return polys; } /** * Method to create a Poly object that describes an ImmutableArcInst. * The ImmutableArcInst is described by its width and style. * @param a an ImmutableArcInst * @param gridWidth the width of the Poly in grid units. * @param style the style of the ArcInst. * @return a Poly that describes the ArcInst. */ public Poly makePoly(ImmutableArcInst a, long gridWidth, Poly.Type style) { isChanging = true; lastPolys.clear(); makeGridPoly(a, gridWidth, style, null); isChanging = false; if (lastPolys.isEmpty()) return null; Poly poly = lastPolys.get(0); if (inLambda) poly.gridToLambda(); return poly; } @Override public void addDoublePoly(int numPoints, Poly.Type style, Layer layer) { assert isChanging; Point2D.Double[] points = new Point2D.Double[numPoints]; for (int i = 0; i < numPoints; i++) points[i] = new Point2D.Double(doubleCoords[i*2], doubleCoords[i*2+1]); Poly poly = new Poly(points); poly.setStyle(style); poly.setLayer(layer); lastPolys.add(poly); } @Override public void addIntLine(int[] coords, Poly.Type style, Layer layer) { assert isChanging; Poly poly = new Poly(new Point2D.Double[] { new Point2D.Double(coords[0], coords[1]), new Point2D.Double(coords[2], coords[3]) }); poly.setStyle(style); poly.setLayer(layer); lastPolys.add(poly); } @Override public void addIntBox(int[] coords, Layer layer) { assert isChanging; Poly poly = new Poly(new Point2D.Double[] { new Point2D.Double(coords[0], coords[1]), new Point2D.Double(coords[2], coords[1]), new Point2D.Double(coords[2], coords[3]), new Point2D.Double(coords[0], coords[3]) }); poly.setStyle(Poly.Type.FILLED); poly.setLayer(layer); lastPolys.add(poly); } } /** * Type is a typesafe enum class that describes the nature of a Poly. */ public static enum Type { // ************************ polygons ************************ /** * Describes a closed polygon which is filled in. */ FILLED("filled", false), /** * Describes a closed polygon with only the outline drawn. */ CLOSED("closed", false), /** * Describes a closed rectangle with the outline drawn and an "X" drawn through it. */ CROSSED("crossed", false), // ************************ lines ************************ /** * Describes an open outline. * The last point is not implicitly connected to the first point. */ OPENED("opened", false), /** * Describes an open outline, drawn with a dotted texture. * The last point is not implicitly connected to the first point. */ OPENEDT1("opened-dotted", false), /** * Describes an open outline, drawn with a dashed texture. * The last point is not implicitly connected to the first point. */ OPENEDT2("opened-dashed", false), /** * Describes an open outline, drawn with thicker lines. * The last point is not implicitly connected to the first point. */ OPENEDT3("opened-thick", false), /** * Describes a vector endpoint pairs, solid. * There must be an even number of points in the Poly so that vectors can be drawn from point 0 to 1, * then from point 2 to 3, etc. */ VECTORS("vectors", false), // ************************ curves ************************ /** * Describes a circle (only the outline is drawn). * The first point is the center of the circle and the second point is on the edge, thus defining the radius. * This second point should be on the same horizontal level as the radius point to make radius computation easier. */ CIRCLE("circle", false), /** * Describes a circle, drawn with thick lines (only the outline is drawn). * The first point is the center of the circle and the second point is on the edge, thus defining the radius. * This second point should be on the same horizontal level as the radius point to make radius computation easier. */ THICKCIRCLE("thick-circle", false), /** * Describes a filled circle. * The first point is the center of the circle and the second point is on the edge, thus defining the radius. * This second point should be on the same horizontal level as the radius point to make radius computation easier. */ DISC("disc", false), /** * Describes an arc of a circle. * The first point is the center of the circle, the second point is the start of the arc, and * the third point is the end of the arc. * The arc will be drawn counter-clockwise from the start point to the end point. */ CIRCLEARC("circle-arc", false), /** * Describes an arc of a circle, drawn with thick lines. * The first point is the center of the circle, the second point is the start of the arc, and * the third point is the end of the arc. * The arc will be drawn counter-clockwise from the start point to the end point. */ THICKCIRCLEARC("thick-circle-arc", false), // ************************ text ************************ /** * Describes text that should be centered about the Poly point. * Only one point need be specified. */ TEXTCENT("text-center", true), /** * Describes text that should be placed so that the Poly point is at the top-center. * Only one point need be specified, and the text will be below that point. */ TEXTTOP("text-top", true), /** * Describes text that should be placed so that the Poly point is at the bottom-center. * Only one point need be specified, and the text will be above that point. */ TEXTBOT("text-bottom", true), /** * Describes text that should be placed so that the Poly point is at the left-center. * Only one point need be specified, and the text will be to the right of that point. */ TEXTLEFT("text-left", true), /** * Describes text that should be placed so that the Poly point is at the right-center. * Only one point need be specified, and the text will be to the left of that point. */ TEXTRIGHT("text-right", true), /** * Describes text that should be placed so that the Poly point is at the upper-left. * Only one point need be specified, and the text will be to the lower-right of that point. */ TEXTTOPLEFT("text-topleft", true), /** * Describes text that should be placed so that the Poly point is at the lower-left. * Only one point need be specified, and the text will be to the upper-right of that point. * This is the normal starting point for most text. */ TEXTBOTLEFT("text-botleft", true), /** * Describes text that should be placed so that the Poly point is at the upper-right. * Only one point need be specified, and the text will be to the lower-left of that point. */ TEXTTOPRIGHT("text-topright", true), /** * Describes text that should be placed so that the Poly point is at the lower-right. * Only one point need be specified, and the text will be to the upper-left of that point. */ TEXTBOTRIGHT("text-botright", true), /** * Describes text that is centered in the Poly and must remain inside. * If the letters do not fit, a smaller font will be used, and if that still does not work, * any letters that cannot fit are not written. * The Poly coordinates must define an area for the text to live in. */ TEXTBOX("text-box", true), // ************************ miscellaneous ************************ /** * Describes a small cross, drawn at the specified location. * Typically there will be only one point in this polygon * but if there are more they are averaged and the cross is drawn in the center. */ CROSS("cross", false), /** * Describes a big cross, drawn at the specified location. * Typically there will be only one point in this polygon * but if there are more they are averaged and the cross is drawn in the center. */ BIGCROSS("big-cross", false); private final String name; private final boolean isText; private Type(String name, boolean isText) { this.name = name; this.isText = isText; } /** * Method to tell whether this Poly Style is text. * @return true if this Poly Style is text. */ public boolean isText() { return isText; } /** * Returns a printable version of this Type. * @return a printable version of this Type. */ public String toString() { return "Poly.Type "+name; } /** * Method to tell whether this is a style that can draw an opened polygon. * @return true if this is a style that can draw an opened polygon. */ public boolean isOpened() { if (this == OPENED || this == OPENEDT1 || this == OPENEDT2 || this == OPENEDT3 || this == VECTORS) return true; return false; } /** * Method to get the "angle" of a style of text. * When rotating a node, the anchor point also rotates. * To to this elegantly, the Type is converted to an angle, rotated, and then converted back to a Type. * @return the angle of this text Type. */ public int getTextAngle() { if (this == TEXTLEFT) return 0; if (this == TEXTBOTLEFT) return 450; if (this == TEXTBOT) return 900; if (this == TEXTBOTRIGHT) return 1350; if (this == TEXTRIGHT) return 1800; if (this == TEXTTOPRIGHT) return 2250; if (this == TEXTTOP) return 2700; if (this == TEXTTOPLEFT) return 3150; return 0; } /** * Method to get a text Type from an angle. * When rotating a node, the anchor point also rotates. * To to this elegantly, the Type is converted to an angle, rotated, and then converted back to a Type. * @param angle of the text anchor. * @return a text Type that corresponds to the angle. */ public static Type getTextTypeFromAngle(int angle) { switch (angle) { case 0: return TEXTLEFT; case 450: return TEXTBOTLEFT; case 900: return TEXTBOT; case 1350: return TEXTBOTRIGHT; case 1800: return TEXTRIGHT; case 2250: return TEXTTOPRIGHT; case 2700: return TEXTTOP; case 3150: return TEXTTOPLEFT; } return TEXTCENT; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -