📄 postscriptcolor.java
字号:
for (int k=0; k < q2.numBoxes; k++) { t[1] = q2.boxes[k].pos[3] + q2.boxes[k].pos[1]; b[1] = q2.boxes[k].pos[3]; l[1] = q2.boxes[k].pos[2]; r[1] = q2.boxes[k].pos[2] + q2.boxes[k].pos[0]; t[2] = t[0] < t[1] ? t[0] : t[1]; b[2] = b[0] > b[1] ? b[0] : b[1]; l[2] = l[0] > l[1] ? l[0] : l[1]; r[2] = r[0] < r[1] ? r[0] : r[1]; if (t[2] > b[2] && r[2] > l[2]) { // create overlap layer PsBox curBox = new PsBox(); curBox.layer = layerNum; curBox.pos[0] = (r[2]-l[2]); curBox.pos[1] = (t[2]-b[2]); curBox.pos[2] = (l[2]); curBox.pos[3] = (b[2]); curBox.visible = true; if (t[2] == t[0] && b[2] == b[0] && l[2] == l[0] && r[2] == r[0]) q1.boxes[j].visible = false; if (t[2] == t[1] && b[2] == b[1] && l[2] == l[1] && r[2] == r[1]) q2.boxes[k].visible = false; flattenedBoxes.get(layerNum).add(curBox); } } } } } private void flatten() { double [] ident = new double[9]; newIdentityMatrix(ident); for (int i=0; i<numLayers; i++) { flattenedPolys.add(new ArrayList<PsPoly>()); flattenedBoxes.add(new ArrayList<PsBox>()); } // for now, assume last cell is top level. Change this to recognize C *** at top of CIF System.out.println("Flattening..."); int lastCell = allCells.size() - 1; PsCell topCell = allCells.get(lastCell); recursiveFlatten(topCell, ident); } private void recursiveFlatten(PsCell topCell, double [] m) { // add boxes from this cell for(PsBox box : topCell.boxes) { if (box.visible) { PsBox newBox = copyBox(box, m); flattenedBoxes.get(newBox.layer).add(newBox); } } // add polygons from this cell for(PsPoly poly : topCell.polys) { PsPoly newPoly = copyPoly(poly, m); flattenedPolys.get(newPoly.layer).add(newPoly); } // recursively traverse subinstances double [] tm = new double[9]; for(PsCellInst inst : topCell.inst) { totalInstances++; matrixMul(tm, inst.transform, m); recursiveFlatten(inst.inst, tm); } } private void writePS(Cell cell, boolean usePlotter, double pageWidth, double pageHeight, double border) { // Header info PrintWriter printWriter = psObject.printWriter; printWriter.println("%%!PS-Adobe-1.0"); printWriter.println("%%Title: " + cell.describe(false)); if (User.isIncludeDateAndVersionInOutput()) { printWriter.println("%%%%Creator: Electric VLSI Design System (David Harris's color PostScript generator) version " + Version.getVersion()); printWriter.println("%%%%CreationDate: " + TextUtils.formatDate(new Date())); } else { printWriter.println("%%%%Creator: Electric VLSI Design System (David Harris's color PostScript generator)"); } printWriter.println("%%%%Pages: 1"); printWriter.println("%%%%BoundingBox: " + TextUtils.formatDouble(psBoundaries[0]) + " " + TextUtils.formatDouble(psBoundaries[1]) + " " + TextUtils.formatDouble(psBoundaries[2]) + " " + TextUtils.formatDouble(psBoundaries[3])); printWriter.println("%%%%DocumentFonts: " + FONTNAME); printWriter.println("%%%%EndComments"); // Coordinate system printWriter.println("%% Min X: " + TextUtils.formatDouble(psBoundaries[0]) + " min Y: " + TextUtils.formatDouble(psBoundaries[1]) + " max X: " + TextUtils.formatDouble(psBoundaries[2]) + " max Y: " + TextUtils.formatDouble(psBoundaries[3])); double reducedwidth = pageWidth - border*2; double reducedheight = pageHeight - border*2; double scale = reducedwidth/(psBoundaries[2]-psBoundaries[0]); if (usePlotter) { // plotter: infinite height printWriter.println(TextUtils.formatDouble(scale) + " " + TextUtils.formatDouble(scale) + " scale"); double x = psBoundaries[0]+(psBoundaries[2]-psBoundaries[0]) / 2 - (reducedwidth/scale) / 2 - border/scale; double y = psBoundaries[1] - border/scale; printWriter.println(TextUtils.formatDouble(x) + " neg " + TextUtils.formatDouble(y) + " neg translate"); } else { // printer: fixed height if (reducedheight/(psBoundaries[3]-psBoundaries[1]) < scale) scale = reducedheight/(psBoundaries[3]-psBoundaries[1]); printWriter.println(TextUtils.formatDouble(scale) + " " + TextUtils.formatDouble(scale) + " scale"); double x = psBoundaries[0]+(psBoundaries[2]-psBoundaries[0]) / 2 - (reducedwidth/scale) / 2 - border/scale; double y = psBoundaries[1]+(psBoundaries[3]-psBoundaries[1]) / 2 - (reducedheight/scale) / 2 - border/scale; printWriter.println(TextUtils.formatDouble(x) + " neg " + TextUtils.formatDouble(y) + " neg translate"); } // set font printWriter.println("/DefaultFont /" + FONTNAME + " def"); printWriter.println("/scaleFont {"); printWriter.println(" DefaultFont findfont"); printWriter.println(" exch scalefont setfont} def"); // define box command to make rectangles more memory efficient printWriter.println("\n/bx \n { /h exch def /w exch def /x exch def /y exch def"); printWriter.println(" newpath x y moveto w 0 rlineto 0 h rlineto w neg 0 rlineto closepath fill } def"); // draw layers for (int i=0; i<numLayers; i++) { // skip drawing layers that are white if (allLayers[i].r != 1 || allLayers[i].g != 1 || allLayers[i].b != 1) { List<PsBox> g = flattenedBoxes.get(i); List<PsPoly> p = flattenedPolys.get(i); if (g.size() > 0 || p.size() > 0) { StringBuffer buf = new StringBuffer(); makeLayerName(i, buf); printWriter.println(); printWriter.println("%% Layer" + buf.toString()); printWriter.println(TextUtils.formatDouble(allLayers[i].r) + " " + TextUtils.formatDouble(allLayers[i].g) + " " + TextUtils.formatDouble(allLayers[i].b) + " setrgbcolor"); } for(PsBox gB : g) { if (gB.visible) { double w = gB.pos[0]; double h = gB.pos[1]; printWriter.println(gB.pos[3] + " " + gB.pos[2] + " " + w + " " + h + " bx"); totalBoxes++; } } for(PsPoly pB : p) { if (pB.coords.length > 2) { printWriter.println("newpath " + TextUtils.formatDouble(pB.coords[0]) + " " + TextUtils.formatDouble(pB.coords[1]) + " moveto"); for (int j=2; j<pB.coords.length; j+=2) { printWriter.println(" " + TextUtils.formatDouble(pB.coords[j]) + " " + TextUtils.formatDouble(pB.coords[j+1]) + " lineto"); } printWriter.println("closepath " + (i==0 ? "stroke" : "fill")); totalPolys++; } } } } // label ports and cell instances PsCell topCell = allCells.get(0); printWriter.println(); printWriter.println("%% Port and Cell Instance Labels"); printWriter.println("0 0 0 setrgbcolor"); for(int i=0; i<psObject.headerString.length; i++) printWriter.println(psObject.headerString[i]); for(PsLabel l : topCell.labels) { double size = 14; TextDescriptor.Size s = l.descript.getSize(); if (s != null) { // absolute font sizes are easy if (s.isAbsolute()) size = s.getSize(); else { // relative font: get size in grid units size = s.getSize(); } } EditWindow_ wnd = Job.getUserInterface().getCurrentEditWindow_(); if (wnd != null) size *= wnd.getGlobalTextScale(); double psLX = l.pos[0]; double psHX = l.pos[1]; double psLY = l.pos[2]; double psHY = l.pos[3]; if (l.style == Poly.Type.TEXTBOX) { printWriter.print(TextUtils.formatDouble((psLX+psHX)/2) + " " + TextUtils.formatDouble((psLY+psHY)/2) + " " + TextUtils.formatDouble(psHX-psLX) + " " + TextUtils.formatDouble(psHY-psLY) + " "); psObject.writePSString(l.label); printWriter.println(" " + TextUtils.formatDouble(size/scale) + " Boxstring"); } else { double x = 0, y = 0; String opName = ""; if (l.style == Poly.Type.TEXTCENT) { x = (psLX+psHX)/2; y = (psLY+psHY)/2; opName = "Centerstring"; } else if (l.style == Poly.Type.TEXTTOP) { x = (psLX+psHX)/2; y = psHY; opName = "Topstring"; } else if (l.style == Poly.Type.TEXTBOT) { x = (psLX+psHX)/2; y = psLY; opName = "Botstring"; } else if (l.style == Poly.Type.TEXTLEFT) { x = psLX; y = (psLY+psHY)/2; opName = "Leftstring"; } else if (l.style == Poly.Type.TEXTRIGHT) { x = psHX; y = (psLY+psHY)/2; opName = "Rightstring"; } else if (l.style == Poly.Type.TEXTTOPLEFT) { x = psLX; y = psHY; opName = "Topleftstring"; } else if (l.style == Poly.Type.TEXTTOPRIGHT) { x = psHX; y = psHY; opName = "Toprightstring"; } else if (l.style == Poly.Type.TEXTBOTLEFT) { x = psLX; y = psLY; opName = "Botleftstring"; } else if (l.style == Poly.Type.TEXTBOTRIGHT) { x = psHX; y = psLY; opName = "Botrightstring"; } double descenderOffset = size / 12; TextDescriptor.Rotation rot = l.descript.getRotation(); if (rot == TextDescriptor.Rotation.ROT0) y += descenderOffset; else if (rot == TextDescriptor.Rotation.ROT90) x -= descenderOffset; else if (rot == TextDescriptor.Rotation.ROT180) y -= descenderOffset; else if (rot == TextDescriptor.Rotation.ROT270) x += descenderOffset; double xOff = x; double yOff = y; if (rot != TextDescriptor.Rotation.ROT0) { if (rot == TextDescriptor.Rotation.ROT90 || rot == TextDescriptor.Rotation.ROT270) { if (l.style == Poly.Type.TEXTTOP) opName = "Rightstring"; else if (l.style == Poly.Type.TEXTBOT) opName = "Leftstring"; else if (l.style == Poly.Type.TEXTLEFT) opName = "Botstring"; else if (l.style == Poly.Type.TEXTRIGHT) opName = "Topstring"; else if (l.style == Poly.Type.TEXTTOPLEFT) opName = "Botrightstring"; else if (l.style == Poly.Type.TEXTBOTRIGHT) opName = "Topleftstring"; } x = y = 0; if (rot == TextDescriptor.Rotation.ROT90) { printWriter.println(xOff + " " + yOff + " translate 90 rotate"); } else if (rot == TextDescriptor.Rotation.ROT180) { printWriter.println(xOff + " " + yOff + " translate 180 rotate"); } else if (rot == TextDescriptor.Rotation.ROT270) { printWriter.println(xOff + " " + yOff + " translate 270 rotate"); } } printWriter.print(x + " " + y + " "); psObject.writePSString(l.label); printWriter.println(" " + size + " " + opName); if (rot != TextDescriptor.Rotation.ROT0) { if (rot == TextDescriptor.Rotation.ROT90) { printWriter.println("270 rotate " + (-xOff) + " " + (-yOff) + " translate"); } else if (rot == TextDescriptor.Rotation.ROT180) { printWriter.println("180 rotate " + (-xOff) + " " + (-yOff) + " translate"); } else if (rot == TextDescriptor.Rotation.ROT270) { printWriter.println("90 rotate " + (-xOff) + " " + (-yOff) + " translate"); } } } } // Finish page printWriter.println("\nshowpage"); } private void makeLayerName(int index, StringBuffer buf) { if (allLayers[index].layer != null) { buf.append(" "); buf.append(allLayers[index].layer.getName()); return; } makeLayerName(allLayers[index].mix1, buf); makeLayerName(allLayers[index].mix2, buf); } private PsBox copyBox(PsBox g, double [] m) { PsBox newBox = new PsBox(); newBox.layer = g.layer; transformBox(newBox.pos, g.pos, m); newBox.visible = g.visible; // Update bounding box double dx = newBox.pos[0]; double dy = newBox.pos[1]; if (newBox.pos[2] < psBoundaries[0]) psBoundaries[0] = newBox.pos[2]; if (newBox.pos[3] < psBoundaries[1]) psBoundaries[1] = newBox.pos[3]; if (newBox.pos[2]+dx > psBoundaries[2]) psBoundaries[2] = newBox.pos[2]+dx; if (newBox.pos[3]+dy > psBoundaries[3]) psBoundaries[3] = newBox.pos[3]+dy; return newBox; } private PsPoly copyPoly(PsPoly p, double [] m) { PsPoly newPoly = new PsPoly(); newPoly.layer = p.layer; int numCoords = p.coords.length; newPoly.coords = new double[numCoords]; transformPoly(newPoly, p, m); // Update bounding box for(int i=0; i<numCoords; i++) { if ((i%2) == 0) { if (newPoly.coords[i] < psBoundaries[0]) psBoundaries[0] = newPoly.coords[i]; if (newPoly.coords[i] > psBoundaries[3]) psBoundaries[3] = newPoly.coords[i]; } else { if (newPoly.coords[i] < psBoundaries[1]) psBoundaries[1] = newPoly.coords[i]; if (newPoly.coords[i] > psBoundaries[2]) psBoundaries[2] = newPoly.coords[i]; } } return newPoly; } private void matrixMul(double [] r, double [] a, double [] b) { double [] tmp = new double[9]; for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { tmp[i*3+j] = 0; for (int k=0; k<3; k++) { tmp[i*3+j] += a[i*3+k] * b[k*3+j]; } } } for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { r[i*3+j] = tmp[i*3+j]; } } } private void newIdentityMatrix(double [] m) { for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { m[i*3+j] = (i==j ? 1 : 0); } } } private void transformBox(double [] finall, double [] initial, double [] m) { double [] pos = new double[2]; pos[0] = initial[2]+initial[0]/2; pos[1] = initial[3]+initial[1]/2; for (int i=0; i < 2; i++) { finall[i+2] = m[6+i]; for (int j=0; j<2; j++) { finall[i+2] += m[i+j*3]*pos[j]; } } if (m[1] == 0) { // rotation finall[0] = initial[0]; finall[1] = initial[1]; } else { finall[0] = initial[1]; finall[1] = initial[0]; } finall[2] -= finall[0]/2; finall[3] -= finall[1]/2; } private void transformPoly(PsPoly finall, PsPoly initial, double [] m) { for (int p=0; p<initial.coords.length/2; p++) { for (int i=0; i <2; i++) { finall.coords[p*2+i] = m[6+i]; for (int j=0; j<2; j++) { finall.coords[p*2+i] += m[i+j*3]*initial.coords[p*2+j]; } } } }// private void printStatistics()// {// System.out.println("Plotting statistics:");// System.out.println(" " + numLayers + " layers defined or transparencies implied in layer map");// System.out.println(" " + totalCells + " cells");// System.out.println(" " + totalInstances + " instances used");// System.out.println(" " + totalBoxes + " boxes generated");// System.out.println(" " + totalPolys + " polygons generated");// }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -