📄 cif.java
字号:
private boolean nodesCall() { BackCIFCall cc = (BackCIFCall)currentFrontElement.member; BackCIFCell cell = findBackCIFCell(cc.cIndex); if (cell == null) { System.out.println("Referencing an undefined cell"); return true; } int rot = 0; boolean trans = false; int l = cell.l; int r = cell.r; int b = cell.b; int t = cell.t; for(BackCIFTransform ctrans = cc.list; ctrans != null; ctrans = ctrans.next) switch (ctrans.type) { case MIRX: int temp = l; l = -r; r = -temp; rot = (trans) ? ((rot+2700) % 3600) : ((rot+900) % 3600); trans = !trans; break; case MIRY: temp = t; t = -b; b = -temp; rot = (trans) ? ((rot+900) % 3600) : ((rot+2700) % 3600); trans = !trans; break; case TRANS: l += ctrans.x; r += ctrans.x; b += ctrans.y; t += ctrans.y; break; case ROT: int deg = GenMath.figureAngle(new Point2D.Double(0, 0), new Point2D.Double(ctrans.x, ctrans.y)); if (deg != 0) { int hlen = Math.abs(((l-r)/2)); int hwid = Math.abs(((b-t)/2)); int cenX = (l+r)/2; int cenY = (b+t)/2; Point pt = new Point(cenX, cenY); rotateLayer(pt, deg); cenX = pt.x; cenY = pt.y; l = cenX - hlen; r = cenX + hlen; b = cenY - hwid; t = cenY + hwid; rot += ((trans) ? -deg : deg); } } while (rot >= 3600) rot -= 3600; while (rot < 0) rot += 3600; double lX = convertFromCentimicrons(l); double hX = convertFromCentimicrons(r); double lY = convertFromCentimicrons(b); double hY = convertFromCentimicrons(t); double x = (lX + hX) / 2; double y = (lY + hY) / 2; double sX = hX - lX; double sY = hY - lY; Rectangle2D bounds = cell.addr.getBounds(); sX = bounds.getWidth(); sY = bounds.getHeight(); // transform is rotation and transpose: convert to rotation/MX/MY Orientation or = Orientation.fromC(rot, trans); // special code to account for rotation of cell centers AffineTransform ctrTrans = or.rotateAbout(x, y); Point2D spin = new Point2D.Double(x - bounds.getCenterX(), y - bounds.getCenterY()); ctrTrans.transform(spin, spin); x = spin.getX(); y = spin.getY(); // create the node NodeInst ni = NodeInst.makeInstance(cell.addr, new Point2D.Double(x, y), sX, sY, currentBackCell.addr, or, null, 0); if (ni == null) { System.out.println("Problems creating an instance of " + cell.addr + " in " + currentBackCell.addr); return true; } return false; } private boolean nodesPoly() { BackCIFPoly cp = (BackCIFPoly)currentFrontElement.member; if (cp.lim == 0) return false; NodeProto np = findPrototype(cp.lay); int lx = cp.x[0]; int hx = cp.x[0]; int ly = cp.y[0]; int hy = cp.y[0]; for(int i=1; i<cp.lim; i++) { if (cp.x[i] < lx) lx = cp.x[i]; if (cp.x[i] > hx) hx = cp.x[i]; if (cp.y[i] < ly) ly = cp.y[i]; if (cp.y[i] > hy) hy = cp.y[i]; } // convert from centimicrons double lowX = convertFromCentimicrons(lx); double highX = convertFromCentimicrons(hx); double lowY = convertFromCentimicrons(ly); double highY = convertFromCentimicrons(hy); double x = (lowX + highX) / 2; double y = (lowY + highY) / 2; double sX = highX - lowX; double sY = highY - lowY; NodeInst newni = NodeInst.makeInstance(np, new Point2D.Double(x, y), sX, sY, currentBackCell.addr); if (newni == null) { System.out.println("Problems creating a polygon on layer " + cp.lay + " in " + currentBackCell.addr); return true; } // store the trace information EPoint [] points = new EPoint[cp.lim]; for(int i=0; i<cp.lim; i++) { points[i] = new EPoint(convertFromCentimicrons(cp.x[i]), convertFromCentimicrons(cp.y[i])); } // store the trace information newni.setTrace(points); return false; } private void rotateLayer(Point pt, int deg) { // trivial test to prevent atan2 domain errors if (pt.x == 0 && pt.y == 0) return; switch (deg) // do the manhattan cases directly { case 0: case 3600: // just in case break; case 900: int temp = pt.x; pt.x = -pt.y; pt.y = temp; break; case 1800: pt.x = -pt.x; pt.y = -pt.y; break; case 2700: temp = pt.x; pt.x = pt.y; pt.y = -temp; break; default: // this old code only permits rotation by integer angles double factx = 1, facty = 1; while(Math.abs(pt.x/factx) > 1000) factx *= 10.0; while(Math.abs(pt.y/facty) > 1000) facty *= 10.0; double fact = (factx > facty) ? facty : factx; double fx = pt.x / fact; double fy = pt.y / fact; double vlen = fact * Math.hypot(fx, fy); double vang = (deg + GenMath.figureAngle(new Point2D.Double(0, 0), new Point2D.Double(pt.x, pt.y))) / 10.0 / (45.0 / Math.atan(1.0)); pt.x = (int)(vlen * Math.cos(vang)); pt.y = (int)(vlen * Math.sin(vang)); break; } } private void outputPolygon(Layer lay, FrontPath pPath) { int lim = pPath.pLength; if (lim < 3) return; placeCIFList(CPOLY); BackCIFPoly cp = (BackCIFPoly)currentFrontElement.member; cp.lay = lay; cp.x = new int[lim]; cp.y = new int[lim]; cp.lim = lim; for (int i = 0; i < lim; i++) { Point temp = removePoint(pPath); cp.x[i] = temp.x; cp.y[i] = temp.y; } } private double convertFromCentimicrons(double v) { return TextUtils.convertFromDistance(v/100, curTech, TextUtils.UnitScale.MICRO); } private boolean nodesBox() { BackCIFBox cb = (BackCIFBox)currentFrontElement.member; NodeProto node = findPrototype(cb.lay); if (node == null) { String layname = cb.lay.getName(); System.out.println("Cannot find primitive to use for layer '" + layname + "' (number " + cb.lay + ")"); return true; } int r = GenMath.figureAngle(new Point2D.Double(0, 0), new Point2D.Double(cb.xRot, cb.yRot)); double x = convertFromCentimicrons(cb.cenX); double y = convertFromCentimicrons(cb.cenY); double len = convertFromCentimicrons(cb.length); double wid = convertFromCentimicrons(cb.width); Orientation orient = Orientation.fromAngle(r); NodeInst ni = NodeInst.makeInstance(node, new Point2D.Double(x, y), len, wid, currentBackCell.addr, orient, null, 0); if (ni == null) { String layname = cb.lay.getName(); System.out.println("Problems creating a box on layer " + layname + " in " + currentBackCell.addr); return true; } return false; } private boolean interpret() { initParser(); initInterpreter(); inFromFile(); parseFile(); // read in the cif doneParser(); if (numFatalErrors > 0) return true; if (unknownLayerNames.size() > 0) { System.out.println("Error: these layers appear in the CIF file but are not assigned to Electric layers:"); for(String str : unknownLayerNames) { System.out.println(" " + str); } } getInterpreterBounds(); // construct a list: first step in the conversion createList(); return false; } private BackCIFCell findBackCIFCell(int cIndex) { return cifCellMap.get(new Integer(cIndex)); } private BackCIFCell makeBackCIFCell(int cIndex) { BackCIFCell newCC = new BackCIFCell(); newCC.addr = null; newCC.cIndex = cIndex; cifCellMap.put(new Integer(newCC.cIndex), newCC); currentBackCell = newCC; return newCC; } private NodeProto findPrototype(Layer lay) { return lay.getNonPseudoLayer().getPureLayerNode(); } private boolean initFind() { // get the array of CIF names cifLayerNames = new HashMap<String,Layer>(); unknownLayerNames = new HashSet<String>(); boolean valid = false; curTech = Technology.getCurrent(); for(Iterator<Layer> it = curTech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); String cifName = layer.getCIFLayer(); if (cifName != null && cifName.length() > 0) { cifLayerNames.put(cifName, layer); valid = true; } } if (!valid) { System.out.println("There are no CIF layer names assigned in the " + curTech.getTechName() + " technology"); return true; } return false; } private void initInterpreter() { numNullLayerErrors = false; isInCellDefinition = false; ignoreStatements = false; namePending = false; endCommandFound = false; currentLayer = null; currentItemList = null; initUtilities(); initMatrices(); } private void initParser() { errorFound = false; errorType = NOERROR; isInCellDefinition = false; endIsSeen = false; initInput(); initErrors(); } private void doneParser() { if (!endIsSeen) errorReport("missing End command", FATALSYNTAX); } private int parseFile() { int comCount = 1; for(;;) { int com = parseStatement(); if (com == END || com == ENDFILE) break; comCount++; } return comCount; } private void doneInterpreter() { if (numNullLayerErrors) { System.out.println("Warning: some CIF objects were not read"); } } private Rectangle getInterpreterBounds() { FrontItem h = currentItemList; boolean first = true; if (h == null) { errorReport("item list is empty!", ADVISORY); return null; } pushTransform(); while (h != null) { FrontObjBase obj = h.what; Point temp = new Point(); temp.x = obj.bb.l; temp.y = obj.bb.b; Point comperror = transformPoint(temp); initMinMax(comperror); temp.x = obj.bb.r; comperror = transformPoint(temp); minMax(comperror); temp.y = obj.bb.t; comperror = transformPoint(temp); minMax(comperror); temp.x = obj.bb.l; comperror = transformPoint(temp); minMax(comperror); int left = getMinMaxMinX(); int right = getMinMaxMaxX(); int bottom = getMinMaxMinY(); int top = getMinMaxMaxY(); doneMinMax(); temp.x = left; temp.y = bottom; if (first) {first = false; initMinMax(temp);} else minMax(temp); temp.x = right; temp.y = top; minMax(temp); h = h.same; } Rectangle ret = new Rectangle(getMinMaxMinX(), getMinMaxMinY(), getMinMaxMaxX()-getMinMaxMinX(), getMinMaxMaxY()-getMinMaxMinY()); doneMinMax(); popTransform(); return ret; } private void createList() { if (!isEndSeen()) System.out.println("missing End command, assumed"); if (numFatalErrors > 0) return; sendList(currentItemList); // sendlist deletes nodes currentItemList = null; } private void sendList(FrontItem list) { FrontItem h = list; while (h != null) { FrontItem save = h.same; outItem(h); h = save; } } /** * spit out an item */ private void outItem(FrontItem thing) { if (thing.what instanceof FrontPoly) { FrontPoly po = (FrontPoly)thing.what; FrontPath pPath = new FrontPath(); for (int i = 0; i < po.points.length; i++) appendPoint(pPath, po.points[i]); outputPolygon(po.layer, pPath); return; } if (thing.what instanceof FrontWire) { FrontWire wi = (FrontWire)thing.what; FrontPath pPath = new FrontPath(); for (int i = 0; i < wi.points.length; i++) appendPoint(pPath, wi.points[i]); outputWire(wi.layer, wi.width, pPath); return; } if (thing.what instanceof FrontFlash) { FrontFlash fl = (FrontFlash)thing.what; outputFlash(fl.layer, fl.diameter, fl.center); return; } if (thing.what instanceof FrontBox) { FrontBox bo = (FrontBox)thing.what; outputBox(bo.layer, bo.length, bo.width, bo.center, bo.xRot, bo.yRot); return; } if (thing.what instanceof FrontManBox) { Point temp = new Point(); FrontManBox mb = (FrontManBox)thing.what; temp.x = (mb.bb.r + mb.bb.l)/2; temp.y = (mb.bb.t + mb.bb.b)/2; outputBox(mb.layer, mb.bb.r-mb.bb.l, mb.bb.t-mb.bb.b, temp, 1, 0); return; } if (thing.what instanceof FrontCall) { pushTransform(); FrontCall sc = (FrontCall)thing.what; applyLocal(sc.matrix); FrontTransformList tList = new FrontTransformList(); dupTransformList(sc.transList, tList); dumpDefinition(sc.unID); outputCall(sc.symNumber, sc.unID.name, tList); popTransform(); return; } if (thing.what instanceof FrontGeomName) { FrontGeomName gn = (FrontGeomName)thing.what; outputGeomName(gn.layer); return; } if (thing.what instanceof FrontLabel) { FrontLabel la = (FrontLabel)thing.what; outputLabel(la.name, la.pos); return; } } private void outputLabel(String name, Point pt) { placeCIFList(CLABEL); BackCIFLabel cl = (BackCIFLabel)currentFrontElement.member; cl.label = name; cl.x = pt.x; cl.y = pt.y; } private void outputGeomName(Layer lay) { placeCIFList(CGNAME); BackCIFGeomName cg = (BackCIFGeomName)currentFrontElement.member; cg.lay = lay; } private void outputCall(int number, String name, FrontTransformList list) { placeCIFList(CCALL); BackCIFCall cc = (BackCIFCall)currentFrontElement.member; cc.cIndex = number; cc.name = name; cc.list = currentCTrans = null; for(int i = getFrontTransformListLength(list); i>0; i--) { if (newBackCIFTransform() == null) return; FrontTransformEntry temp = removeFrontTransformEntry(list); if (temp.kind == MIRROR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -