All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.technology.ArcProto Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: ArcProto.java
 *
 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
 *
 * 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.technology;

import com.sun.electric.database.EObjectInputStream;
import com.sun.electric.database.EObjectOutputStream;
import com.sun.electric.database.EditingPreferences;
import com.sun.electric.database.ImmutableArcInst;
import com.sun.electric.database.geometry.EGraphics;
import com.sun.electric.database.geometry.EPoint;
import com.sun.electric.database.geometry.Poly;
import com.sun.electric.database.id.ArcProtoId;
import com.sun.electric.database.id.PrimitiveNodeId;
import com.sun.electric.database.id.PrimitivePortId;
import com.sun.electric.technology.technologies.Generic;
import com.sun.electric.technology.technologies.Schematics;
import com.sun.electric.tool.erc.ERCAntenna;
import com.sun.electric.util.math.DBMath;
import com.sun.electric.util.math.ECoord;

import com.sun.electric.util.math.FixpCoord;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * The ArcProto class defines a type of ArcInst.
 * 

* Every arc in the database appears as one prototypical object and many instantiative objects. * Thus, for a ArcProto such as the CMOS Metal-1 there is one object (called a ArcProto) * that describes the wire prototype and there are many objects (called ArcInsts), * one for every instance of a Metal-1 wire that appears in a circuit. * ArcProtos are statically created and placed in the Technology objects. *

* The basic ArcProto has a name, default width, function, Layers that describes it graphically and more. */ public class ArcProto implements Comparable, Serializable { /** * Function is a typesafe enum class that describes the function of an ArcProto. * Functions are technology-independent and include different types of metal, * polysilicon, and other basic wire types. */ public static enum Function { /** Describes an arc with unknown type. */ UNKNOWN("unknown", 0, 0), /** Describes an arc on Metal layer 1. */ METAL1("metal-1", 1, 0), /** Describes an arc on Metal layer 2. */ METAL2("metal-2", 2, 0), /** Describes an arc on Metal layer 3. */ METAL3("metal-3", 3, 0), /** Describes an arc on Metal layer 4. */ METAL4("metal-4", 4, 0), /** Describes an arc on Metal layer 5. */ METAL5("metal-5", 5, 0), /** Describes an arc on Metal layer 6. */ METAL6("metal-6", 6, 0), /** Describes an arc on Metal layer 7. */ METAL7("metal-7", 7, 0), /** Describes an arc on Metal layer 8. */ METAL8("metal-8", 8, 0), /** Describes an arc on Metal layer 9. */ METAL9("metal-9", 9, 0), /** Describes an arc on Metal layer 10. */ METAL10("metal-10", 10, 0), /** Describes an arc on Metal layer 11. */ METAL11("metal-11", 11, 0), /** Describes an arc on Metal layer 12. */ METAL12("metal-12", 12, 0), /** Describes an arc on Polysilicon layer 1. */ POLY1("polysilicon-1", 0, 1), /** Describes an arc on Polysilicon layer 2. */ POLY2("polysilicon-2", 0, 2), /** Describes an arc on Polysilicon layer 3. */ POLY3("polysilicon-3", 0, 3), /** Describes an arc on the Diffusion layer. */ DIFF("diffusion", 0, 0), /** Describes an arc on the P-Diffusion layer. */ DIFFP("p-diffusion", 0, 0), /** Describes an arc on the N-Diffusion layer. */ DIFFN("n-diffusion", 0, 0), /** Describes an arc on the Substrate-Diffusion layer. */ DIFFS("substrate-diffusion", 0, 0), /** Describes an arc on the Well-Diffusion layer. */ DIFFW("well-diffusion", 0, 0), /** Describes an arc on the Well layer (bias connections). */ WELL("well", 0, 0), /** Describes a bus arc. */ BUS("bus", 0, 0), /** Describes an arc that is unrouted (to be replaced by routers). */ UNROUTED("unrouted", 0, 0), /** Describes an arc that is non-electrical (does not make a circuit connection). */ NONELEC("nonelectrical", 0, 0); private final String printName; private final int level; private final boolean isMetal; private final boolean isPoly; private final boolean isDiffusion; private static final Function[] metalLayers = initMetalLayers(Function.class.getEnumConstants()); private static final Function[] polyLayers = initPolyLayers(Function.class.getEnumConstants()); private Function(String printName, int metalLevel, int polyLevel) { this.printName = printName; isMetal = metalLevel != 0; isPoly = polyLevel != 0; isDiffusion = name().startsWith("DIFF"); level = isMetal ? metalLevel : isPoly ? polyLevel : 0; } /** * Returns a printable version of this ArcProto. * @return a printable version of this ArcProto. */ public String toString() { return printName; } /** * Returns the constant name for this Function. * Constant names are used when writing Java code, so they must be the same as the actual symbol name. * @return the constant name for this Function. */ public String getConstantName() { return name(); } /** * Method to return a List of all ArcProto functions. * @return a List of all ArcProto functions. */ public static List getFunctions() { return Arrays.asList(Function.class.getEnumConstants()); } /** * Method to get the level of this ArcProto.Function. * The level applies to metal and polysilicon functions, and gives the layer number * (i.e. Metal-2 is level 2). * @return the level of this ArcProto.Function. */ public int getLevel() { return level; } /** * Method to find the Function that corresponds to Metal on a given layer. * @param level the layer (starting at 1 for Metal-1). * @return the Function that represents that Metal layer. */ public static Function getMetal(int level) { return level < metalLayers.length ? metalLayers[level] : null; } /** * Method to find the Function that corresponds to Polysilicon on a given layer. * @param level the layer (starting at 1 for Polysilicon-1). * @return the Function that represents that Polysilicon layer. */ public static Function getPoly(int level) { return level < polyLayers.length ? polyLayers[level] : null; } /** * Method to find the Function that corresponds to a contact on a given arc. * @param level the arc (starting at 1 for Contact-1). * @return the Function that represents that Contact arc. */ public static Function getContact(int level) { return metalLayers[level]; } /** * Method to tell whether this ArcProto.Function is metal. * @return true if this ArcProto.Function is metal. */ public boolean isMetal() { return isMetal; } /** * Method to tell whether this ArcProto.Function is polysilicon. * @return true if this ArcProto.Function is polysilicon. */ public boolean isPoly() { return isPoly; } /** * Method to tell whether this ArcProto.Function is diffusion. * @return true if this ArcProto.Function is diffusion. */ public boolean isDiffusion() { return isDiffusion; } private static Function[] initMetalLayers(Function[] allFunctions) { int maxLevel = -1; for (Function fun : getFunctions()) { if (!fun.isMetal()) { continue; } maxLevel = Math.max(maxLevel, fun.level); } Function[] layers = new Function[maxLevel + 1]; for (Function fun : getFunctions()) { if (!fun.isMetal()) { continue; } assert layers[fun.level] == null; layers[fun.level] = fun; } return layers; } private static Function[] initPolyLayers(Function[] allFunctions) { int maxLevel = -1; for (Function fun : getFunctions()) { if (!fun.isPoly()) { continue; } maxLevel = Math.max(maxLevel, fun.level); } Function[] layers = new Function[maxLevel + 1]; for (Function fun : getFunctions()) { if (!fun.isPoly()) { continue; } assert layers[fun.level] == null; layers[fun.level] = fun; } return layers; } } // ----------------------- private data ------------------------------- /** The name of this ArcProto. */ private final ArcProtoId protoId; /** The technology in which this ArcProto resides. */ private final Technology tech; /** The ELIB width offset */ private final double lambdaElibWidthOffset; /** The base extend of this ArcProto in grid units. */ private ECoord baseExtend; /** The minimum extend among ArcLayers. */ private ECoord minLayerExtend; /** The minimum extend among ArcLayers. */ private ECoord maxLayerExtend; /** Flags bits for this ArcProto. */ private int userBits; /** The function of this ArcProto. */ final Function function; /** Layers in this arc */ final Technology.ArcLayer[] layers; /** Pin for this arc */ PrimitiveNode arcPin; /** Index of this ArcProto. */ final int primArcIndex; /** factory default instance */ ImmutableArcInst factoryDefaultInst; /** factory arc angle increment. */ private int factoryAngleIncrement = 90; /** Factory value for arc antenna ratio. */ private double factoryAntennaRatio = Double.NaN; // the meaning of the "userBits" field: // /** these arcs are fixed-length */ private static final int WANTFIX = 01; // /** these arcs are fixed-angle */ private static final int WANTFIXANG = 02; // /** set if arcs should not slide in ports */ private static final int WANTCANTSLIDE = 04; // /** set if ends do not extend by half width */ private static final int WANTNOEXTEND = 010; // /** set if arcs should be negated */ private static final int WANTNEGATED = 020; // /** set if arcs should be directional */ private static final int WANTDIRECTIONAL = 040; /** set if arcs can wipe wipable nodes */ private static final int CANWIPE = 0100; /** set if arcs can curve */ private static final int CANCURVE = 0200; // /** arc function (from efunction.h) */ private static final int AFUNCTION = 017400; // /** right shift for AFUNCTION */ private static final int AFUNCTIONSH = 8; // /** angle increment for this type of arc */ private static final int AANGLEINC = 017760000; // /** right shift for AANGLEINC */ private static final int AANGLEINCSH = 13; /** set if arc is not selectable in palette */ private static final int ARCSPECIAL = 010000000; /** set if arc is selectable by edge, not area */ private static final int AEDGESELECT = 020000000; // /** set if arc is invisible and unselectable */ private static final int AINVISIBLE = 040000000; /** set if arc is not used */ private static final int ANOTUSED = 020000000000; /** set if node will be considered in palette */ private static final int SKIPSIZEINPALETTE = 0400; // ----------------- protected and private methods ------------------------- /** * The constructor is never called. Use "Technology.newArcProto" instead. */ protected ArcProto(Technology tech, String protoName, double lambdaElibWidthOffset, Function function, Technology.ArcLayer[] layers, int primArcIndex) { if (!Technology.jelibSafeName(protoName)) { System.out.println("ArcProto name " + protoName + " is not safe to write into JELIB"); } protoId = tech.getId().newArcProtoId(protoName); this.tech = tech; this.userBits = 0; this.function = function; this.layers = layers.clone(); this.primArcIndex = primArcIndex; this.lambdaElibWidthOffset = lambdaElibWidthOffset; this.baseExtend = layers[0].getExtend(); assert -Integer.MAX_VALUE / 8 < baseExtend.getGrid() && baseExtend.getGrid() < Integer.MAX_VALUE / 8; computeLayerGridExtendRange(); PrimitivePortId ppId = protoId.techId.idManager.newTechId("generic").newPrimitiveNodeId("Universal-Pin").newPortId(""); factoryDefaultInst = ImmutableArcInst.newInstance(0, protoId, ImmutableArcInst.BASENAME, null, 0, ppId, EPoint.ORIGIN, 0, ppId, EPoint.ORIGIN, 0, 0, ImmutableArcInst.FACTORY_DEFAULT_FLAGS); } private void computeLayerGridExtendRange() { ECoord min = ECoord.MAX_ECOORD; ECoord max = ECoord.MIN_ECOORD; for (int i = 0; i < layers.length; i++) { Technology.ArcLayer primLayer = layers[i]; assert indexOf(primLayer.getLayer()) == i; // layers are unique min = min.min(getLayerExtend(i)); max = max.max(getLayerExtend(i)); } assert -Integer.MAX_VALUE / 8 < min.getGrid(); // assert 0 <= min; assert max.getGrid() < Integer.MAX_VALUE / 8 && min.compareTo(max) <= 0; minLayerExtend = min; maxLayerExtend = max; } protected Object writeReplace() { return new ArcProtoKey(this); } private static class ArcProtoKey extends EObjectInputStream.Key { public ArcProtoKey() { } private ArcProtoKey(ArcProto ap) { super(ap); } @Override public void writeExternal(EObjectOutputStream out, ArcProto ap) throws IOException { out.writeObject(ap.getTechnology()); out.writeInt(ap.getId().chronIndex); } @Override public ArcProto readExternal(EObjectInputStream in) throws IOException, ClassNotFoundException { Technology tech = (Technology) in.readObject(); int chronIndex = in.readInt(); ArcProto ap = tech.getArcProtoByChronIndex(chronIndex); if (ap == null) { throw new InvalidObjectException("arc proto not found"); } return ap; } } public static class Curvable extends ArcProto { protected Curvable(Technology tech, String protoName, double lambdaElibWidthOffset, Function function, Technology.ArcLayer[] layers, int primArcIndex) { super(tech, protoName, lambdaElibWidthOffset, function, layers, primArcIndex); setCurvable(); } /** * Tells if arc can be drawn by simplified algorithm * Overidden ins subclasses * @param a arc to test * @param explain if true then print explanation why arc is not easy * @return true if arc can be drawn by simplified algorithm */ @Override public boolean isEasyShape(ImmutableArcInst a, boolean explain) { if (a.getVar(ImmutableArcInst.ARC_RADIUS) != null) { if (explain) { System.out.println("CURVABLE"); } return false; } return super.isEasyShape(a, explain); } /** * Method to fill in an AbstractShapeBuilder a polygon that describes this ImmutableArcInst in grid units. * The polygon is described by its width, and style. * @param a the arc information. * @param gridWidth the gridWidth of the Poly. * @param style the style of the Poly. * @param layer layer of the Poly * @param graphicsOverride graphics override of the Poly */ @Override public void makeGridPoly(AbstractShapeBuilder b, ImmutableArcInst a, long gridWidth, Poly.Type style, Layer layer, EGraphics graphicsOverride) { // get the radius information on the arc Double radiusDouble = a.getRadius(); if (radiusDouble != null && curvedArcGridOutline(b, a, gridWidth, DBMath.lambdaToGrid(radiusDouble))) { b.pushPoly(style, layer, graphicsOverride, null); return; } super.makeGridPoly(b, a, gridWidth, style, layer, graphicsOverride); } /** * when arcs are curved, the number of line segments will be * between this value, and half of this value. */ private static final int MAXARCPIECES = 16; /** * Method to fill polygon "poly" with the outline in grid units of the curved arc in * this ImmutableArcInst whose width in grid units is "gridWidth". * If there is no curvature information in the arc, the routine returns false, * otherwise it returns the curved polygon. * @param a the arc information. * @param gridWidth width in grid units. * @param gridRadius radius in grid units. * @return true if point were filled to the buuilder */ private boolean curvedArcGridOutline(AbstractShapeBuilder b, ImmutableArcInst a, long gridWidth, long gridRadius) { // get information about the curved arc long pureGridRadius = Math.abs(gridRadius); double gridLength = a.getGridLength(); // see if the lambdaRadius can work with these arc ends if (pureGridRadius * 2 < gridLength) { return false; } // determine the center of the circle Point2D[] centers = DBMath.findCenters(pureGridRadius, a.headLocation.gridMutable(), a.tailLocation.gridMutable()); if (centers == null) { return false; } Point2D centerPt = gridRadius >= 0 ? centers[1] : centers[0]; double centerX = centerPt.getX(); double centerY = centerPt.getY(); // determine the base and range of angles int angleBase = DBMath.figureAngle(a.headLocation.getGridX() - centerX, a.headLocation.getGridY() - centerY); int angleRange = DBMath.figureAngle(a.tailLocation.getGridX() - centerX, a.tailLocation.getGridY() - centerY); angleRange -= angleBase; if (angleRange < 0) { angleRange += 3600; } // force the curvature to be the smaller part of a circle (used to determine this by the reverse-ends bit) if (angleRange > 1800) { angleBase += angleRange; if (angleBase < 0) { angleBase += 3600; } angleRange = 3600 - angleRange; } // determine the number of intervals to use for the arc int pieces = angleRange; while (pieces > MAXARCPIECES) { pieces /= 2; } if (pieces == 0) { return false; } // get the inner and outer radii of the arc double outerRadius = pureGridRadius + gridWidth / 2; double innerRadius = outerRadius - gridWidth; // fill the polygon for (int i = 0; i <= pieces; i++) { int angle = (angleBase + i * angleRange / pieces) % 3600; b.pushPoint((DBMath.cos(angle) * innerRadius + centerX) * FixpCoord.FIXP_SCALE, (DBMath.sin(angle) * innerRadius + centerY) * FixpCoord.FIXP_SCALE); } for (int i = pieces; i >= 0; i--) { int angle = (angleBase + i * angleRange / pieces) % 3600; b.pushPoint((DBMath.cos(angle) * outerRadius + centerX) * FixpCoord.FIXP_SCALE, (DBMath.sin(angle) * outerRadius + centerY) * FixpCoord.FIXP_SCALE); } return true; } } // ------------------------ public methods ------------------------------- /** * Method to return the Id of this ArcProto. * @return the Id of this ArcProto. */ public ArcProtoId getId() { return protoId; } /** * Method to return the name of this ArcProto. * @return the name of this ArcProto. */ public String getName() { return protoId.name; } /** * Method to return the full name of this ArcProto. * Full name has format "techName:primName" * @return the full name of this ArcProto. */ public String getFullName() { return protoId.fullName; } /** * Method to return the Technology of this ArcProto. * @return the Technology of this ArcProto. */ public Technology getTechnology() { return tech; } /** * Method to return the default base width of this ArcProto in lambda units. * This is the reported/selected width, which means that it does not include the width offset. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the width of the diffusion. * @return the default base width of this ArcProto in lambda units. * @deprecated Use method with explicit EditingPreferences parameter. */ public double getDefaultLambdaBaseWidth() { return getDefaultLambdaBaseWidth(EditingPreferences.getThreadEditingPreferences()); } /** * Method to return the default base width of this ArcProto in lambda units. * This is the reported/selected width, which means that it does not include the width offset. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the width of the diffusion. * @param ep EditingPreferences * @return the default base width of this ArcProto in lambda units. */ public double getDefaultLambdaBaseWidth(EditingPreferences ep) { return DBMath.gridToLambda(getDefaultGridBaseWidth(ep)); } /** * Method to return the factory default base width of this ArcProto in lambda units. * This is the reported/selected width, which means that it does not include the width offset. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the width of the diffusion. * @return the factory default base width of this ArcProto in lambda units. */ public double getFactoryDefaultLambdaBaseWidth() { return DBMath.gridToLambda(getFactoryDefaultGridBaseWidth()); } /** * Method to return the default base width of this ArcProto in grid units. * This is the reported/selected width, which means that it does not include the width offset. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the width of the diffusion. * @param ep EditingPreferences * @return the default base width of this ArcProto in grid units. */ public long getDefaultGridBaseWidth(EditingPreferences ep) { return 2 * (getDefaultInst(ep).getGridExtendOverMin() + baseExtend.getGrid()); } /** * Method to return the factory default base width of this ArcProto in grid units. * This is the reported/selected width, which means that it does not include the width offset. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the width of the diffusion. * @return the factory default base width of this ArcProto in grid units. */ public long getFactoryDefaultGridBaseWidth() { return 2 * (factoryDefaultInst.getGridExtendOverMin() + baseExtend.getGrid()); } /** * Method to return the default immutable instance of this PrimitiveNode * in specified EditingPreferences. * @param ep specified EditingPreferences * @return the default immutable instance of this PrimitiveNode */ public ImmutableArcInst getDefaultInst(EditingPreferences ep) { ImmutableArcInst defaultInst = ep.getDefaultArc(protoId); return defaultInst != null ? defaultInst : factoryDefaultInst; } /** * Method to return the factory default immutable instance of this PrimitiveNode * @return the factory default immutable instance of this PrimitiveNode */ public ImmutableArcInst getFactoryDefaultInst() { return factoryDefaultInst; } /** * Method to return the base width extend of this ArcProto as ECoord object. * This is the reported/selected width. * For example, diffusion arcs are always accompanied by a surrounding well and select. * This call returns only the half width of the diffusion of minimal-width arc. * @return the default base width extend of this ArcProto as ECoord object. */ public ECoord getBaseExtend() { return baseExtend; } /** * Method to return the width offset of this ArcProto in lambda units. * The width offset excludes the surrounding implang material. * For example, diffusion arcs are always accompanied by a surrounding well and select. * The offset amount is the difference between the diffusion width and the overall width. * @return the width offset of this ArcProto in lambda units. */ public double getLambdaElibWidthOffset() { return lambdaElibWidthOffset; } /** * Method to return the minimal layer extend of this ArcProto as ECoord object. * @return the minimal layer extend of this ArcProto as ECoord object. */ public ECoord getMinLayerExtend() { return minLayerExtend; } /** * Method to return the maximal layer extend of this ArcProto as ECoord object. * @return the maximal layer extend of this ArcProto as ECoord object. */ public ECoord getMaxLayerExtend() { return maxLayerExtend; } /** * Method to set the factory antenna ratio of this ArcProto. * Antenna ratios are used in antenna checks that make sure the ratio of the area of a layer is correct. * @param ratio the antenna ratio of this ArcProto. */ public void setFactoryAntennaRatio(double ratio) { assert Double.isNaN(factoryAntennaRatio); factoryAntennaRatio = ratio; } /** * Method to tell the default antenna ratio of this ArcProto. * Antenna ratios are used in antenna checks that make sure the ratio of the area of a layer is correct. * @return the default antenna ratio of this ArcProto. */ public double getFactoryAntennaRatio() { return factoryAntennaRatio; } /** * Method to set the "factory default" rigid state of this ArcProto. * Rigid arcs cannot change length or the angle of their connection to a NodeInst. * @param rigid true if this ArcProto should be rigid by factory-default. */ public void setFactoryRigid(boolean rigid) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.RIGID, rigid); } /** * Method to set the "factory default" fixed-angle state of this ArcProto. * Fixed-angle arcs cannot change their angle, so if one end moves, * the other may also adjust to keep the arc angle constant. * @param fixed true if this ArcProto should be fixed-angle by factory-default. */ public void setFactoryFixedAngle(boolean fixed) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.FIXED_ANGLE, fixed); } /** * Method to set the "factory default" slidability state of this ArcProto. * Arcs that slide will not move their connected NodeInsts if the arc's end is still within the port area. * Arcs that cannot slide will force their NodeInsts to move by the same amount as the arc. * Rigid arcs cannot slide but nonrigid arcs use this state to make a decision. * @param slidable true if this ArcProto should be slidability by factory-default. */ public void setFactorySlidable(boolean slidable) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.SLIDABLE, slidable); } /** * Method to set the "factory default" end-extension state of this ArcProto. * End-extension causes an arc to extend past its endpoint by half of its width. * Most layout arcs want this so that they make clean connections to orthogonal arcs. * @param extended true if this ArcProto should be end-extended by factory-default. */ public void setFactoryExtended(boolean extended) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.TAIL_EXTENDED, extended). withFlag(ImmutableArcInst.HEAD_EXTENDED, extended); } /** * Method to set the "factory default" directional state of this ArcProto. * Directionality causes arrows to be drawn at the head, tail, or center of the arc. * @param defaultDir has bit 0 set to put arrow on head, bit 1 set to put arrow on tail, * bit 2 set to put arrow on body. */ public void setFactoryDirectional(int defaultDir) { if ((defaultDir & 1) != 0) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.HEAD_ARROWED, true); } if ((defaultDir & 2) != 0) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.TAIL_ARROWED, true); } if ((defaultDir & 4) != 0) { factoryDefaultInst = factoryDefaultInst.withFlag(ImmutableArcInst.BODY_ARROWED, true); } } /** * Method to set this ArcProto so that it is not used. * Unused arcs do not appear in the component menus and cannot be created by the user. * The state is useful for hiding arcs that the user should not use. * @param set */ public void setNotUsed(boolean set) { /* checkChanging();*/ if (set) { userBits |= ANOTUSED; } else { userBits &= ~ANOTUSED; } if (arcPin != null) { arcPin.setNotUsed(set); } } /** * Method to tell if this ArcProto is used. * Unused arcs do not appear in the component menus and cannot be created by the user. * The state is useful for hiding arcs that the user should not use. * @return true if this ArcProto is used. */ public boolean isNotUsed() { return (userBits & ANOTUSED) != 0; } /** * Method to allow instances of this ArcProto not to be considered in * tech palette for the calculation of the largest icon. * Valid for menu display */ public void setSkipSizeInPalette() { userBits |= SKIPSIZEINPALETTE; } /** * Method to tell if instaces of this ArcProto are special (don't appear in menu). * Valid for menu display */ public boolean isSkipSizeInPalette() { return (userBits & SKIPSIZEINPALETTE) != 0; } /** * Method to set this ArcProto so that instances of it can wipe nodes. * For display efficiency reasons, pins that have arcs connected to them should not bother being drawn. * Those arc prototypes that can erase their connecting pins have this state set, * and when instances of these arcs connect to the pins, those pins stop being drawn. * It is necessary for the pin node prototype to enable wiping (with setArcsWipe). * A NodeInst that becomes wiped out has "setWiped" called. */ public void setWipable() { userBits |= CANWIPE; } /** * Method to set this ArcProto so that instances of it cannot wipe nodes. * For display efficiency reasons, pins that have arcs connected to them should not bother being drawn. * Those arc prototypes that can erase their connecting pins have this state set, * and when instances of these arcs connect to the pins, those pins stop being drawn. * It is necessary for the pin node prototype to enable wiping (with setArcsWipe). * A NodeInst that becomes wiped out has "setWiped" called. */ public void clearWipable() { userBits &= ~CANWIPE; } /** * Method to tell if instances of this ArcProto can wipe nodes. * For display efficiency reasons, pins that have arcs connected to them should not bother being drawn. * Those arc prototypes that can erase their connecting pins have this state set, * and when instances of these arcs connect to the pins, those pins stop being drawn. * It is necessary for the pin node prototype to enable wiping (with setArcsWipe). * A NodeInst that becomes wiped out has "setWiped" called. * @return true if instances of this ArcProto can wipe nodes. */ public boolean isWipable() { return (userBits & CANWIPE) != 0; } /** * Method to set this ArcProto so that instances of it can curve. * Since arc curvature is complex to draw, arcs with this capability * must be marked this way. * A curved arc has the variable "arc_radius" on it with a curvature factor. */ void setCurvable() { userBits |= CANCURVE; } /** * Method to set this ArcProto so that instances of it cannot curve. * Since arc curvature is complex to draw, arcs with this capability * must be marked this way. * A curved arc has the variable "arc_radius" on it with a curvature factor. */ private void clearCurvable() { userBits &= ~CANCURVE; } /** * Method to tell if instances of this ArcProto can curve. * Since arc curvature is complex to draw, arcs with this capability * must be marked this way. * A curved arc has the variable "arc_radius" on it with a curvature factor. * @return true if instances of this ArcProto can curve. */ public boolean isCurvable() { return (userBits & CANCURVE) != 0; } /** * Method to set this ArcProto so that instances of it can be selected by their edge. * Artwork primitives that are not filled-in or are outlines want edge-selection, instead * of allowing a click anywhere in the bounding box to work. */ public void setEdgeSelect() { userBits |= AEDGESELECT; } /** * Method to set this ArcProto so that instances of it cannot be selected by their edge. * Artwork primitives that are not filled-in or are outlines want edge-selection, instead * of allowing a click anywhere in the bounding box to work. */ public void clearEdgeSelect() { userBits &= ~AEDGESELECT; } /** * Method to tell if instances of this ArcProto can be selected by their edge. * Artwork primitives that are not filled-in or are outlines want edge-selection, instead * of allowing a click anywhere in the bounding box to work. * @return true if instances of this ArcProto can be selected by their edge. */ public boolean isEdgeSelect() { return (userBits & AEDGESELECT) != 0; } /** * Method to allow instances of this ArcProto to be special in menu. * Valid for menu display */ public void setSpecialArc() { userBits |= ARCSPECIAL; } /** * Method to tell if instaces of this ArcProto are special (don't appear in menu). * Valid for menu display */ public boolean isSpecialArc() { return (userBits & ARCSPECIAL) != 0; } /** * Method to return the function of this ArcProto. * The Function is a technology-independent description of the behavior of this ArcProto. * @return function the function of this ArcProto. */ public ArcProto.Function getFunction() { return function; } /** * Method to set the factory-default angle of this ArcProto. * This is only called from ArcProto during construction. * @param angle the factory-default angle of this ArcProto. */ public void setFactoryAngleIncrement(int angle) { factoryAngleIncrement = angle; } /** * Method to get the angle increment on this ArcProto. * The angle increment is the granularity on placement angle for instances * of this ArcProto. It is in degrees. * For example, a value of 90 requests that instances run at 0, 90, 180, or 270 degrees. * A value of 0 allows arcs to be created at any angle. * @param ep editing preferences with default increment * @return the angle increment on this ArcProto. */ public int getAngleIncrement(EditingPreferences ep) { Integer angleIncrement = ep.getDefaultAngleIncrement(protoId); return angleIncrement != null ? angleIncrement.intValue() : factoryAngleIncrement; } /** * Method to get the default angle increment on this ArcProto. * The angle increment is the granularity on placement angle for instances * of this ArcProto. It is in degrees. * For example, a value of 90 requests that instances run at 0, 90, 180, or 270 degrees. * A value of 0 allows arcs to be created at any angle. * @return the default angle increment on this ArcProto. */ public int getFactoryAngleIncrement() { return factoryAngleIncrement; } /** * Method to find the PrimitiveNode pin corresponding to this ArcProto type. * Users can override the pin to use, and this method returns the user setting. * For example, if this ArcProto is metal-1 then return the Metal-1-pin, * but the user could set it to Metal-1-Metal-2-Contact. * @param ep editing preferences with user overrides * @return the PrimitiveNode pin to use for arc bends. */ public PrimitiveNode findOverridablePinProto(EditingPreferences ep) { // see if there is a default on this arc proto PrimitiveNodeId pinId = ep.getDefaultArcPinId(protoId); if (pinId != null) { PrimitiveNode np = tech.getPrimitiveNode(pinId); if (np != null) { return np; } } return findPinProto(); } /** * Method to find the PrimitiveNode pin corresponding to this ArcProto type. * For example, if this ArcProto is metal-1 then return the Metal-1-pin. * @return the PrimitiveNode pin to use for arc bends. */ public PrimitiveNode findPinProto() { if (arcPin != null) { return arcPin; } // search for an appropriate pin Iterator it = tech.getNodes(); while (it.hasNext()) { PrimitiveNode pn = it.next(); if (pn.isPin()) { if (pn.getNumPorts() > 1) { System.out.println("Missing cases in ArcProto:findPinProto"); } PrimitivePort pp = (PrimitivePort) pn.getPorts().next(); if (pp.connectsTo(this)) { return pn; } } } return null; } // public PrimitiveNode makeWipablePin(String pinName, String portName) { // double defSize = DBMath.round(2*getLambdaBaseExtend() + getLambdaElibWidthOffset()); // return makeWipablePin(pinName, portName, defSize); // } // public PrimitiveNode makeWipablePin(String pinName, String portName, double defSize, ArcProto... extraArcs) { // double elibSize0 = DBMath.round(defSize * 0.5); // double elibSize1 = DBMath.round(elibSize0 - 0.5 * getLambdaElibWidthOffset()); // arcPin = PrimitiveNode.makeArcPin(this, pinName, portName, elibSize0, elibSize1, extraArcs); // arcPin.setNotUsed(isNotUsed()); // return arcPin; // } /** * Method to find the ArcProto with the given name. * This can be prefixed by a Technology name. * @param line the name of the ArcProto. * @return the specified ArcProto, or null if none can be found. */ public static ArcProto findArcProto(String line) { Technology tech = Technology.getCurrent(); int colon = line.indexOf(':'); String withoutPrefix; if (colon == -1) { withoutPrefix = line; } else { String prefix = line.substring(0, colon); Technology t = Technology.findTechnology(prefix); if (t != null) { tech = t; } withoutPrefix = line.substring(colon + 1); } ArcProto ap = tech.findArcProto(withoutPrefix); if (ap != null) { return ap; } return null; } /** * Method to return the number of layers that comprise this ArcProto. * @return the number of layers that comprise this ArcProto. */ public int getNumArcLayers() { return layers.length; } /** * Method to return the list of ArcLayers that comprise this ArcProto.. * @return the list of ArcLayers that comprise this ArcProto. */ public Technology.ArcLayer[] getArcLayers() { return layers; } /** * Method to return layer that comprises by its index in all layers * @param arcLayerIndex layer index * @return specified layer that comprises this ArcProto. */ public Layer getLayer(int arcLayerIndex) { return layers[arcLayerIndex].getLayer(); } /** * Returns the extend of specified layer that comprise this ArcProto over base arc width as ECoord object. * @param arcLayerIndex layer index * @return the extend of specified layer that comprise this ArcProto over base arc width in ECoord object. */ public ECoord getLayerExtend(int arcLayerIndex) { return layers[arcLayerIndex].getExtend(); } /** * Returns the Poly.Style of specified layer that comprise this ArcLayer. * @param arcLayerIndex layer index * @return the Poly.Style of specified layer that comprise this ArcLayer. */ public Poly.Type getLayerStyle(int arcLayerIndex) { return layers[arcLayerIndex].getStyle(); } /** * Returns the extend of specified layer that comprise this ArcProto over base arc width as ECoord object. * @param layer specified Layer * @return the extend of specified layer that comprise this ArcProto over base arc width as ECoord object. * @throws IndexOutOfBoundsException when specified layer diesn't comprise this ArcProto */ public ECoord getLayerExtend(Layer layer) { return getLayerExtend(indexOf(layer)); } /** * Returns the Poly.Style of specified layer that comprise this ArcLayer. * @param layer specified Layer * @return the Poly.Style of specified layer that comprise this ArcLayer. * @throws IndexOutOfBoundsException when specified layer diesn't comprise this ArcProto */ public Poly.Type getLayerStyle(Layer layer) { return getLayerStyle(indexOf(layer)); } /** * Method to return specified layer that comprise this ArcProto. * @param i layer index * @return specified layer that comprise this ArcProto. */ Technology.ArcLayer getArcLayer(int i) { return layers[i]; } // /** // * Method to return the array of layers that comprise this ArcProto. // * @return the array of layers that comprise this ArcProto. // */ // public Iterator getArcLayers() { return ArrayIterator.iterator(layers); } /** * Method to return an iterator over the layers in this ArcProto. * @return an iterator over the layers in this ArcProto. */ public Iterator getLayerIterator() { return new LayerIterator(layers); } /** * Iterator for Layers on this ArcProto */ private static class LayerIterator implements Iterator { Technology.ArcLayer[] array; int pos; public LayerIterator(Technology.ArcLayer[] a) { array = a; pos = 0; } @Override public boolean hasNext() { return pos < array.length; } @Override public Layer next() throws NoSuchElementException { if (pos >= array.length) { throw new NoSuchElementException(); } return array[pos++].getLayer(); } @Override public void remove() throws UnsupportedOperationException, IllegalStateException { throw new UnsupportedOperationException(); } } // /** // * Method to find the ArcLayer on this ArcProto with a given Layer. // * If there are more than 1 with the given Layer, the first is returned. // * @param layer the Layer to find. // * @return the ArcLayer that has this Layer. // */ // public Technology.ArcLayer findArcLayer(Layer layer) // { // for(int j=0; j distance) ? distance : array[0]; array[1] = (array[1] < z) ? z : array[1]; } } /** * Tells if arc can be drawn by simplified algorithm * Overidden ins subclasses * @param a arc to test * @param explain if true then print explanation why arc is not easy * @return true if arc can be drawn by simplified algorithm */ public boolean isEasyShape(ImmutableArcInst a, boolean explain) { assert a.protoId == getId(); if (a.isBodyArrowed() || a.isTailArrowed() || a.isHeadArrowed()) { if (explain) { System.out.println("ARROWED"); } return false; } if (a.isTailNegated() || a.isHeadNegated()) { if (explain) { System.out.println("NEGATED"); } return false; } long minLayerExtend = a.getFixpExtendOverMin() + getMinLayerExtend().getFixp(); if (minLayerExtend <= 0) { if (minLayerExtend != 0 || getNumArcLayers() != 1) { if (explain) { System.out.println(this + " many zero-width layers"); } return false; } return true; } for (int i = 0, numArcLayers = getNumArcLayers(); i < numArcLayers; i++) { if (getLayerStyle(i) != Poly.Type.FILLED) { if (explain) { System.out.println("Wide should be filled"); } return false; } } if (!a.isManhattan()) { if (explain) { System.out.println("NON-MANHATTAN"); } return false; } return true; } /** * Fill the polygons that describe arc "a". * @param b AbstractShapeBuilder to fill polygons. * @param a the ImmutableArcInst that is being described. */ protected void getShapeOfArc(AbstractShapeBuilder b, ImmutableArcInst a) { getShapeOfArc(b, a, null); } /** * Fill the polygons that describe arc "a". * @param b AbstractShapeBuilder to fill polygons. * @param a the ImmutableArcInst that is being described. * @param graphicsOverride the graphics to use for all generated polygons (if not null). */ protected void getShapeOfArc(AbstractShapeBuilder b, ImmutableArcInst a, EGraphics graphicsOverride) { // get information about the arc assert a.protoId == getId(); int numArcLayers = getNumArcLayers(); // construct the polygons that describe the basic arc if (!tech.isNoNegatedArcs() && (a.isHeadNegated() || a.isTailNegated())) { for (int i = 0; i < numArcLayers; i++) { Technology.ArcLayer primLayer = getArcLayer(i); Layer layer = primLayer.getLayer(); // remove a gap for the negating bubble int angle = a.getDefinedAngle(); double fixpBubbleSize = Schematics.tech().getNegatingBubbleSize() * (FixpCoord.GRIDS_IN_LAMBDA * FixpCoord.FIXP_SCALE); double cosDist = DBMath.cos(angle) * fixpBubbleSize; double sinDist = DBMath.sin(angle) * fixpBubbleSize; if (!b.skipLayer(layer)) { if (a.isTailNegated()) { b.pushPoint(a.tailLocation, cosDist, sinDist); } else { b.pushPoint(a.tailLocation); } if (a.isHeadNegated()) { b.pushPoint(a.headLocation, -cosDist, -sinDist); } else { b.pushPoint(a.headLocation); } b.pushPoly(Poly.Type.OPENED, layer, graphicsOverride, null); } Layer node_lay = Schematics.tech().node_lay; if (!b.skipLayer(node_lay)) { if (a.isTailNegated()) { b.pushPoint(a.tailLocation, 0.5 * cosDist, 0.5 * sinDist); b.pushPoint(a.tailLocation); b.pushPoly(Poly.Type.CIRCLE, node_lay, null, null); } if (a.isHeadNegated()) { b.pushPoint(a.headLocation, -0.5 * cosDist, -0.5 * sinDist); b.pushPoint(a.headLocation); b.pushPoly(Poly.Type.CIRCLE, node_lay, null, null); } } } } else { for (int i = 0; i < numArcLayers; i++) { Technology.ArcLayer primLayer = getArcLayer(i); Layer layer = primLayer.getLayer(); if (b.skipLayer(layer)) { continue; } makeGridPoly(b, a, 2 * (a.getGridExtendOverMin() + getLayerExtend(i).getGrid()), primLayer.getStyle(), layer, graphicsOverride); } } // add an arrow to the arc description if (!tech.isNoDirectionalArcs() && !b.skipLayer(tech.generic.glyphLay)) { final double fixpArrowSize = 1.0 * (FixpCoord.GRIDS_IN_LAMBDA * FixpCoord.FIXP_SCALE); Generic generic = tech.generic; int angle = a.getDefinedAngle(); if (a.isBodyArrowed()) { b.pushPoint(a.headLocation); b.pushPoint(a.tailLocation); b.pushPoly(Poly.Type.VECTORS, generic.glyphLay, null, null); } if (a.isTailArrowed()) { int angleOfArrow = 3300; // -30 degrees int backAngle1 = angle - angleOfArrow; int backAngle2 = angle + angleOfArrow; b.pushPoint(a.tailLocation); b.pushPoint(a.tailLocation, DBMath.cos(backAngle1) * fixpArrowSize, DBMath.sin(backAngle1) * fixpArrowSize); b.pushPoint(a.tailLocation); b.pushPoint(a.tailLocation, DBMath.cos(backAngle2) * fixpArrowSize, DBMath.sin(backAngle2) * fixpArrowSize); b.pushPoly(Poly.Type.VECTORS, generic.glyphLay, null, null); } if (a.isHeadArrowed()) { angle = (angle + 1800) % 3600; int angleOfArrow = 300; // 30 degrees int backAngle1 = angle - angleOfArrow; int backAngle2 = angle + angleOfArrow; b.pushPoint(a.headLocation); b.pushPoint(a.headLocation, DBMath.cos(backAngle1) * fixpArrowSize, DBMath.sin(backAngle1) * fixpArrowSize); b.pushPoint(a.headLocation); b.pushPoint(a.headLocation, DBMath.cos(backAngle2) * fixpArrowSize, DBMath.sin(backAngle2) * fixpArrowSize); b.pushPoly(Poly.Type.VECTORS, generic.glyphLay, graphicsOverride, null); } } } /** * Method to fill in an AbstractShapeBuilder a polygon that describes this ImmutableArcInst in grid units. * The polygon is described by its width, and style. * @param a the arc information. * @param gridWidth the gridWidth of the Poly. * @param style the style of the Poly. * @param layer layer of the Poly * @param graphicsOverride graphics override of the Poly */ public void makeGridPoly(AbstractShapeBuilder b, ImmutableArcInst a, long gridWidth, Poly.Type style, Layer layer, EGraphics graphicsOverride) { b.makeGridPoly(a, gridWidth, style, layer, graphicsOverride); } /** * Returns the polygons that describe dummy arc of this ArcProto * with default width and specified length. * @param lambdaLength length of dummy arc in lambda units. * @return an array of Poly objects that describes dummy arc graphically. * @deprecated Use method with explicit EditingPreferences parameter. */ public Poly[] getShapeOfDummyArc(double lambdaLength) { return getShapeOfDummyArc(EditingPreferences.getThreadEditingPreferences(), lambdaLength); } /** * Returns the polygons that describe dummy arc of this ArcProto * with default width and specified length. * @param ep EditingPreferences with default width * @param lambdaLength length of dummy arc in lambda units. * @return an array of Poly objects that describes dummy arc graphically. */ public Poly[] getShapeOfDummyArc(EditingPreferences ep, double lambdaLength) { long l2 = DBMath.lambdaToGrid(lambdaLength / 2); // see how many polygons describe this arc Poly[] polys = new Poly[layers.length]; // Point2D.Double headLocation = new Point2D.Double(lambdaLength/2, 0); // Point2D.Double tailLocation = new Point2D.Double(-lambdaLength/2, 0); long defaultGridExtendOverMin = getDefaultInst(ep).getGridExtendOverMin(); for (int i = 0; i < layers.length; i++) { long gridWidth = 2 * (defaultGridExtendOverMin + getLayerExtend(i).getGrid()); // long gridWidth = getDefaultGridFullWidth() - primLayer.getGridOffset(); Poly.Type style = getLayerStyle(i); Poly.Point[] points; if (gridWidth == 0) { points = new Poly.Point[]{Poly.fromGrid(-l2, 0), Poly.fromGrid(l2, 0)}; if (style == Poly.Type.FILLED) { style = Poly.Type.OPENED; } } else { long w2 = gridWidth / 2; assert w2 > 0; points = new Poly.Point[]{ Poly.fromGrid(-l2 - w2, w2), Poly.fromGrid(-l2 - w2, -w2), Poly.fromGrid(l2 + w2, -w2), Poly.fromGrid(l2 + w2, w2)}; if (style.isOpened()) { points = new Poly.Point[]{points[0], points[1], points[2], points[3], (Poly.Point) points[0].clone()}; } } Poly poly = new Poly(points); // poly.gridToLambda(); poly.setStyle(style); poly.setLayer(getLayer(i)); polys[i] = poly; } return polys; } /** * Method to describe this ArcProto as a string. * Prepends the Technology name if it is * not from the current technology (for example, "mocmos:Polysilicon-1"). * @return a String describing this ArcProto. */ public String describe() { String description = ""; Technology tech = getTechnology(); if (Technology.getCurrent() != tech) { description += tech.getTechName() + ":"; } description += getName(); return description; } /** * Compares ArcProtos by their Technologies and definition order. * @param that the other ArcProto. * @return a comparison between the ArcProto. */ @Override public int compareTo(ArcProto that) { if (this.tech != that.tech) { int cmp = this.tech.compareTo(that.tech); if (cmp != 0) { return cmp; } } return this.primArcIndex - that.primArcIndex; } /** * Method to finish initialization of this ArcProto. */ void finish() { if (Double.isNaN(factoryAntennaRatio)) { double ratio = ERCAntenna.DEFPOLYRATIO; if (function.isMetal()) { ratio = ERCAntenna.DEFMETALRATIO; } setFactoryAntennaRatio(ratio); } // assert !factoryDefaultInst.isTailArrowed() && !factoryDefaultInst.isHeadArrowed() && !factoryDefaultInst.isBodyArrowed(); assert factoryDefaultInst.isTailExtended() == factoryDefaultInst.isHeadExtended(); assert !factoryDefaultInst.isTailNegated() && !factoryDefaultInst.isHeadNegated(); assert !factoryDefaultInst.isHardSelect(); } /** * Returns a printable version of this ArcProto. * @return a printable version of this ArcProto. */ @Override public String toString() { return "arc " + describe(); } void dump(PrintWriter out) { out.println("ArcProto " + getName() + " " + getFunction()); out.println("\tisWipable=" + isWipable()); out.println("\tisCurvable=" + isCurvable()); out.println("\tisSpecialArc=" + isSpecialArc()); out.println("\tisEdgeSelect=" + isEdgeSelect()); out.println("\tisNotUsed=" + isNotUsed()); out.println("\tisSkipSizeInPalette=" + isSkipSizeInPalette()); Technology.printlnPref(out, 1, "DefaultExtendFor" + getName() + "IN" + tech.getTechName(), new Double(factoryDefaultInst.getLambdaExtendOverMin())); out.println("\tbaseExtend=" + getBaseExtend()); out.println("\tdefaultLambdaBaseWidth=" + getFactoryDefaultLambdaBaseWidth()); out.println("\tdiskOffset1=" + DBMath.round(getBaseExtend().getLambda() + 0.5 * getLambdaElibWidthOffset())); out.println("\tdiskOffset2=" + getBaseExtend()); Technology.printlnPref(out, 1, "DefaultAngleFor" + getName() + "IN" + tech.getTechName(), new Integer(factoryAngleIncrement)); Technology.printlnPref(out, 1, "DefaultRigidFor" + getName() + "IN" + tech.getTechName(), Boolean.valueOf(factoryDefaultInst.isRigid())); Technology.printlnPref(out, 1, "DefaultFixedAngleFor" + getName() + "IN" + tech.getTechName(), Boolean.valueOf(factoryDefaultInst.isFixedAngle())); Technology.printlnPref(out, 1, "DefaultExtendedFor" + getName() + "IN" + tech.getTechName(), Boolean.valueOf(factoryDefaultInst.isTailExtended())); Technology.printlnPref(out, 1, "DefaultDirectionalFor" + getName() + "IN" + tech.getTechName(), Boolean.valueOf(factoryDefaultInst.isHeadArrowed())); for (Technology.ArcLayer arcLayer : layers) { arcLayer.dump(out); } } Xml.ArcProto makeXml() { Xml.ArcProto a = new Xml.ArcProto(); a.name = getName(); for (Map.Entry e : tech.getOldArcNames().entrySet()) { if (e.getValue() != this) { continue; } assert a.oldName == null; a.oldName = e.getKey(); } a.function = getFunction(); a.wipable = isWipable(); a.curvable = isCurvable(); a.special = isSpecialArc(); a.notUsed = isNotUsed(); a.skipSizeInPalette = isSkipSizeInPalette(); double correction2 = getBaseExtend().getLambda(); double correction1 = DBMath.round(correction2 + 0.5 * getLambdaElibWidthOffset()); if (correction1 != correction2) { a.diskOffset.put(Integer.valueOf(1), new Double(correction1)); } if (correction2 != 0) { a.diskOffset.put(Integer.valueOf(2), new Double(correction2)); } a.extended = factoryDefaultInst.isTailExtended(); a.fixedAngle = factoryDefaultInst.isFixedAngle(); a.angleIncrement = getFactoryAngleIncrement(); a.antennaRatio = getFactoryAntennaRatio(); for (Technology.ArcLayer arcLayer : layers) { a.arcLayers.add(arcLayer.makeXml()); } // if (arcPin != null) { // a.arcPin = new Xml.ArcPin(); // a.arcPin.name = arcPin.getName(); // PrimitivePort port = arcPin.getPort(0); // a.arcPin.portName = port.getName(); // a.arcPin.elibSize = 2*arcPin.getSizeCorrector(0).getX(); // for (ArcProto cap: port.getConnections()) { // if (cap.getTechnology() == tech && cap != this) // a.arcPin.portArcs.add(cap.getName()); // } // // } return a; } /** * Method to check invariants in this ArcProto. * @exception AssertionError if invariants are not valid */ void check() { assert protoId.techId == tech.getId(); for (Technology.ArcLayer primLayer : layers) { ECoord extend = getLayerExtend(primLayer.getLayer()); assert minLayerExtend.compareTo(extend) <= 0 && extend.compareTo(maxLayerExtend) <= 0; } assert lambdaElibWidthOffset >= 0; assert baseExtend.signum() >= 0 && baseExtend.compareTo(maxLayerExtend) <= 0; assert baseExtend == getLayerExtend(0); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy