/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Gallery.java
*
* Copyright (c) 2003 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.generator.layout;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.ListIterator;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.Library;
import com.sun.electric.database.hierarchy.View;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.technology.PrimitiveNode;
import com.sun.electric.technology.Technology;
import com.sun.electric.tool.Job;
public class Gallery {
static final double PAGE_WIDTH = 1000;
static final double HORIZONTAL_SPACE = 30;
static final double VERTICAL_SPACE = 30;
static final double TEXT_OFFSET_BELOW_CELL = 10;
private PrimitiveNode textPin;
private StdCellParams stdCell;
private Library lib;
private static void error(boolean pred, String msg) {
Job.error(pred, msg);
}
ArrayList<Cell> readLayoutCells(Library lib) {
ArrayList<Cell> cells = new ArrayList<Cell>();
Iterator<Cell> it = lib.getCells();
View layView = View.findView("layout");
while (it.hasNext()) {
Cell c = it.next();
if (c.getName().equals("gallery")) continue;
if (c.getName().startsWith("drcRing")) continue;
if (c.getView()==layView) cells.add(c);
}
return cells;
}
void sortCellsByName(ArrayList<Cell> facets) {
Collections.sort(facets, new Comparator<Cell>() {
public int compare(Cell c1, Cell c2) {
String n1 = c1.getName();
String n2 = c2.getName();
return n1.compareTo(n2);
}
});
}
void printCells(ArrayList<Cell> facets) {
for (int i=0; i<facets.size(); i++) {
Cell p = facets.get(i);
System.out.println(p.getName());
}
}
ArrayList<NodeInst> addOneInstOfEveryCell(ArrayList<Cell> cells, Cell gallery) {
ArrayList<NodeInst> insts = new ArrayList<NodeInst>();
for (int i=0; i<cells.size(); i++) {
Cell c = cells.get(i);
NodeInst ni = LayoutLib.newNodeInst(c, 0, 0, 0,
0, 0, gallery);
insts.add(ni);
}
return insts;
}
double width(NodeInst ni) {
return LayoutLib.getBounds(ni).getWidth();
}
double height(NodeInst ni) {
return LayoutLib.getBounds(ni).getHeight();
}
double[] getRow(ArrayList<NodeInst> row, ListIterator<NodeInst> it) {
double x = 0;
double highestAboveCenter = Double.MIN_VALUE;
double lowestBelowCenter = Double.MIN_VALUE;
while (it.hasNext()) {
NodeInst ni = it.next();
// always add at least 1 part to each row
if (x!=0 && x+width(ni)>PAGE_WIDTH) {it.previous(); break;}
row.add(ni);
Rectangle2D bounds = LayoutLib.getBounds(ni);
highestAboveCenter = Math.max(highestAboveCenter, bounds.getMaxY());
lowestBelowCenter = Math.min(lowestBelowCenter, bounds.getMinY());
x = x + width(ni) + HORIZONTAL_SPACE;
}
return new double[] {highestAboveCenter, lowestBelowCenter};
}
void placeRow(ArrayList<NodeInst> row, double centerY, Cell gallery) {
double curLeftX = 0;
//System.out.println("Row at: "+y);
for (int i=0; i<row.size(); i++) {
NodeInst ni = row.get(i);
double x = LayoutLib.getBounds(ni).getMinX();
double y = LayoutLib.getPosition(ni).getY();
// System.out.println("Instance initial bounding box: "+r);
// System.out.println("Put instance at: ("+x+", "+(y-r.getY())+")");
LayoutLib.modNodeInst(ni, curLeftX-x, centerY-y, 0,0,false,false,0);
// label instance with text
double defSz = LayoutLib.DEF_SIZE;
NodeInst ti =
LayoutLib.newNodeInst(textPin, curLeftX+width(ni)/2, centerY-TEXT_OFFSET_BELOW_CELL, defSz,
defSz, 0, gallery);
ti.setExpanded(true);
// String partNm = ni.getProto().getName();
// System.out.println("Cell: "+partNm+" has width: "+width(ni));
//ti.setVar("ART_message", partNm);
//String s = (String) ni.getVar("ART_message");
//System.out.println("placeRow: NodeInst Width: "+width(ni));
curLeftX = curLeftX + width(ni) + HORIZONTAL_SPACE;
}
}
void placeInstsOnPage(ArrayList<NodeInst> insts, Cell gallery) {
double topY = 0;
for (ListIterator<NodeInst> it=insts.listIterator(); it.hasNext();) {
ArrayList<NodeInst> row = new ArrayList<NodeInst>();
double[] hiLo = getRow(row, it);
double highestAboveCenter = hiLo[0];
double lowestBelowCenter = hiLo[1];
double centerY = topY - highestAboveCenter;
placeRow(row, centerY, gallery);
topY = centerY + lowestBelowCenter - VERTICAL_SPACE;
}
}
Gallery(Library lib) {
this.lib = lib;
Technology generic = Technology.findTechnology("generic");
error(generic == null, "No generic technology?");
textPin = generic.findNodeProto("Invisible-Pin");
stdCell = new StdCellParams(TechType.TechTypeEnum.MOCMOS);
stdCell.setOutputLibrary(lib);
}
Cell makeGallery1() {
ArrayList<Cell> cells = readLayoutCells(lib);
System.out.println("Gallery contains: " + cells.size() + " Cells");
sortCellsByName(cells);
Cell gallery = Cell.newInstance(lib, "gallery{lay}");
ArrayList<NodeInst> insts = addOneInstOfEveryCell(cells, gallery);
placeInstsOnPage(insts, gallery);
return gallery;
}
/**
* Create a new Cell named "gallery" in Library "lib". Into
* Gallery place one instance of every Cell in "lib". Arrange
* instances in rows sorted alphabetically by Cell name.
*/
public static Cell makeGallery(Library lib) {
Gallery galleryMaker = new Gallery(lib);
return galleryMaker.makeGallery1();
}
// generate Gallery for currently open library
public static void main(String[] args) {
Library lib = Library.getCurrent();
error(lib == null, "No currently open library?");
makeGallery(lib);
System.out.println("Done");
}
}