📄 postscriptcolor.java
字号:
Poly [] polys = np.getTechnology().getShapeOfNode(ni); for(int i=0; i<polys.length; i++) { Poly poly = polys[i]; poly.transform(trans); plotPolygon(poly, curCell); } } } // add geometry for all arcs for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); Poly [] polys = ai.getProto().getTechnology().getShapeOfArc(ai); for(int i=0; i<polys.length; i++) { Poly poly = polys[i]; plotPolygon(poly, curCell); } } // add the name of all exports for(Iterator<Export> it = cell.getExports(); it.hasNext(); ) { Export pp = it.next(); PsLabel curLabel = new PsLabel(); curLabel.label = pp.getName(); Rectangle2D bounds = pp.getOriginalPort().getPoly().getBounds2D(); curLabel.pos[0] = curLabel.pos[1] = bounds.getCenterX(); curLabel.pos[2] = curLabel.pos[3] = bounds.getCenterY(); curLabel.style = Poly.Type.TEXTCENT; curLabel.descript = pp.getTextDescriptor(Export.EXPORT_NAME); curCell.labels.add(curLabel); } } private void plotPolygon(Poly poly, PsCell curCell) { Layer layer = poly.getLayer(); Technology tech = layer.getTechnology(); if (tech == null) return; getLayerMap(tech); int j = 0; for( ; j<numLayers; j++) if (allLayers[j].layer == poly.getLayer()) break; if (j >= numLayers) return; Rectangle2D polyBox = poly.getBox(); Poly.Type style = poly.getStyle(); Point2D [] points = poly.getPoints(); if (style == Poly.Type.FILLED) { if (polyBox != null) { PsBox curBox = new PsBox(); curBox.layer = j; curBox.visible = true; curBox.pos[0] = polyBox.getWidth(); curBox.pos[1] = polyBox.getHeight(); curBox.pos[2] = polyBox.getCenterX(); curBox.pos[3] = polyBox.getCenterY(); curBox.pos[2] -= curBox.pos[0]/2; // adjust center x to left edge; curBox.pos[3] -= curBox.pos[1]/2; // adjust center y to bottom edge curCell.boxes.add(curBox); } else { PsPoly curPoly = new PsPoly(); curPoly.layer = j; int numCoords = points.length * 2; curPoly.coords = new double[numCoords]; for(int k=0; k<numCoords; k++) { if ((k%2) == 0) curPoly.coords[k] = points[k/2].getX(); else curPoly.coords[k] = points[k/2].getY(); } curCell.polys.add(curPoly); } } else if (style == Poly.Type.CLOSED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3) { int type = 0; if (poly.getStyle() == Poly.Type.OPENEDT1) type = 1; else if (poly.getStyle() == Poly.Type.OPENEDT2) type = 2; else if (poly.getStyle() == Poly.Type.OPENEDT3) type = 3; for (int k = 1; k < points.length; k++) plotLine(j, points[k-1].getX(), points[k-1].getY(), points[k].getX(), points[k].getY(), type, curCell); if (poly.getStyle() == Poly.Type.CLOSED) { int k = points.length - 1; plotLine(j, points[k].getX(), points[k].getY(), points[0].getX(), points[0].getY(), type, curCell); } } else if (style == Poly.Type.VECTORS) { for(int k=0; k<points.length; k += 2) plotLine(j, points[k].getX(), points[k].getY(), points[k+1].getX(), points[k+1].getY(), 0, curCell); } else if (style == Poly.Type.CROSS || style == Poly.Type.BIGCROSS) { Rectangle2D bounds = poly.getBounds2D(); double x = bounds.getCenterX(); double y = bounds.getCenterY(); plotLine(j, x-5, y, x+5, y, 0, curCell); plotLine(j, x, y+5, x, y-5, 0, curCell); } else if (style == Poly.Type.CROSSED) { Rectangle2D bounds = poly.getBounds2D(); double lX = bounds.getMinX(); double hX = bounds.getMaxX(); double lY = bounds.getMinY(); double hY = bounds.getMaxY(); plotLine(j, lX, lY, lX, hY, 0, curCell); plotLine(j, lX, hY, hX, hY, 0, curCell); plotLine(j, hX, hY, hX, lY, 0, curCell); plotLine(j, hX, lY, lX, lY, 0, curCell); plotLine(j, hX, hY, lX, lY, 0, curCell); plotLine(j, hX, lY, lX, hY, 0, curCell); } else if (style == Poly.Type.DISC || style == Poly.Type.CIRCLE || style == Poly.Type.THICKCIRCLE || style == Poly.Type.CIRCLEARC || style == Poly.Type.THICKCIRCLEARC) { if (!curveWarning) System.out.println("Warning: the 'merged color' PostScript option ignores curves. Use other color options"); curveWarning = true; } else if (style.isText()) { PsLabel curLabel = new PsLabel(); curLabel.label = poly.getString(); Rectangle2D bounds = poly.getBounds2D(); curLabel.pos[0] = bounds.getMinX(); curLabel.pos[1] = bounds.getMaxX(); curLabel.pos[2] = bounds.getMinY(); curLabel.pos[3] = bounds.getMaxY(); curLabel.style = poly.getStyle(); curLabel.descript = poly.getTextDescriptor(); curCell.labels.add(curLabel); } } /** * Method to add a line from (fx,fy) to (tx,ty) on layer "layer" to the cell "curCell". */ private void plotLine(int layer, double fx, double fy, double tx, double ty, int texture, PsCell curCell) { PsPoly curPoly = new PsPoly(); curPoly.layer = layer; curPoly.coords = new double[4]; curPoly.coords[0] = fx; curPoly.coords[1] = fy; curPoly.coords[2] = tx; curPoly.coords[3] = ty; curCell.polys.add(curPoly); } private void genOverlapShapesAfterFlattening() { // traverse the list of boxes and create new layers where overlaps occur System.out.println("Generating overlap after flattening " + numLayers + " layers..."); for (int i=0; i<numLayers; i++) { if (allLayers[i].mix1 != -1 && allLayers[i].mix2 != -1) { PxBoxQuadTree q1 = makeBoxQuadTree(allLayers[i].mix1); PxBoxQuadTree q2 = makeBoxQuadTree(allLayers[i].mix2); coaf1(q1, q2, i); } } } private PxBoxQuadTree makeBoxQuadTree(int layer) { // return if the quadtree is already generated if (quadTrees[layer] != null) return quadTrees[layer]; // otherwise find number of boxes on this layer int numBoxes = 0; for(PsBox g : flattenedBoxes.get(layer)) { if (g.visible) numBoxes++; } // and convert the list into a quad tree for faster processing // first allocate the quad tree quadTrees[layer] = new PxBoxQuadTree(); quadTrees[layer].bounds[0] = psBoundaries[0]; quadTrees[layer].bounds[1] = psBoundaries[1]; quadTrees[layer].bounds[2] = psBoundaries[2]; quadTrees[layer].bounds[3] = psBoundaries[3]; quadTrees[layer].tl = null; quadTrees[layer].tr = null; quadTrees[layer].bl = null; quadTrees[layer].br = null; quadTrees[layer].numBoxes = numBoxes; quadTrees[layer].boxes = new PsBoxElement[numBoxes]; quadTrees[layer].parent = null; quadTrees[layer].level = 0; // then copy the boxes into the tree int i = 0; for(PsBox g : flattenedBoxes.get(layer)) { if (g.visible) { quadTrees[layer].boxes[i] = new PsBoxElement(); quadTrees[layer].boxes[i].pos[0] = g.pos[0]; quadTrees[layer].boxes[i].pos[1] = g.pos[1]; quadTrees[layer].boxes[i].pos[2] = g.pos[2]; quadTrees[layer].boxes[i].pos[3] = g.pos[3]; quadTrees[layer].boxes[i].layer = g.layer; quadTrees[layer].boxes[i].visible = true; i++; } } // if there are too many boxes in this layer of the tree, create subtrees if (numBoxes > TREETHRESHOLD) recursivelyMakeBoxQuadTree(quadTrees[layer]); return quadTrees[layer]; } private void recursivelyMakeBoxQuadTree(PxBoxQuadTree q) { q.tl = new PxBoxQuadTree(); q.tl.parent = q; q.tl.level = q.level*10+1; q.tr = new PxBoxQuadTree(); q.tr.parent = q; q.tr.level = q.level*10+2; q.bl = new PxBoxQuadTree(); q.bl.parent = q; q.bl.level = q.level*10+3; q.br = new PxBoxQuadTree(); q.br.parent = q; q.br.level = q.level*10+4; // split boxes into subtrees where they fit splitTree(q.numBoxes, q.boxes, q.bl, q.bounds[0], q.bounds[1], (q.bounds[0]+q.bounds[2])/2, (q.bounds[1]+q.bounds[3])/2); splitTree(q.numBoxes, q.boxes, q.br, (q.bounds[0]+q.bounds[2])/2, q.bounds[1], q.bounds[2], (q.bounds[1]+q.bounds[3])/2); splitTree(q.numBoxes, q.boxes, q.tl, q.bounds[0], (q.bounds[1]+q.bounds[3])/2, (q.bounds[0]+q.bounds[2])/2, q.bounds[3]); splitTree(q.numBoxes, q.boxes, q.tr, (q.bounds[0]+q.bounds[2])/2, (q.bounds[1]+q.bounds[3])/2, q.bounds[2], q.bounds[3]); // and leave boxes that span the subtrees at the top level int numBoxes = 0; for (int i=0; i<q.numBoxes; i++) { if (q.boxes[i].visible) { // q.boxes[numBoxes] = q.boxes[i]; q.boxes[numBoxes].layer = q.boxes[i].layer; q.boxes[numBoxes].visible = true; q.boxes[numBoxes].pos[0] = q.boxes[i].pos[0]; q.boxes[numBoxes].pos[1] = q.boxes[i].pos[1]; q.boxes[numBoxes].pos[2] = q.boxes[i].pos[2]; q.boxes[numBoxes].pos[3] = q.boxes[i].pos[3]; numBoxes++; } } q.numBoxes = numBoxes; } private void splitTree(int numBoxes, PsBoxElement [] boxes, PxBoxQuadTree q, double left, double bot, double right, double top) { // count how many boxes are in subtree int count = 0; for (int i = 0; i<numBoxes; i++) { if (boxes[i].visible && boxes[i].pos[2] >= left && boxes[i].pos[3] >= bot && (boxes[i].pos[2]+boxes[i].pos[0]) <= right && (boxes[i].pos[3]+boxes[i].pos[1]) <= top) count++; } // and copy them into a new array for the subtree q.boxes = new PsBoxElement[count]; count = 0; for (int i=0; i<numBoxes; i++) { if (boxes[i].visible && boxes[i].pos[2] >= left && boxes[i].pos[3] >= bot && (boxes[i].pos[2]+boxes[i].pos[0]) <= right && (boxes[i].pos[3]+boxes[i].pos[1]) <= top) { q.boxes[count] = new PsBoxElement(); q.boxes[count].layer = boxes[i].layer; q.boxes[count].visible = true; q.boxes[count].pos[0] = boxes[i].pos[0]; q.boxes[count].pos[1] = boxes[i].pos[1]; q.boxes[count].pos[2] = boxes[i].pos[2]; q.boxes[count].pos[3] = boxes[i].pos[3]; boxes[i].visible = false; // mark box for removal from upper level count++; } } q.numBoxes = count; q.bounds[0] = left; q.bounds[1] = bot; q.bounds[2] = right; q.bounds[3] = top; q.tl = null; q.tr = null; q.bl = null; q.br = null; if (count > TREETHRESHOLD) { recursivelyMakeBoxQuadTree(q); } } private void mergeBoxes() { int numMerged = 0; System.out.println("Merging boxes for " + totalCells + " cells..."); for(PsCell c : allCells) { boolean changed = false; do { changed = false; for(int i1 = 0; i1 < c.boxes.size(); i1++) { PsBox b1 = c.boxes.get(i1); for(int i2 = i1+1; i2 < c.boxes.size(); i2++) { PsBox b2 = c.boxes.get(i2); if (b1.layer == b2.layer && b1.visible && b2.visible) if (mergeBoxPair(b1, b2)) changed = true; } } } while (changed); numMerged++; } } private boolean mergeBoxPair(PsBox bx1, PsBox bx2) { double t0 = bx1.pos[3] + bx1.pos[1]; double b0 = bx1.pos[3]; double l0 = bx1.pos[2]; double r0 = bx1.pos[2] + bx1.pos[0]; double t1 = bx2.pos[3] + bx2.pos[1]; double b1 = bx2.pos[3]; double l1 = bx2.pos[2]; double r1 = bx2.pos[2] + bx2.pos[0]; // if the boxes coincide, expand the first one and hide the second one if (t0 == t1 && b0 == b1 && (Math.min(r0, r1) > Math.max(l0, l1))) { double l2 = Math.min(l0, l1); double r2 = Math.max(r0, r1); bx1.pos[0] = r2-l2; bx1.pos[1] = t0-b0; bx1.pos[2] = l2; bx1.pos[3] = b0; bx2.visible = false; return true; } else if (r0 == r1 && l0 == l1 && (Math.min(t0, t1) > Math.max(b0, b1))) { double b2 = Math.min(b0, b1); double t2 = Math.max(t0, t1); bx1.pos[0] = r0-l0; bx1.pos[1] = t2-b2; bx1.pos[2] = l0; bx1.pos[3] = b2; bx2.visible = false; return true; } // if one completely covers another, hide the covered box else if (r0 >= r1 && l0 <= l1 && t0 >= t1 && b0 <= b1) { bx2.visible = false; return true; } else if (r1 >= r0 && l1 <= l0 && t1 >= t0 && b1 <= b0) { bx1.visible = false; return true; } return false; } private void coaf1(PxBoxQuadTree q1, PxBoxQuadTree q2, int layerNum) { coaf2(q1, q2, layerNum); if (q1.tl != null) { coaf3(q1.tl, q2, layerNum); coaf3(q1.tr, q2, layerNum); coaf3(q1.bl, q2, layerNum); coaf3(q1.br, q2, layerNum); if (q2.tl != null) { coaf1(q1.tl, q2.tl, layerNum); coaf1(q1.tr, q2.tr, layerNum); coaf1(q1.bl, q2.bl, layerNum); coaf1(q1.br, q2.br, layerNum); } else { coaf4(q1.tl, q2, layerNum, false); coaf4(q1.tr, q2, layerNum, false); coaf4(q1.bl, q2, layerNum, false); coaf4(q1.br, q2, layerNum, false); } } } private void coaf2(PxBoxQuadTree q1, PxBoxQuadTree q2, int layerNum) { checkOverlapAfterFlattening(q1, q2, layerNum); if (q2.tl != null) { coaf2(q1, q2.tl, layerNum); coaf2(q1, q2.tr, layerNum); coaf2(q1, q2.bl, layerNum); coaf2(q1, q2.br, layerNum); } } private void coaf3(PxBoxQuadTree q1, PxBoxQuadTree q2, int layerNum) { checkOverlapAfterFlattening(q1, q2, layerNum); if (q2.parent != null) coaf3(q1, q2.parent, layerNum); } private void coaf4(PxBoxQuadTree q1, PxBoxQuadTree q2, int layerNum, boolean check) { if (check) { coaf3(q1, q2, layerNum); } if (q1.tl != null) { coaf4(q1.tl, q2, layerNum, true); coaf4(q1.tr, q2, layerNum, true); coaf4(q1.bl, q2, layerNum, true); coaf4(q1.br, q2, layerNum, true); } } private void checkOverlapAfterFlattening(PxBoxQuadTree q1, PxBoxQuadTree q2, int layerNum) { // check overlap of boxes at this level of the quad tree double [] t = new double[3]; double [] b = new double[3]; double [] l = new double[3]; double [] r = new double[3]; if (q1.numBoxes != 0 && q2.numBoxes != 0) { for (int j=0; j<q1.numBoxes; j++) { t[0] = q1.boxes[j].pos[3] + q1.boxes[j].pos[1]; b[0] = q1.boxes[j].pos[3]; l[0] = q1.boxes[j].pos[2]; r[0] = q1.boxes[j].pos[2] + q1.boxes[j].pos[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -