/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ArcInfo.java * Technology Editor, arc information * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2005 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.user.tecEdit; import com.sun.electric.database.geometry.Poly; import com.sun.electric.database.hierarchy.Cell; import com.sun.electric.database.hierarchy.Library; import com.sun.electric.technology.ArcProto; import com.sun.electric.database.text.TextUtils; import com.sun.electric.database.topology.NodeInst; import com.sun.electric.database.variable.Variable; import com.sun.electric.technology.technologies.Generic; import java.awt.geom.Rectangle2D; import java.util.Iterator; import java.util.List; /** * This class defines information about arcs in the Technology Editor. */ public class ArcInfo extends Info { static class LayerDetails { LayerInfo layer; double width; Poly.Type style; } /** the name of the arc */ String name; /** the name of the arc in Java code */ String javaName; /** the arc Function */ ArcProto.Function func; /** true for fixed-angle arcs */ boolean fixAng; /** true if arcs wipe pins */ boolean wipes; /** true if arcs don't extend endpoints */ boolean noExtend; /** true if arc is curvable */ boolean curvable; /** true if arc is special */ boolean special; /** true if arc not used */ boolean notUsed; /** true if arc size doesn't grow palette */boolean skipSizeInPalette; /** true if arc is slidable */ boolean slidable; /** the arc angle increment */ int angInc; /** the maximum antenna ratio */ double antennaRatio; /** the width offset to the highlight */ double widthOffset; /** the ArcProto in the Technology */ ArcProto generated; /** layers in the arc */ LayerDetails [] arcDetails; private static SpecialTextDescr [] arcTextTable = { new SpecialTextDescr(0, 21, ARCFUNCTION), new SpecialTextDescr(0, 18, ARCFIXANG), new SpecialTextDescr(0, 15, ARCWIPESPINS), new SpecialTextDescr(0, 12, ARCNOEXTEND), new SpecialTextDescr(0, 9, ARCINC), new SpecialTextDescr(0, 6, ARCANTENNARATIO), new SpecialTextDescr(0, 3, ARCWIDTHOFFSET), }; ArcInfo() { func = ArcProto.Function.UNKNOWN; } /** * Method to return an array of cells that comprise the arcs in a technology library. * @param lib the technology library. * @return an array of cells for each arc (in the proper order). */ public static Cell [] getArcCells(Library lib) { Library [] oneLib = new Library[1]; oneLib[0] = lib; return findCellSequence(oneLib, "arc-", ARCSEQUENCE_KEY); } /** * Method to build the appropriate descriptive information for an arc into * cell "np". The function is in "func"; the arc is fixed-angle if "fixang" * is nonzero; the arc wipes pins if "wipes" is nonzero; and the arc does * not extend its ends if "noextend" is nonzero. The angle increment is * in "anginc". */ void generate(Cell np) { // load up the structure with the current values loadTableEntry(arcTextTable, ARCFUNCTION, func); loadTableEntry(arcTextTable, ARCFIXANG, Boolean.valueOf(fixAng)); loadTableEntry(arcTextTable, ARCWIPESPINS, Boolean.valueOf(wipes)); loadTableEntry(arcTextTable, ARCNOEXTEND, Boolean.valueOf(noExtend)); loadTableEntry(arcTextTable, ARCINC, new Integer(angInc)); loadTableEntry(arcTextTable, ARCANTENNARATIO, new Double(antennaRatio)); loadTableEntry(arcTextTable, ARCWIDTHOFFSET, new Double(widthOffset)); // now create those text objects createSpecialText(np, arcTextTable); } /** * Method to parse the arc cell in "np" and return an ArcInfo object that describes it. */ static ArcInfo parseCell(Cell np) { // create and initialize the GRAPHICS structure ArcInfo aIn = new ArcInfo(); aIn.name = np.getName().substring(4); // look at all nodes in the arc description cell for(Iterator<NodeInst> it = np.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); Variable var = ni.getVar(OPTION_KEY); if (var == null) continue; String str = getValueOnNode(ni); switch (((Integer)var.getObject()).intValue()) { case ARCFUNCTION: aIn.func = ArcProto.Function.UNKNOWN; List<ArcProto.Function> allFuncs = ArcProto.Function.getFunctions(); for(ArcProto.Function fun : allFuncs) { if (fun.toString().equalsIgnoreCase(str)) { aIn.func = fun; break; } } break; case ARCINC: aIn.angInc = TextUtils.atoi(str); break; case ARCFIXANG: aIn.fixAng = str.equalsIgnoreCase("yes"); break; case ARCWIPESPINS: aIn.wipes = str.equalsIgnoreCase("yes"); break; case ARCNOEXTEND: aIn.noExtend = str.equalsIgnoreCase("no"); break; case ARCANTENNARATIO: aIn.antennaRatio = TextUtils.atof(str); break; case ARCWIDTHOFFSET: aIn.widthOffset = TextUtils.atof(str); break; } } return aIn; } /** * Method to compact an Arc technology-edit cell */ static void compactCell(Cell cell) { // compute bounds of arc contents Rectangle2D nonSpecBounds = null; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) continue; // ignore the special text nodes boolean special = false; for(int i=0; i<arcTextTable.length; i++) if (arcTextTable[i].ni == ni) special = true; if (special) continue; // compute overall bounds Rectangle2D bounds = ni.getBounds(); if (nonSpecBounds == null) nonSpecBounds = bounds; else Rectangle2D.union(nonSpecBounds, bounds, nonSpecBounds); } // now rearrange the geometry if (nonSpecBounds != null) { double xOff = -nonSpecBounds.getCenterX(); double yOff = -nonSpecBounds.getMaxY(); if (xOff != 0 || yOff != 0) { for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) continue; // ignore the special text nodes boolean special = false; for(int i=0; i<arcTextTable.length; i++) if (arcTextTable[i].ni == ni) special = true; if (special) continue; // center the geometry ni.move(xOff, yOff); } } } } }