All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.tool.user.IconParameters Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
package com.sun.electric.tool.user;

import com.sun.electric.database.EditingPreferences;
import com.sun.electric.database.geometry.EPoint;
import com.sun.electric.database.geometry.ERectangle;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.Export;
import com.sun.electric.database.hierarchy.View;
import com.sun.electric.database.prototype.NodeProto;
import com.sun.electric.database.prototype.PortCharacteristic;
import com.sun.electric.database.prototype.PortProto;
import com.sun.electric.database.topology.ArcInst;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.topology.PortInst;
import com.sun.electric.database.variable.TextDescriptor;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.technologies.Artwork;
import com.sun.electric.technology.technologies.Generic;
import com.sun.electric.technology.technologies.Schematics;
import com.sun.electric.tool.JobException;
import com.sun.electric.util.TextUtils;
import com.sun.electric.util.math.DBMath;

import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
	 * Class to define parameters for automatic icon generation
 */
public class IconParameters implements Serializable
{
    /** side for input ports (when placeByCellLocation false) */		int inputSide;
    /** side for output ports (when placeByCellLocation false) */		int outputSide;
    /** side for bidir ports (when placeByCellLocation false) */		int bidirSide;
    /** side for power ports (when placeByCellLocation false) */		int pwrSide;
    /** side for ground ports (when placeByCellLocation false) */		int gndSide;
    /** side for clock ports (when placeByCellLocation false) */		int clkSide;
    /** rotation of top text (when placeByCellLocation true) */			int topRot;
    /** rotation of bottom text (when placeByCellLocation true) */		int bottomRot;
    /** rotation of left text (when placeByCellLocation true) */		int leftRot;
    /** rotation of right text (when placeByCellLocation true) */		int rightRot;
    /** skip top text (when placeByCellLocation true) */				boolean topSkip;
    /** skip bottom text (when placeByCellLocation true) */				boolean bottomSkip;
    /** skip left text (when placeByCellLocation true) */				boolean leftSkip;
    /** skip right text (when placeByCellLocation true) */				boolean rightSkip;

    public static IconParameters makeInstance(boolean userDefaults)
    {
        return new IconParameters(userDefaults);
    }

    private IconParameters(boolean userDefaults)
    {
        inputSide = 0;
        outputSide = 1;
        bidirSide = 2;
        pwrSide = 3;
        gndSide = 3;
        clkSide = 0;
        topRot = 0;
        bottomRot = 0;
        leftRot = 0;
        rightRot = 0;
        topSkip = false;
        bottomSkip = false;
        leftSkip = false;
        rightSkip = false;
        if (userDefaults)
        {
            inputSide = User.getIconGenInputSide();
            outputSide = User.getIconGenOutputSide();
            bidirSide = User.getIconGenBidirSide();
            pwrSide = User.getIconGenPowerSide();
            gndSide = User.getIconGenGroundSide();
            clkSide = User.getIconGenClockSide();
            topRot = User.getIconGenTopRot();
            bottomRot = User.getIconGenBottomRot();
            leftRot = User.getIconGenLeftRot();
            rightRot = User.getIconGenRightRot();
            topSkip = User.isIconGenTopSkip();
            bottomSkip = User.isIconGenBottomSkip();
            leftSkip = User.isIconGenLeftSkip();
            rightSkip = User.isIconGenRightSkip();
        }
    }

    private static class ShadowExport implements Comparable
    {
    	String exportName;
    	List indices;
    	List originals;
    	Point2D center;
    	boolean isBus;
    	boolean nearLeft, nearRight, nearTop, nearBottom;

    	ShadowExport(String name)
    	{
    		exportName = name;
    		indices = new ArrayList();
    		originals = new ArrayList();
    		isBus = false;
    		nearLeft = nearRight = nearTop = nearBottom = false;
    	}

		/**
		 * Method to sort Exports by their angle about the cell center.
		 */
		public int compareTo(ShadowExport other)
		{
			Cell cell = originals.get(0).getParent();
			ERectangle bounds = cell.getBounds();
			Point2D cellCtr = new Point2D.Double(bounds.getCenterX(), bounds.getCenterY());
			double angle1 = DBMath.figureAngleRadians(cellCtr, center);
			double angle2 = DBMath.figureAngleRadians(cellCtr, other.center);
			if (angle1 < angle2) return 1;
			if (angle1 > angle2) return -1;
			return 0;
		}
    }

    /**
     * Method to create an icon for a cell.
     * @param curCell the cell to turn into an icon.
     * @param ep EditingPreferences with default sizes and text descriptors.
     * @return the icon cell (null on error).
     */
    public Cell makeIconForCell(Cell curCell, EditingPreferences ep)
        throws JobException
    {
        // create the new icon cell
    	boolean schematicSource = (curCell.getView() == View.SCHEMATIC);
        String iconCellName = curCell.getName() + "{ic}";
        Cell iconCell = Cell.makeInstance(ep, curCell.getLibrary(), iconCellName);
        if (iconCell == null)
            throw new JobException("Cannot create Icon cell " + iconCellName);
        iconCell.setWantExpanded();
        ERectangle cellBounds = curCell.getBounds();

        // make the "shadow" list of exports to place
    	Map shadowExports = new HashMap();
    	for(Iterator it = curCell.getPorts(); it.hasNext(); )
    	{
    		Export e = (Export)it.next();
    		if (e.isBodyOnly()) continue;
    		String name = e.getName();
    		if (schematicSource)
    		{
        		ShadowExport se = new ShadowExport(name);
        		shadowExports.put(name, se);
        		se.isBus = e.getNameKey().isBus();
        		se.originals.add(e);
    		} else
    		{
        		Integer index = null;
        		int indexPos = name.indexOf('[');
        		if (indexPos >= 0)
        		{
        			String indexPart = name.substring(indexPos+1);
        			int lastSq = indexPart.indexOf(']');
        			if (lastSq == indexPart.length()-1)
        			{
        				int indexVal = TextUtils.atoi(indexPart.substring(0, lastSq));
        				index = Integer.valueOf(indexVal);
        				name = name.substring(0, indexPos);
        			}
        		}
        		ShadowExport se = shadowExports.get(name);
        		if (se == null) shadowExports.put(name, se = new ShadowExport(name));
        		if (index != null) se.indices.add(index);
        		se.originals.add(e);
    		}
    	}
    	List shadowExportList = new ArrayList();
    	for(String seName : shadowExports.keySet())
    	{
    		ShadowExport se = shadowExports.get(seName);
    		double x = 0, y = 0;
    		for(Export e : se.originals)
    		{
    			Point2D ctr = e.getOriginalPort().getCenter();
    			x += ctr.getX();
    			y += ctr.getY();
    			if (ctr.getX() < cellBounds.getMinX() + cellBounds.getWidth()/10.0) se.nearLeft = true;
    			if (ctr.getX() > cellBounds.getMaxX() - cellBounds.getWidth()/10.0) se.nearRight = true;
    			if (ctr.getY() < cellBounds.getMinY() + cellBounds.getHeight()/10.0) se.nearBottom = true;
    			if (ctr.getY() > cellBounds.getMaxY() - cellBounds.getHeight()/10.0) se.nearTop = true;
    		}
    		se.center = new Point2D.Double(x / se.originals.size(), y / se.originals.size());

    		if (se.indices.size() == 1)
    		{
    			se.exportName += "[" + se.indices.get(0) + "]";
    		} else if (se.indices.size() > 0)
    		{
    			Collections.sort(se.indices);
    			String index = "";
    			for(int i=0; i portIndex = new HashMap();
        Map portSide = new HashMap();
        Map portRotation = new HashMap();

        // make a sorted list of exports
        if (ep.getIconGenExportPlacement() == 1)
        {
        	// place exports according to their location in the cell
            Collections.sort(shadowExportList);

            // figure out how many exports go on each side
            int numExports = shadowExportList.size();
        	int numSides = (topSkip ? 0 : 1) + (bottomSkip ? 0 : 1) + (leftSkip ? 0 : 1) + (rightSkip ? 0 : 1);
        	if (numSides == 0) { numSides = 1;  leftSkip = false; }
            if (schematicSource)
            {
            	int numOnSide = numExports / numSides;
            	if (topSkip) topSide = 0; else topSide = numOnSide;
            	if (bottomSkip) bottomSide = 0; else bottomSide = numOnSide;
            	if (leftSkip) leftSide = 0; else leftSide = numOnSide;
            	if (rightSkip) rightSide = 0; else rightSide = numOnSide;
            } else
            {
            	for(ShadowExport se : shadowExportList)
            	{
            		if (se.nearBottom && !bottomSkip) { bottomSide++;  continue; }
            		if (se.nearTop && !topSkip) { topSide++;  continue; }
            		if (se.nearLeft && !leftSkip) { leftSide++;  continue; }
            		if (se.nearRight && !rightSkip) { rightSide++;  continue; }
            	}
            }
            int cycle = 0;
            while (leftSide + rightSide + topSide + bottomSide < numExports)
            {
            	switch (cycle)
            	{
            		case 0: if (!leftSkip) leftSide++;      break;
            		case 1: if (!rightSkip) rightSide++;    break;
            		case 2: if (!topSkip) topSide++;        break;
            		case 3: if (!bottomSkip) bottomSide++;  break;
            	}
            	cycle = (cycle+1) % 4;
            }

            // make an array of points in the middle of each side
            int[] sides = new int[numExports];
            int fill = 0;
            for(int i=0; i
	{
		/**
		 * Method to sort Exports by their angle about the cell center.
		 */
		public int compare(ShadowExport p1, ShadowExport p2)
		{
			String p1Name = p1.exportName;
			String p2Name = p2.exportName;
			return p1Name.compareTo(p2Name);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy