⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 circuitchangejobs.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: CircuitChangeJobs.java * * Copyright (c) 2006 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.user;import com.sun.electric.database.IdMapper;import com.sun.electric.database.constraint.Layout;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.Dimension2D;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.geometry.PolyMerge;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.EDatabase;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.Name;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Connection;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.CodeExpression;import com.sun.electric.database.variable.DisplayedText;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.io.input.LibraryFiles;import com.sun.electric.tool.user.dialogs.OpenFile;import com.sun.electric.tool.user.ui.EditWindow;import com.sun.electric.tool.user.ui.SizeListener;import com.sun.electric.tool.user.ui.StatusBar;import com.sun.electric.tool.user.ui.TopLevel;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.Serializable;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.swing.JOptionPane;/** * Class for Jobs that make changes to the circuit. */public class CircuitChangeJobs{	// constructor, never used	CircuitChangeJobs() {}	/****************************** NODE TRANSFORMATION ******************************/	public static class RotateSelected extends Job	{		private Cell cell;		private int amount;		private boolean mirror;		private boolean mirrorH;		private List<Geometric> highs;		/**		 * @param cell		 * @param highs the highlighted objects (list of highlights)		 * @param amount angle in tenth degrees to rotate		 * @param mirror whether or not to mirror. if true, amount is ignored, and mirrorH is used.		 * @param mirrorH if true, mirror horizontally (flip over X-axis), otherwise mirror		 * vertically (flip over Y-axis). Ignored if mirror is false.		 */		public RotateSelected(Cell cell, List<Geometric> highs, int amount, boolean mirror, boolean mirrorH)		{			super("Rotate selected objects", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);			this.cell = cell;			this.amount = amount;			this.mirror = mirror;			this.mirrorH = mirrorH;			this.highs = highs;			startJob();		}		public boolean doIt() throws JobException		{			// disallow rotating if lock is on			if (cantEdit(cell, null, true, false, true) != 0) return false;			// figure out which nodes get rotated/mirrored			Set<Geometric> markObj = new HashSet<Geometric>();			int nicount = 0;			NodeInst theNi = null;			Rectangle2D selectedBounds = new Rectangle2D.Double();			for(Geometric geom : highs)			{				if (!(geom instanceof NodeInst)) continue;				NodeInst ni = (NodeInst)geom;				if (cantEdit(cell, ni, true, false, true) != 0)				{					return false;				}				markObj.add(ni);				if (nicount == 0)				{					selectedBounds.setRect(ni.getBounds());				} else				{					Rectangle2D.union(selectedBounds, ni.getBounds(), selectedBounds);				}				theNi = ni;				nicount++;			}			// must be at least 1 node			if (nicount <= 0)			{				System.out.println("Must select at least 1 node for rotation");				return false;			}			// if multiple nodes, find the center one			if (nicount > 1)			{				Point2D center = new Point2D.Double(selectedBounds.getCenterX(), selectedBounds.getCenterY());				theNi = null;				double bestdist = Integer.MAX_VALUE;				for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )				{					NodeInst ni = it.next();					if (!markObj.contains(ni)) continue;					double dist = center.distance(ni.getTrueCenter());					// LINTED "bestdist" used in proper order					if (theNi == null || dist < bestdist)					{						theNi = ni;						bestdist = dist;					}				}			}			// see which nodes already connect to the main rotation/mirror node (theNi)			markObj.clear();			for(Geometric geom : highs)			{				if (!(geom instanceof ArcInst)) continue;				ArcInst ai = (ArcInst)geom;				markObj.add(ai);			}			spreadRotateConnection(theNi, markObj);			// now make sure that it is all connected			for(Geometric geom : highs)			{				if (!(geom instanceof NodeInst)) continue;				NodeInst ni = (NodeInst)geom;				spreadRotateConnection(ni, markObj);			}			// do the rotation/mirror			Orientation dOrient;			if (mirror)			{				// do mirroring				dOrient = mirrorH ? Orientation.Y : Orientation.X;			} else			{				// do rotation				dOrient = Orientation.fromAngle(amount);			}			AffineTransform trans = dOrient.rotateAbout(theNi.getAnchorCenter());			Point2D.Double tmpPt1 = new Point2D.Double(), tmpPt2 = new Point2D.Double();			// Rotate nodes in markObj			for (Geometric geom : markObj) {				if (!(geom instanceof NodeInst)) continue;				NodeInst ni = (NodeInst)geom;				trans.transform(ni.getAnchorCenter(), tmpPt1);				ni.rotate(dOrient);				ni.move(tmpPt1.getX() - ni.getAnchorCenterX(), tmpPt1.getY() - ni.getAnchorCenterY());			}			// Rotate arcs in markObj			for (Geometric geom : markObj) {				if (!(geom instanceof ArcInst)) continue;				ArcInst ai = (ArcInst)geom;				if (markObj.contains(ai.getHeadPortInst().getNodeInst()))					trans.transform(ai.getHeadLocation(), tmpPt1);				else					tmpPt1.setLocation(ai.getHeadLocation());				if (markObj.contains(ai.getTailPortInst().getNodeInst()))					trans.transform(ai.getTailLocation(), tmpPt2);				else					tmpPt2.setLocation(ai.getTailLocation());				ai.modify(tmpPt1.getX() - ai.getHeadLocation().getX(), tmpPt1.getY() - ai.getHeadLocation().getY(),					tmpPt2.getX() - ai.getTailLocation().getX(), tmpPt2.getY() - ai.getTailLocation().getY());			}			return true;		}	}	/**	 * Helper method for rotation to mark selected nodes that need not be	 * connected with an invisible arc.	 */	private static void spreadRotateConnection(NodeInst theNi, Set<Geometric> markObj)	{		if (markObj.contains(theNi)) return;		markObj.add(theNi);		for(Iterator<Connection> it = theNi.getConnections(); it.hasNext(); )		{			Connection con = it.next();			ArcInst ai = con.getArc();			if (!markObj.contains(ai)) continue;			int otherEnd = 1 - con.getEndIndex();			NodeInst ni = ai.getPortInst(otherEnd).getNodeInst();			if (markObj.contains(ni)) continue;			markObj.add(ni);			spreadRotateConnection(ni, markObj);		}	}	/****************************** NODE ALIGNMENT ******************************/	/**	 * This class implement the command to align objects to the grid.	 */	public static class AlignObjects extends Job	{		private List<Geometric> list;			// list of highlighted objects to align		private Dimension2D alignment;		public AlignObjects(List<Geometric> highs, Dimension2D alignment)		{			super("Align Objects", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);			this.list = highs;			this.alignment = alignment;			startJob();		}		public boolean doIt() throws JobException		{			if (list.size() == 0)			{				System.out.println("Must select something before aligning it to the grid");				return false;			}			if (alignment.getWidth() <= 0 || alignment.getHeight() <= 0)			{				System.out.println("No alignment given: set Alignment Options first");				return false;			}			// first adjust the nodes			int adjustedNodes = 0;			for(Geometric geom : list)			{				if (!(geom instanceof NodeInst)) continue;				NodeInst ni = (NodeInst)geom;				Point2D [] points = ni.getTrace();				if (points != null)				{					AffineTransform transOut = ni.pureRotateOut();					Point2D [] newPoints = new Point2D[points.length];					boolean changed = false;					for(int i=0; i<points.length; i++)					{						if (points[i] == null) continue;						Point2D newPoint = new Point2D.Double(points[i].getX() + ni.getAnchorCenterX(), points[i].getY() + ni.getAnchorCenterY());						transOut.transform(newPoint, newPoint);						double oldX = newPoint.getX();						double oldY = newPoint.getY();						DBMath.gridAlign(newPoint, alignment);						if (oldX != newPoint.getX() || oldY != newPoint.getY()) changed = true;						newPoints[i] = newPoint;					}					if (changed)					{						adjustedNodes++;						ni.setTrace(newPoints);					}					continue;				}				Point2D center = new Point2D.Double(ni.getAnchorCenterX(), ni.getAnchorCenterY());				DBMath.gridAlign(center, alignment);				double bodyXOffset = center.getX() - ni.getAnchorCenterX();				double bodyYOffset = center.getY() - ni.getAnchorCenterY();				double portXOffset = bodyXOffset;				double portYOffset = bodyYOffset;				boolean mixedportpos = false;				boolean firstPort = true;				for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); )				{					PortInst pi = pIt.next();					Poly poly = pi.getPoly();					Point2D portCenter = new Point2D.Double(poly.getCenterX(), poly.getCenterY());					DBMath.gridAlign(portCenter, alignment);					double pXO = portCenter.getX() - poly.getCenterX();					double pYO = portCenter.getY() - poly.getCenterY();					if (firstPort)					{						firstPort = false;						portXOffset = pXO;   portYOffset = pYO;					} else					{						if (portXOffset != pXO || portYOffset != pYO) mixedportpos = true;					}				}				if (!mixedportpos)				{					bodyXOffset = portXOffset;   bodyYOffset = portYOffset;				}				// if a primitive has an offset, see if the node edges are aligned				if (bodyXOffset != 0 || bodyYOffset != 0)				{					if (!ni.isCellInstance())					{						AffineTransform transr = ni.rotateOut();						Technology tech = ni.getProto().getTechnology();						Poly [] polyList = tech.getShapeOfNode(ni);						for(int j=0; j<polyList.length; j++)						{							Poly poly = polyList[j];							poly.transform(transr);							Rectangle2D bounds = poly.getBox();							if (bounds == null) continue;							Point2D polyPoint1 = new Point2D.Double(bounds.getMinX(), bounds.getMinY());							Point2D polyPoint2 = new Point2D.Double(bounds.getMaxX(), bounds.getMaxY());							DBMath.gridAlign(polyPoint1, alignment);							DBMath.gridAlign(polyPoint2, alignment);							if (polyPoint1.getX() == bounds.getMinX() &&								polyPoint2.getX() == bounds.getMaxX()) bodyXOffset = 0;							if (polyPoint1.getY() == bounds.getMinY() &&								polyPoint2.getY() == bounds.getMaxY()) bodyYOffset = 0;							if (bodyXOffset == 0 && bodyYOffset == 0) break;						}					}				}				// move the node				if (bodyXOffset != 0 || bodyYOffset != 0)				{					// turn off all constraints on arcs					Map<ArcInst,Integer> constraints = new HashMap<ArcInst,Integer>();					for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); )					{						Connection con = aIt.next();						ArcInst ai = con.getArc();						int constr = 0;						if (ai.isRigid()) constr |= 1;						if (ai.isFixedAngle()) constr |= 2;						constraints.put(ai, new Integer(constr));					}					ni.move(bodyXOffset, bodyYOffset);					adjustedNodes++;					// restore arc constraints					for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); )					{						Connection con = aIt.next();						ArcInst ai = con.getArc();						Integer constr = constraints.get(ai);						if (constr == null) continue;						if ((constr.intValue() & 1) != 0) ai.setRigid(true);						if ((constr.intValue() & 2) != 0) ai.setFixedAngle(true);					}				}			}			// now adjust the arcs			int adjustedArcs = 0;			for(Geometric geom : list)			{				if (!(geom instanceof ArcInst)) continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -