~ubuntu-branches/ubuntu/maverick/electric/maverick

« back to all changes in this revision

Viewing changes to com/sun/electric/tool/user/Highlight2.java

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2010-01-09 16:26:04 UTC
  • mfrom: (1.1.4 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100109162604-1ypvmy8ijmlc6oq7
Tags: 8.10-1
* New upstream version.
* debian/control
  - Add libjava3d-java and quilt build dependencies.
  - Update standards version to 3.8.3.
  - Add libjava3d-java as recommends to binary package.
* debian/rules
  - Use quilt patch system instead of simple patchsys.
  - Add java3d related jar files to DEB_JARS.
* debian/patches/*
  - Update as per current upstream source. Convert to quilt.
* debian/ant.properties
  - Do not disable 3D plugin anymore.
  - Use new property to disable compilation of OS X related classes.
* debian/wrappers/electric
  - Add java3d related jar files to runtime classpath.
* debian/README.source
  - Change text to the appropriate one for quilt.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- tab-width: 4 -*-
2
 
 *
3
 
 * Electric(tm) VLSI Design System
4
 
 *
5
 
 * File: Highlight2.java
6
 
 *
7
 
 * Copyright (c) 2006 Sun Microsystems and Static Free Software
8
 
 *
9
 
 * Electric(tm) is free software; you can redistribute it and/or modify
10
 
 * it under the terms of the GNU General Public License as published by
11
 
 * the Free Software Foundation; either version 3 of the License, or
12
 
 * (at your option) any later version.
13
 
 *
14
 
 * Electric(tm) is distributed in the hope that it will be useful,
15
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 * GNU General Public License for more details.
18
 
 *
19
 
 * You should have received a copy of the GNU General Public License
20
 
 * along with Electric(tm); see the file COPYING.  If not, write to
21
 
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
 
 * Boston, Mass 02111-1307, USA.
23
 
 */
24
 
package com.sun.electric.tool.user;
25
 
 
26
 
import com.sun.electric.database.geometry.DBMath;
27
 
import com.sun.electric.database.geometry.GenMath;
28
 
import com.sun.electric.database.geometry.Poly;
29
 
import com.sun.electric.database.hierarchy.Cell;
30
 
import com.sun.electric.database.hierarchy.Export;
31
 
import com.sun.electric.database.hierarchy.Nodable;
32
 
import com.sun.electric.database.network.Netlist;
33
 
import com.sun.electric.database.network.Network;
34
 
import com.sun.electric.database.network.NetworkTool;
35
 
import com.sun.electric.database.prototype.PortProto;
36
 
import com.sun.electric.database.text.Name;
37
 
import com.sun.electric.database.topology.ArcInst;
38
 
import com.sun.electric.database.topology.Connection;
39
 
import com.sun.electric.database.topology.Geometric;
40
 
import com.sun.electric.database.topology.NodeInst;
41
 
import com.sun.electric.database.topology.PortInst;
42
 
import com.sun.electric.database.variable.DisplayedText;
43
 
import com.sun.electric.database.variable.ElectricObject;
44
 
import com.sun.electric.database.variable.Variable;
45
 
import com.sun.electric.technology.PrimitiveNode;
46
 
import com.sun.electric.technology.Technology;
47
 
import com.sun.electric.technology.technologies.Artwork;
48
 
import com.sun.electric.tool.Job;
49
 
import com.sun.electric.tool.user.ui.EditWindow;
50
 
import com.sun.electric.tool.user.ui.ToolBar;
51
 
 
52
 
import java.awt.BasicStroke;
53
 
import java.awt.Color;
54
 
import java.awt.Dimension;
55
 
import java.awt.Font;
56
 
import java.awt.Graphics;
57
 
import java.awt.Graphics2D;
58
 
import java.awt.Point;
59
 
import java.awt.Stroke;
60
 
import java.awt.font.FontRenderContext;
61
 
import java.awt.font.GlyphVector;
62
 
import java.awt.font.LineMetrics;
63
 
import java.awt.geom.AffineTransform;
64
 
import java.awt.geom.Point2D;
65
 
import java.awt.geom.Rectangle2D;
66
 
import java.util.HashSet;
67
 
import java.util.Iterator;
68
 
import java.util.List;
69
 
import java.util.Set;
70
 
 
71
 
/**
72
 
 * Super class for all types of highlighting.
73
 
 */
74
 
public abstract class Highlight2 implements Cloneable{
75
 
 
76
 
        /** for drawing solid lines */          public static final BasicStroke solidLine = new BasicStroke(0);
77
 
        /** for drawing dotted lines */         public static final BasicStroke dottedLine = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] {1}, 0);
78
 
        /** for drawing dashed lines */         public static final BasicStroke dashedLine = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, new float[] {10}, 0);
79
 
        /** for drawing dashed lines */         public static final BasicStroke boldLine = new BasicStroke(3);
80
 
 
81
 
        /** The Cell containing the selection. */       protected Cell cell;
82
 
        private static final int CROSSSIZE = 3;
83
 
 
84
 
        Highlight2(Cell c)
85
 
        {
86
 
                this.cell = c;
87
 
        }
88
 
 
89
 
        public Cell getCell() { return cell; }
90
 
 
91
 
        boolean isValid()
92
 
        {
93
 
                if (cell != null)
94
 
                        if (!cell.isLinked()) return false;
95
 
                return true;
96
 
        }
97
 
 
98
 
    // creating so HighlightEOBJ is not a public class
99
 
    public boolean isHighlightEOBJ() { return false; }
100
 
 
101
 
    // creating so HighlightText is not a public class
102
 
    public boolean isHighlightText() { return false; }
103
 
 
104
 
    public Object getObject() { return null; }
105
 
 
106
 
    public Variable.Key getVarKey() { return null; }
107
 
 
108
 
    // point variable, only useful for HighlightEOBJ?
109
 
    public void setPoint(int p) {;}
110
 
    public int getPoint() { return -1; }
111
 
 
112
 
    public Object clone()
113
 
    {
114
 
        try {
115
 
                        return super.clone();
116
 
                }
117
 
                catch (CloneNotSupportedException e) {
118
 
            e.printStackTrace();
119
 
                }
120
 
        return null;
121
 
    }
122
 
 
123
 
    /**
124
 
         * Method to tell whether two Highlights are the same.
125
 
         * @param obj the Highlight to compare to this one.
126
 
         * @return true if the two refer to the same thing.
127
 
         */
128
 
    boolean sameThing(Highlight2 obj)
129
 
    {
130
 
        return false;
131
 
    }
132
 
 
133
 
    /**
134
 
         * Method to tell whether this Highlight is text that stays with its node.
135
 
         * The two possibilities are (1) text on invisible pins
136
 
         * (2) export names, when the option to move exports with their labels is requested.
137
 
         * @return true if this Highlight is text that should move with its node.
138
 
         */
139
 
    public boolean nodeMovesWithText()
140
 
        {
141
 
                return false;
142
 
        }
143
 
 
144
 
    /**
145
 
         * Method to display this Highlight in a window.
146
 
         * @param wnd the window in which to draw this highlight.
147
 
         * @param g the Graphics associated with the window.
148
 
         */
149
 
        public void showHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY, boolean onlyHighlight,
150
 
                              Color mainColor, Stroke primaryStroke, boolean setConnected)
151
 
    {
152
 
        if (!isValid()) return;
153
 
                g.setColor(mainColor);
154
 
        Graphics2D g2 = (Graphics2D)g;
155
 
        g2.setStroke(primaryStroke);
156
 
        showInternalHighlight(wnd, g, highOffX, highOffY, onlyHighlight, setConnected);
157
 
    }
158
 
 
159
 
    abstract void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
160
 
                                        boolean onlyHighlight, boolean setConnected);
161
 
 
162
 
    /**
163
 
         * Method to populate a List of all highlighted Geometrics.
164
 
     * @param list the list to populate
165
 
         * @param wantNodes true if NodeInsts should be included in the list.
166
 
         * @param wantArcs true if ArcInsts should be included in the list.
167
 
         */
168
 
    void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs) {;}
169
 
 
170
 
    static void getHighlightedEObjsInternal(Geometric geom, List<Geometric> list, boolean wantNodes, boolean wantArcs)
171
 
    {
172
 
        if (geom == null) return;
173
 
        if (!wantNodes && geom instanceof NodeInst) return;
174
 
        if (!wantArcs && geom instanceof ArcInst) return;
175
 
 
176
 
        if (list.contains(geom)) return;
177
 
        list.add(geom);
178
 
    }
179
 
 
180
 
    /**
181
 
         * Method to return the Geometric object that is in this Highlight.
182
 
         * If the highlight is a PortInst, an Export, or annotation text, its base NodeInst is returned.
183
 
         * @return the Geometric object that is in this Highlight.
184
 
         * Returns null if this Highlight is not on a Geometric.
185
 
         */
186
 
    public Geometric getGeometric() { return null; }
187
 
 
188
 
    /**
189
 
         * Method to return a List of all highlighted NodeInsts.
190
 
         * Return a list with the highlighted NodeInsts.
191
 
         */
192
 
        void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list) {;}
193
 
 
194
 
    static void getHighlightedNodesInternal(Geometric geom, List<NodeInst> list)
195
 
    {
196
 
        if (geom == null || !(geom instanceof NodeInst)) return;
197
 
        NodeInst ni = (NodeInst)geom;
198
 
        if (list.contains(ni)) return;
199
 
        list.add(ni);
200
 
    }
201
 
 
202
 
    /**
203
 
         * Method to return a List of all highlighted ArcInsts.
204
 
         * Return a list with the highlighted ArcInsts.
205
 
         */
206
 
    void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list) {;}
207
 
 
208
 
    static void getHighlightedArcsInternal(Geometric geom, List<ArcInst> list)
209
 
    {
210
 
        if (geom == null || !(geom instanceof ArcInst)) return;
211
 
        ArcInst ai = (ArcInst)geom;
212
 
 
213
 
        if (list.contains(ai)) return;
214
 
        list.add(ai);
215
 
    }
216
 
 
217
 
    /**
218
 
         * Method to return a set of the currently selected networks.
219
 
         * Return a set of the currently selected networks.
220
 
         * If there are no selected networks, the list is empty.
221
 
         */
222
 
    void getHighlightedNetworks(Set<Network> nets, Netlist netlist) {;}
223
 
 
224
 
    /**
225
 
         * Method to return a List of all highlighted text.
226
 
     * @param list list to populate.
227
 
         * @param unique true to request that the text objects be unique,
228
 
         * and not attached to another object that is highlighted.
229
 
         * For example, if a node and an export on that node are selected,
230
 
         * the export text will not be included if "unique" is true.
231
 
         * Return a list with the Highlight objects that point to text.
232
 
         */
233
 
    void getHighlightedText(List<DisplayedText> list, boolean unique, List<Highlight2> getHighlights) {;}
234
 
 
235
 
    /**
236
 
         * Method to return the bounds of the highlighted objects.
237
 
         * @param wnd the window in which to get bounds.
238
 
         * @return the bounds of the highlighted objects (null if nothing is highlighted).
239
 
         */
240
 
    Rectangle2D getHighlightedArea(EditWindow wnd) { return null; }
241
 
 
242
 
    /**
243
 
         * Method to return the ElectricObject associated with this Highlight object.
244
 
         * @return the ElectricObject associated with this Highlight object.
245
 
         */
246
 
    public ElectricObject getElectricObject() { return null; }
247
 
 
248
 
    /**
249
 
         * Method to tell whether a point is over this Highlight.
250
 
         * @param wnd the window being examined.
251
 
         * @param x the X screen coordinate of the point.
252
 
         * @param y the Y screen coordinate of the point.
253
 
         * @return true if the point is over this Highlight.
254
 
         */
255
 
    boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter) { return false; }
256
 
 
257
 
    public String getInfo() { return null;}
258
 
 
259
 
    /**
260
 
     * Method to load an array of counts with the number of highlighted objects in a list.
261
 
     * arc = 0, node = 1, export = 2, text = 3, graphics = 4
262
 
     * @param list the list of highlighted objects.
263
 
     * @param counts the array of counts to set.
264
 
     * @return a NodeInst, if it is in the list.
265
 
     */
266
 
    public static NodeInst getInfoCommand(List<Highlight2> list, int[] counts)
267
 
    {
268
 
        // information about the selected items
269
 
        NodeInst theNode = null;
270
 
        for(Highlight2 h : list)
271
 
        {
272
 
            ElectricObject eobj = h.getElectricObject();
273
 
            if (h.isHighlightEOBJ())
274
 
            {
275
 
                if (eobj instanceof NodeInst || eobj instanceof PortInst)
276
 
                {
277
 
                    counts[1]++;
278
 
                    if (eobj instanceof NodeInst) theNode = (NodeInst)eobj; else
279
 
                        theNode = ((PortInst)eobj).getNodeInst();
280
 
                } else if (eobj instanceof ArcInst)
281
 
                {
282
 
                    counts[0]++;
283
 
                }
284
 
            } else if (h.isHighlightText())
285
 
            {
286
 
                if (h.getVarKey() == Export.EXPORT_NAME) counts[2]++; else
287
 
                {
288
 
                        if (h.getElectricObject() instanceof NodeInst)
289
 
                                theNode = (NodeInst)h.getElectricObject();
290
 
                    counts[3]++;
291
 
                }
292
 
            } else if (h instanceof HighlightArea)
293
 
            {
294
 
                counts[4]++;
295
 
            } else if (h instanceof HighlightLine)
296
 
            {
297
 
                counts[4]++;
298
 
            }
299
 
        }
300
 
        return theNode;
301
 
    }
302
 
 
303
 
    /**
304
 
         * Method to draw an array of points as highlighting.
305
 
         * @param wnd the window in which drawing is happening.
306
 
     * @param g the Graphics for the window.
307
 
     * @param points the array of points being drawn.
308
 
     * @param offX the X offset of the drawing.
309
 
     * @param offY the Y offset of the drawing.
310
 
     * @param opened true if the points are drawn "opened".
311
 
     * @param thickLine
312
 
     */
313
 
        public static void drawOutlineFromPoints(EditWindow wnd, Graphics g, Point2D[] points, int offX, int offY,
314
 
                                             boolean opened, boolean thickLine)
315
 
        {
316
 
                boolean onePoint = true;
317
 
                if (points.length <= 0)
318
 
                        return;
319
 
                Point firstP = wnd.databaseToScreen(points[0].getX(), points[0].getY());
320
 
                for(int i=1; i<points.length; i++)
321
 
                {
322
 
                        Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
323
 
                        if (DBMath.doublesEqual(p.getX(), firstP.getX()) &&
324
 
                                DBMath.doublesEqual(p.getY(), firstP.getY())) continue;
325
 
                        onePoint = false;
326
 
                        break;
327
 
                }
328
 
                if (onePoint)
329
 
                {
330
 
                        drawLine(g, wnd, firstP.x + offX-CROSSSIZE, firstP.y + offY, firstP.x + offX+CROSSSIZE, firstP.y + offY);
331
 
                        drawLine(g, wnd, firstP.x + offX, firstP.y + offY-CROSSSIZE, firstP.x + offX, firstP.y + offY+CROSSSIZE);
332
 
                        return;
333
 
                }
334
 
 
335
 
                // find the center
336
 
                int cX = 0, cY = 0;
337
 
//              if (thickCenter != null)
338
 
//              {
339
 
//                      Point lp = wnd.databaseToScreen(thickCenter.getX(), thickCenter.getY());
340
 
//                      cX = lp.x;
341
 
//                      cY = lp.y;
342
 
//              }
343
 
 
344
 
                for(int i=0; i<points.length; i++)
345
 
                {
346
 
                        int lastI = i-1;
347
 
                        if (lastI < 0)
348
 
                        {
349
 
                                if (opened) continue;
350
 
                                lastI = points.length - 1;
351
 
                        }
352
 
                        Point lp = wnd.databaseToScreen(points[lastI].getX(), points[lastI].getY());
353
 
                        Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
354
 
                        int fX = lp.x + offX;   int fY = lp.y + offY;
355
 
                        int tX = p.x + offX;    int tY = p.y + offY;
356
 
                        drawLine(g, wnd, fX, fY, tX, tY);
357
 
                        if (thickLine)
358
 
                        {
359
 
                                if (fX < cX) fX--; else fX++;
360
 
                                if (fY < cY) fY--; else fY++;
361
 
                                if (tX < cX) tX--; else tX++;
362
 
                                if (tY < cY) tY--; else tY++;
363
 
                                drawLine(g, wnd, fX, fY, tX, tY);
364
 
                        }
365
 
                }
366
 
        }
367
 
 
368
 
    void internalDescribe(StringBuffer desc) {;}
369
 
 
370
 
    /**
371
 
     * Describe the Highlight
372
 
     * @return a string describing the highlight
373
 
     */
374
 
    public String describe() {
375
 
        StringBuffer desc = new StringBuffer();
376
 
        desc.append(this.getClass().getName());
377
 
        if (cell != null)
378
 
        {
379
 
                desc.append(" in ");
380
 
                desc.append(cell);
381
 
        }
382
 
        desc.append(": ");
383
 
        internalDescribe(desc);
384
 
        return desc.toString();
385
 
    }
386
 
 
387
 
    /**
388
 
     * Gets a poly that describes the Highlight for the NodeInst.
389
 
     * @param ni the nodeinst to get a poly that will be used to highlight it
390
 
     * @return a poly outlining the nodeInst.
391
 
     */
392
 
    public static Poly getNodeInstOutline(NodeInst ni)
393
 
    {
394
 
        AffineTransform trans = ni.rotateOutAboutTrueCenter();
395
 
 
396
 
        Poly poly = null;
397
 
        if (!ni.isCellInstance())
398
 
        {
399
 
                PrimitiveNode pn = (PrimitiveNode)ni.getProto();
400
 
 
401
 
                // special case for outline nodes
402
 
            if (pn.isHoldsOutline())
403
 
            {
404
 
                Point2D [] outline = ni.getTrace();
405
 
                if (outline != null)
406
 
                {
407
 
                    int numPoints = outline.length;
408
 
                    boolean whole = true;
409
 
                    for(int i=1; i<numPoints; i++)
410
 
                    {
411
 
                        if (outline[i] == null)
412
 
                        {
413
 
                            whole = false;
414
 
                            break;
415
 
                        }
416
 
                    }
417
 
                                        if (whole)
418
 
                                        {
419
 
                            Point2D [] pointList = new Point2D.Double[numPoints];
420
 
                            for(int i=0; i<numPoints; i++)
421
 
                            {
422
 
                                pointList[i] = new Point2D.Double(ni.getAnchorCenterX() + outline[i].getX(),
423
 
                                    ni.getAnchorCenterY() + outline[i].getY());
424
 
                            }
425
 
                            trans.transform(pointList, 0, pointList, 0, numPoints);
426
 
                            poly = new Poly(pointList);
427
 
                                        if (ni.getFunction() == PrimitiveNode.Function.NODE)
428
 
                                        {
429
 
                                                poly.setStyle(Poly.Type.FILLED);
430
 
                                        } else
431
 
                                        {
432
 
                                                poly.setStyle(Poly.Type.OPENED);
433
 
                                        }
434
 
                                        return poly;
435
 
                                        }
436
 
                }
437
 
            }
438
 
 
439
 
            // special case for circular nodes
440
 
                if (pn == Artwork.tech().circleNode || pn == Artwork.tech().thickCircleNode)
441
 
                {
442
 
                        // see if this circle is only a partial one
443
 
                        double [] angles = ni.getArcDegrees();
444
 
                        if (angles[0] != 0.0 || angles[1] != 0.0)
445
 
                        {
446
 
                                Point2D [] pointList = Artwork.fillEllipse(ni.getAnchorCenter(), ni.getXSize(), ni.getYSize(), angles[0], angles[1]);
447
 
                                poly = new Poly(pointList);
448
 
                                poly.setStyle(Poly.Type.OPENED);
449
 
                                poly.transform(ni.rotateOut());
450
 
                        }
451
 
                }
452
 
        }
453
 
 
454
 
        // setup outline of node with standard offset
455
 
        if (poly == null)
456
 
            poly = ni.getBaseShape();
457
 
 
458
 
        return poly;
459
 
    }
460
 
 
461
 
    /**
462
 
     * Implementing clipping here speeds things up a lot if there are
463
 
     * many large highlights off-screen
464
 
     */
465
 
    public static void drawLine(Graphics g, EditWindow wnd, int x1, int y1, int x2, int y2)
466
 
    {
467
 
        Dimension size = wnd.getScreenSize();
468
 
                // first clip the line
469
 
        Point pt1 = new Point(x1, y1);
470
 
        Point pt2 = new Point(x2, y2);
471
 
                if (GenMath.clipLine(pt1, pt2, 0, size.width-1, 0, size.height-1)) return;
472
 
                g.drawLine(pt1.x, pt1.y, pt2.x, pt2.y);
473
 
//        if (((x1 >= 0) && (x1 <= size.getLambdaFullWidth())) || ((x2 >= 0) && (x2 <= size.getLambdaFullWidth())) ||
474
 
//            ((y1 >= 0) && (y1 <= size.getHeight())) || ((y2 >= 0) && (y2 <= size.getHeight()))) {
475
 
//                g.drawLine(x1, y1, x2, y2);
476
 
//        }
477
 
    }
478
 
}
479
 
 
480
 
class HighlightPoly extends Highlight2
481
 
{
482
 
    /** The highlighted polygon */                              private Poly polygon;
483
 
    /** The color used when drawing polygons */                 private Color color;
484
 
    HighlightPoly(Cell c, Poly p, Color col)
485
 
    {
486
 
        super(c);
487
 
        this.polygon = p;
488
 
        this.color = col;
489
 
    }
490
 
 
491
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
492
 
                                      boolean onlyHighlight, boolean setConnected)
493
 
    {
494
 
        // switch colors if specified
495
 
        Color oldColor = null;
496
 
        if (color != null)
497
 
        {
498
 
            oldColor = g.getColor();
499
 
            g.setColor(color);
500
 
        }
501
 
 
502
 
        // draw poly
503
 
        Point2D[] points = polygon.getPoints();
504
 
        if (polygon.getStyle() == Poly.Type.FILLED)
505
 
        {
506
 
                int [] xPoints = new int[points.length];
507
 
                int [] yPoints = new int[points.length];
508
 
                for(int i=0; i<points.length; i++)
509
 
                {
510
 
                        Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
511
 
                        xPoints[i] = p.x;
512
 
                        yPoints[i] = p.y;
513
 
                }
514
 
                        g.fillPolygon(xPoints, yPoints, points.length);
515
 
        } else
516
 
        {
517
 
                boolean opened = (polygon.getStyle() == Poly.Type.OPENED);
518
 
                drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, opened, false);
519
 
        }
520
 
 
521
 
        // switch back to old color if switched
522
 
        if (oldColor != null)
523
 
            g.setColor(oldColor);
524
 
    }
525
 
}
526
 
 
527
 
class HighlightLine extends Highlight2
528
 
{
529
 
        /** The highlighted line. */                                                            protected Point2D start, end, center;
530
 
    /** The highlighted line is thick. */                                           protected boolean thickLine;
531
 
    HighlightLine(Cell c, Point2D s, Point2D e, Point2D cen, boolean thick)
532
 
    {
533
 
        super(c);
534
 
        this.start = s;
535
 
        this.end = e;
536
 
        this.center = cen;
537
 
        this.thickLine = thick;
538
 
    }
539
 
 
540
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
541
 
                                      boolean onlyHighlight, boolean setConnected)
542
 
    {
543
 
        Point2D [] points = new Point2D.Double[2];
544
 
        points[0] = new Point2D.Double(start.getX(), start.getY());
545
 
        points[1] = new Point2D.Double(end.getX(), end.getY());
546
 
        drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, false, thickLine);
547
 
    }
548
 
 
549
 
    Rectangle2D getHighlightedArea(EditWindow wnd)
550
 
    {
551
 
        double cX = Math.min(start.getX(), end.getX());
552
 
        double cY = Math.min(start.getY(), end.getY());
553
 
        double sX = Math.abs(start.getX() - end.getX());
554
 
        double sY = Math.abs(start.getY() - end.getY());
555
 
                return new Rectangle2D.Double(cX, cY, sX, sY);
556
 
    }
557
 
 
558
 
    public String getInfo()
559
 
    {
560
 
        String description = "Line from (" + start.getX() + "," + start.getY() + ") to (" +
561
 
            end.getX() + "," + end.getY() + ")";
562
 
        return description;
563
 
    }
564
 
}
565
 
 
566
 
class HighlightObject extends Highlight2
567
 
{
568
 
        /** The highlighted generic object */                       private Object object;
569
 
    HighlightObject(Cell c, Object obj)
570
 
    {
571
 
        super(c);
572
 
        this.object = obj;
573
 
    }
574
 
 
575
 
    public Object getObject() { return object; }
576
 
 
577
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
578
 
                                      boolean onlyHighlight, boolean setConnected)
579
 
    {
580
 
        System.out.println("Should call this one?");
581
 
    }
582
 
}
583
 
 
584
 
class HighlightArea extends Highlight2
585
 
{
586
 
    /** The highlighted area. */                                                                protected Rectangle2D bounds;
587
 
    HighlightArea(Cell c, Rectangle2D area)
588
 
    {
589
 
        super(c);
590
 
                bounds = new Rectangle2D.Double();
591
 
                bounds.setRect(area);
592
 
    }
593
 
 
594
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
595
 
                                      boolean onlyHighlight, boolean setConnected)
596
 
    {
597
 
        Point2D [] points = new Point2D.Double[5];
598
 
        points[0] = new Point2D.Double(bounds.getMinX(), bounds.getMinY());
599
 
        points[1] = new Point2D.Double(bounds.getMinX(), bounds.getMaxY());
600
 
        points[2] = new Point2D.Double(bounds.getMaxX(), bounds.getMaxY());
601
 
        points[3] = new Point2D.Double(bounds.getMaxX(), bounds.getMinY());
602
 
        points[4] = new Point2D.Double(bounds.getMinX(), bounds.getMinY());
603
 
        drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, false, false);
604
 
    }
605
 
 
606
 
    void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
607
 
    {
608
 
        List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false, bounds, null);
609
 
        for(Highlight2 ah : inArea)
610
 
        {
611
 
            if (!(ah instanceof HighlightEOBJ)) continue;
612
 
            ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
613
 
            if (eobj instanceof ArcInst) {
614
 
                if (wantArcs)
615
 
                    list.add((ArcInst)eobj);
616
 
            } else if (eobj instanceof NodeInst) {
617
 
                if (wantNodes)
618
 
                    list.add((NodeInst)eobj);
619
 
            } else if (eobj instanceof PortInst) {
620
 
                if (wantNodes)
621
 
                    list.add(((PortInst)eobj).getNodeInst());
622
 
            }
623
 
//                                      if (!wantNodes)
624
 
//                                      {
625
 
//                                              if (eobj instanceof NodeInst || eobj instanceof PortInst) continue;
626
 
//                                      }
627
 
//                                      if (!wantArcs && eobj instanceof ArcInst) continue;
628
 
//                                      if (eobj instanceof PortInst) eobj = ((PortInst)eobj).getNodeInst();
629
 
//                                      highlightedGeoms.add(eobj);
630
 
        }
631
 
    }
632
 
 
633
 
    void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
634
 
    {
635
 
        List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false,
636
 
                bounds, null);
637
 
        for(Highlight2 ah : inArea)
638
 
        {
639
 
            if (!(ah instanceof HighlightEOBJ)) continue;
640
 
            ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
641
 
            if (eobj instanceof NodeInst)
642
 
                list.add((NodeInst)eobj);
643
 
            else if (eobj instanceof PortInst)
644
 
                list.add(((PortInst)eobj).getNodeInst());
645
 
        }
646
 
    }
647
 
 
648
 
    void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
649
 
    {
650
 
        List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false,
651
 
                bounds, null);
652
 
        for(Highlight2 ah : inArea)
653
 
        {
654
 
            if (!(ah instanceof HighlightEOBJ)) continue;
655
 
            ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
656
 
            if (eobj instanceof ArcInst)
657
 
                list.add((ArcInst)eobj);
658
 
        }
659
 
    }
660
 
 
661
 
    Rectangle2D getHighlightedArea(EditWindow wnd)
662
 
    {
663
 
        return bounds;
664
 
    }
665
 
 
666
 
    public String getInfo()
667
 
    {
668
 
        String description = "Area from " + bounds.getMinX() + "<=X<=" + bounds.getMaxX() +
669
 
            " and " + bounds.getMinY() + "<=Y<=" + bounds.getMaxY();
670
 
        return description;
671
 
    }
672
 
}
673
 
 
674
 
class HighlightMessage extends Highlight2
675
 
{
676
 
        /** The highlighted message. */                                                         protected String msg;
677
 
    /** Location of the message highlight */                    protected Point2D loc;
678
 
    /** Corner of text: 0=lowerLeft, 1=upperLeft, 2=upperRight, 3=lowerRight */ protected int corner;
679
 
 
680
 
    HighlightMessage(Cell c, String m, Point2D p, int co)
681
 
    {
682
 
        super(c);
683
 
        this.msg = m;
684
 
        this.loc = p;
685
 
        this.corner = co;
686
 
    }
687
 
 
688
 
    void internalDescribe(StringBuffer desc)
689
 
    {
690
 
        desc.append(", ");
691
 
        desc.append(msg);
692
 
    }
693
 
 
694
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
695
 
                                      boolean onlyHighlight, boolean setConnected)
696
 
    {
697
 
        Point location = wnd.databaseToScreen(loc.getX(), loc.getY());
698
 
        if (corner != 0)
699
 
        {
700
 
                // determine the size of the text
701
 
                        Font font = g.getFont();
702
 
                        FontRenderContext frc = new FontRenderContext(null, true, true);
703
 
                        GlyphVector gv = font.createGlyphVector(frc, msg);
704
 
                        LineMetrics lm = font.getLineMetrics(msg, frc);
705
 
                        Rectangle2D rasRect = gv.getLogicalBounds();
706
 
                        int width = (int)rasRect.getWidth();
707
 
                        int height = (int)(lm.getHeight()+0.5);
708
 
                switch (corner)
709
 
                {
710
 
                        case 1:         // put upper-left corner of text at drawing coordinate
711
 
                                location.y += height;
712
 
                                break;
713
 
                        case 2:         // put upper-right corner of text at drawing coordinate
714
 
                                location.y += height;
715
 
                                location.x -= width;
716
 
                                break;
717
 
                        case 3:         // put lower-right corner of text at drawing coordinate
718
 
                                location.y += height;
719
 
                                location.x -= width;
720
 
                                break;
721
 
                }
722
 
        }
723
 
        Color oldColor = g.getColor();
724
 
        g.setColor(new Color(255-oldColor.getRed(), 255-oldColor.getGreen(), 255-oldColor.getBlue()));
725
 
        g.drawString(msg, location.x+1, location.y+1);
726
 
        g.setColor(oldColor);
727
 
        g.drawString(msg, location.x, location.y);
728
 
    }
729
 
 
730
 
    Rectangle2D getHighlightedArea(EditWindow wnd)
731
 
    {
732
 
        return new Rectangle2D.Double(loc.getX(), loc.getY(), 0, 0);
733
 
    }
734
 
}
735
 
 
736
 
class HighlightEOBJ extends Highlight2
737
 
{
738
 
        /** The highlighted object. */                                                          protected ElectricObject eobj;
739
 
        /** For Highlighted networks, this prevents excess highlights */ private boolean highlightConnected;
740
 
        /** The highlighted outline point (only for NodeInst). */       protected int point;
741
 
        /** The color used when drawing polygons */                                     private Color color;
742
 
 
743
 
        public HighlightEOBJ(ElectricObject e, Cell c, boolean connected, int p)
744
 
        {
745
 
                super(c);
746
 
                this.eobj = e;
747
 
                this.highlightConnected = connected;
748
 
                this.point = p;
749
 
                this.color = null;
750
 
        }
751
 
 
752
 
        public HighlightEOBJ(ElectricObject e, Cell c, boolean connected, int p, Color col)
753
 
        {
754
 
                super(c);
755
 
                this.eobj = e;
756
 
                this.highlightConnected = connected;
757
 
                this.point = p;
758
 
                this.color = col;
759
 
        }
760
 
 
761
 
        void internalDescribe(StringBuffer desc)
762
 
        {
763
 
                desc.append(", ");
764
 
                if (eobj instanceof PortInst) {
765
 
                        desc.append(((PortInst)eobj).describe(true));
766
 
                }
767
 
                if (eobj instanceof NodeInst) {
768
 
                        desc.append(((NodeInst)eobj).describe(true));
769
 
                }
770
 
                if (eobj instanceof ArcInst) {
771
 
                        desc.append(((ArcInst)eobj).describe(true));
772
 
                }
773
 
        }
774
 
 
775
 
        public ElectricObject getElectricObject() { return eobj; }
776
 
 
777
 
        public boolean isHighlightEOBJ() { return true; }
778
 
 
779
 
        public void setPoint(int p) { point = p;}
780
 
        public int getPoint() { return point; }
781
 
 
782
 
        boolean isValid()
783
 
        {
784
 
                if (!super.isValid()) return false;
785
 
 
786
 
                if (eobj instanceof PortInst)
787
 
                        return ((PortInst)eobj).getNodeInst().isLinked();
788
 
                return eobj.isLinked();
789
 
        }
790
 
 
791
 
        boolean sameThing(Highlight2 obj)
792
 
        {
793
 
                if (this == obj) return (true);
794
 
 
795
 
                // Consider already obj==null
796
 
            if (obj == null || getClass() != obj.getClass())
797
 
            return (false);
798
 
 
799
 
        ElectricObject realEObj = eobj;
800
 
        if (realEObj instanceof PortInst) realEObj = ((PortInst)realEObj).getNodeInst();
801
 
 
802
 
        HighlightEOBJ other = (HighlightEOBJ)obj;
803
 
        ElectricObject realOtherEObj = other.eobj;
804
 
        if (realOtherEObj instanceof PortInst) realOtherEObj = ((PortInst)realOtherEObj).getNodeInst();
805
 
        if (realEObj != realOtherEObj) return false;
806
 
        return true;
807
 
    }
808
 
 
809
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
810
 
                                      boolean onlyHighlight, boolean setConnected)
811
 
    {
812
 
        Graphics2D g2 = (Graphics2D)g;
813
 
        highlightConnected = setConnected;
814
 
 
815
 
                // switch colors if specified
816
 
        Color oldColor = null;
817
 
        if (color != null)
818
 
        {
819
 
            oldColor = g.getColor();
820
 
            g.setColor(color);
821
 
        }
822
 
 
823
 
        // highlight ArcInst
824
 
                if (eobj instanceof ArcInst)
825
 
                {
826
 
                        ArcInst ai = (ArcInst)eobj;
827
 
 
828
 
//            if (!Job.acquireExamineLock(false)) return;
829
 
            try {
830
 
                // construct the polygons that describe the basic arc
831
 
                Poly poly = ai.makeLambdaPoly(ai.getGridBaseWidth(), Poly.Type.CLOSED);
832
 
                if (poly == null) return;
833
 
                drawOutlineFromPoints(wnd, g, poly.getPoints(), highOffX, highOffY, false, false);
834
 
 
835
 
                if (onlyHighlight)
836
 
                {
837
 
                    // this is the only thing highlighted: give more information about constraints
838
 
                    String constraints = "X";
839
 
                    if (ai.isRigid()) constraints = "R"; else
840
 
                    {
841
 
                        if (ai.isFixedAngle())
842
 
                        {
843
 
                            if (ai.isSlidable()) constraints = "FS"; else
844
 
                                constraints = "F";
845
 
                        } else if (ai.isSlidable()) constraints = "S";
846
 
                    }
847
 
                    Point p = wnd.databaseToScreen(ai.getTrueCenterX(), ai.getTrueCenterY());
848
 
                    Font font = wnd.getFont(null);
849
 
                    if (font != null)
850
 
                    {
851
 
                        GlyphVector gv = wnd.getGlyphs(constraints, font);
852
 
                        Rectangle2D glyphBounds = gv.getVisualBounds();
853
 
                        g.drawString(constraints, (int)(p.x - glyphBounds.getWidth()/2 + highOffX),
854
 
                            p.y + font.getSize()/2 + highOffY);
855
 
                    }
856
 
                }
857
 
//                Job.releaseExamineLock();
858
 
            } catch (Error e) {
859
 
//                Job.releaseExamineLock();
860
 
                throw e;
861
 
            }
862
 
                        return;
863
 
                }
864
 
 
865
 
                // highlight NodeInst
866
 
                PortProto pp = null;
867
 
                ElectricObject realEObj = eobj;
868
 
        PortInst originalPi = null;
869
 
        if (realEObj instanceof PortInst)
870
 
                {
871
 
            originalPi = ((PortInst)realEObj);
872
 
            pp = originalPi.getPortProto();
873
 
                        realEObj = ((PortInst)realEObj).getNodeInst();
874
 
                }
875
 
                if (realEObj instanceof NodeInst)
876
 
                {
877
 
                        NodeInst ni = (NodeInst)realEObj;
878
 
                        AffineTransform trans = ni.rotateOutAboutTrueCenter();
879
 
 
880
 
            int offX = highOffX;
881
 
            int offY = highOffY;
882
 
/*
883
 
                        boolean drewOutline = false;
884
 
                        if (!ni.isCellInstance())
885
 
                        {
886
 
                                // special case for outline nodes
887
 
                                if (np.isHoldsOutline())
888
 
                                {
889
 
                                        Point2D [] outline = ni.getTrace();
890
 
                                        if (outline != null)
891
 
                                        {
892
 
                                                int numPoints = outline.length;
893
 
                                                Point2D [] pointList = new Point2D.Double[numPoints];
894
 
                                                for(int i=0; i<numPoints; i++)
895
 
                                                {
896
 
                                                        pointList[i] = new Point2D.Double(ni.getTrueCenterX() + outline[i].getX(),
897
 
                                                                ni.getTrueCenterY() + outline[i].getY());
898
 
                                                }
899
 
                                                trans.transform(pointList, 0, pointList, 0, numPoints);
900
 
                                                drawOutlineFromPoints(wnd, g, pointList, 0, 0, true, null);
901
 
                                                drewOutline = true;
902
 
                                        }
903
 
                                }
904
 
                        }
905
 
 
906
 
                        // setup outline of node with standard offset
907
 
                        if (!drewOutline)
908
 
                        {
909
 
                                SizeOffset so = ni.getSizeOffset();
910
 
                                double nodeLowX = ni.getTrueCenterX() - ni.getXSize()/2 + so.getLowXOffset();
911
 
                                double nodeHighX = ni.getTrueCenterX() + ni.getXSize()/2 - so.getHighXOffset();
912
 
                                double nodeLowY = ni.getTrueCenterY() - ni.getYSize()/2 + so.getLowYOffset();
913
 
                                double nodeHighY = ni.getTrueCenterY() + ni.getYSize()/2 - so.getHighYOffset();
914
 
                                if (nodeLowX == nodeHighX && nodeLowY == nodeHighY)
915
 
                                {
916
 
                                        float x = (float)nodeLowX;
917
 
                                        float y = (float)nodeLowY;
918
 
                                        float size = 3 / (float)wnd.getScale();
919
 
                                        Point c1 = wnd.databaseToScreen(x+size, y);
920
 
                                        Point c2 = wnd.databaseToScreen(x-size, y);
921
 
                                        Point c3 = wnd.databaseToScreen(x, y+size);
922
 
                                        Point c4 = wnd.databaseToScreen(x, y-size);
923
 
                                        drawLine(g, wnd, c1.x + offX, c1.y + offY, c2.x + offX, c2.y + offY);
924
 
                                        drawLine(g, wnd, c3.x + offX, c3.y + offY, c4.x + offX, c4.y + offY);
925
 
                                } else
926
 
                                {
927
 
                                        double nodeX = (nodeLowX + nodeHighX) / 2;
928
 
                                        double nodeY = (nodeLowY + nodeHighY) / 2;
929
 
                                        Poly poly = new Poly(nodeX, nodeY, nodeHighX-nodeLowX, nodeHighY-nodeLowY);
930
 
                                        poly.transform(trans);
931
 
                                        drawOutlineFromPoints(wnd, g, poly.getPoints(), offX, offY, false, null);
932
 
                                }
933
 
                        }
934
 
*/
935
 
 
936
 
                        // draw the selected point
937
 
                        if (point >= 0)
938
 
                        {
939
 
                                Point2D [] points = ni.getTrace();
940
 
                                if (points != null)
941
 
                                {
942
 
                                        // if this is a spline, highlight the true shape
943
 
                                        if (ni.getProto() == Artwork.tech().splineNode)
944
 
                                        {
945
 
                                                Point2D [] changedPoints = new Point2D[points.length];
946
 
                                                for(int i=0; i<points.length; i++)
947
 
                                                {
948
 
                                                        changedPoints[i] = points[i];
949
 
                                                        if (i == point)
950
 
                                                        {
951
 
                                                                double x = ni.getAnchorCenterX() + points[point].getX();
952
 
                                                                double y = ni.getAnchorCenterY() + points[point].getY();
953
 
                                                                Point2D thisPt = new Point2D.Double(x, y);
954
 
                                                                trans.transform(thisPt, thisPt);
955
 
                                                                Point cThis = wnd.databaseToScreen(thisPt);
956
 
                                                                Point2D db = wnd.screenToDatabase(cThis.x+offX, cThis.y+offY);
957
 
                                                                changedPoints[i] = new Point2D.Double(db.getX() - ni.getAnchorCenterX(), db.getY() - ni.getAnchorCenterY());
958
 
                                                        }
959
 
                                                }
960
 
                                                Point2D [] spPoints = Artwork.tech().fillSpline(ni.getAnchorCenterX(), ni.getAnchorCenterY(), changedPoints);
961
 
                                                Point cLast = wnd.databaseToScreen(spPoints[0]);
962
 
                                                for(int i=1; i<spPoints.length; i++)
963
 
                                                {
964
 
                                                        Point cThis = wnd.databaseToScreen(spPoints[i]);
965
 
                                                        drawLine(g, wnd, cLast.x, cLast.y, cThis.x, cThis.y);
966
 
                                                        cLast = cThis;
967
 
                                                }
968
 
                                        }
969
 
 
970
 
                                        // draw an "x" through the selected point
971
 
                                        if (points[point] != null)
972
 
                                        {
973
 
                                                double x = ni.getAnchorCenterX() + points[point].getX();
974
 
                                                double y = ni.getAnchorCenterY() + points[point].getY();
975
 
                                                Point2D thisPt = new Point2D.Double(x, y);
976
 
                                                trans.transform(thisPt, thisPt);
977
 
                                                Point cThis = wnd.databaseToScreen(thisPt);
978
 
                                                int size = 3;
979
 
                                                drawLine(g, wnd, cThis.x + size + offX, cThis.y + size + offY, cThis.x - size + offX, cThis.y - size + offY);
980
 
                                                drawLine(g, wnd, cThis.x + size + offX, cThis.y - size + offY, cThis.x - size + offX, cThis.y + size + offY);
981
 
 
982
 
                                                // find previous and next point, and draw lines to them
983
 
                                                boolean showWrap = ni.traceWraps();
984
 
                                                Point2D prevPt = null, nextPt = null;
985
 
                                                int prevPoint = point - 1;
986
 
                                                if (prevPoint < 0 && showWrap) prevPoint = points.length - 1;
987
 
                                                if (prevPoint >= 0 && points[prevPoint] != null)
988
 
                                                {
989
 
                                                        prevPt = new Point2D.Double(ni.getAnchorCenterX() + points[prevPoint].getX(),
990
 
                                                                ni.getAnchorCenterY() + points[prevPoint].getY());
991
 
                                                        trans.transform(prevPt, prevPt);
992
 
                                                        if (prevPt.getX() == thisPt.getX() && prevPt.getY() == thisPt.getY()) prevPoint = -1; else
993
 
                                                        {
994
 
                                                                Point cPrev = wnd.databaseToScreen(prevPt);
995
 
                                                                drawLine(g, wnd, cThis.x + offX, cThis.y + offY, cPrev.x, cPrev.y);
996
 
                                                        }
997
 
                                                }
998
 
                                                int nextPoint = point + 1;
999
 
                                                if (nextPoint >= points.length)
1000
 
                                                {
1001
 
                                                        if (showWrap) nextPoint = 0; else
1002
 
                                                                nextPoint = -1;
1003
 
                                                }
1004
 
                                                if (nextPoint >= 0 && points[nextPoint] != null)
1005
 
                                                {
1006
 
                                                        nextPt = new Point2D.Double(ni.getAnchorCenterX() + points[nextPoint].getX(),
1007
 
                                                                ni.getAnchorCenterY() + points[nextPoint].getY());
1008
 
                                                        trans.transform(nextPt, nextPt);
1009
 
                                                        if (nextPt.getX() == thisPt.getX() && nextPt.getY() == thisPt.getY()) nextPoint = -1; else
1010
 
                                                        {
1011
 
                                                                Point cNext = wnd.databaseToScreen(nextPt);
1012
 
                                                                drawLine(g, wnd, cThis.x + offX, cThis.y + offY, cNext.x, cNext.y);
1013
 
                                                        }
1014
 
                                                }
1015
 
 
1016
 
                                                // draw arrows on the lines
1017
 
                                                if (offX == 0 && offY == 0 && points.length > 2 && prevPt != null && nextPt != null)
1018
 
                                                {
1019
 
                                                        double arrowLen = Double.MAX_VALUE;
1020
 
                                                        if (prevPoint >= 0) arrowLen = Math.min(thisPt.distance(prevPt), arrowLen);
1021
 
                                                        if (nextPoint >= 0) arrowLen = Math.min(thisPt.distance(nextPt), arrowLen);
1022
 
                                                        arrowLen /= 10;
1023
 
                                                        double angleOfArrow = Math.PI * 0.8;
1024
 
                                                        if (prevPoint >= 0)
1025
 
                                                        {
1026
 
                                                                Point2D prevCtr = new Point2D.Double((prevPt.getX()+thisPt.getX()) / 2,
1027
 
                                                                        (prevPt.getY()+thisPt.getY()) / 2);
1028
 
                                                                double prevAngle = DBMath.figureAngleRadians(prevPt, thisPt);
1029
 
                                                                Point2D prevArrow1 = new Point2D.Double(prevCtr.getX() + Math.cos(prevAngle+angleOfArrow) * arrowLen,
1030
 
                                                                        prevCtr.getY() + Math.sin(prevAngle+angleOfArrow) * arrowLen);
1031
 
                                                                Point2D prevArrow2 = new Point2D.Double(prevCtr.getX() + Math.cos(prevAngle-angleOfArrow) * arrowLen,
1032
 
                                                                        prevCtr.getY() + Math.sin(prevAngle-angleOfArrow) * arrowLen);
1033
 
                                                                Point cPrevCtr = wnd.databaseToScreen(prevCtr);
1034
 
                                                                Point cPrevArrow1 = wnd.databaseToScreen(prevArrow1);
1035
 
                                                                Point cPrevArrow2 = wnd.databaseToScreen(prevArrow2);
1036
 
                                                                drawLine(g, wnd, cPrevCtr.x, cPrevCtr.y, cPrevArrow1.x, cPrevArrow1.y);
1037
 
                                                                drawLine(g, wnd, cPrevCtr.x, cPrevCtr.y, cPrevArrow2.x, cPrevArrow2.y);
1038
 
                                                        }
1039
 
 
1040
 
                                                        if (nextPoint >= 0)
1041
 
                                                        {
1042
 
                                                                Point2D nextCtr = new Point2D.Double((nextPt.getX()+thisPt.getX()) / 2,
1043
 
                                                                        (nextPt.getY()+thisPt.getY()) / 2);
1044
 
                                                                double nextAngle = DBMath.figureAngleRadians(thisPt, nextPt);
1045
 
                                                                Point2D nextArrow1 = new Point2D.Double(nextCtr.getX() + Math.cos(nextAngle+angleOfArrow) * arrowLen,
1046
 
                                                                        nextCtr.getY() + Math.sin(nextAngle+angleOfArrow) * arrowLen);
1047
 
                                                                Point2D nextArrow2 = new Point2D.Double(nextCtr.getX() + Math.cos(nextAngle-angleOfArrow) * arrowLen,
1048
 
                                                                        nextCtr.getY() + Math.sin(nextAngle-angleOfArrow) * arrowLen);
1049
 
                                                                Point cNextCtr = wnd.databaseToScreen(nextCtr);
1050
 
                                                                Point cNextArrow1 = wnd.databaseToScreen(nextArrow1);
1051
 
                                                                Point cNextArrow2 = wnd.databaseToScreen(nextArrow2);
1052
 
                                                                drawLine(g, wnd, cNextCtr.x, cNextCtr.y, cNextArrow1.x, cNextArrow1.y);
1053
 
                                                                drawLine(g, wnd, cNextCtr.x, cNextCtr.y, cNextArrow2.x, cNextArrow2.y);
1054
 
                                                        }
1055
 
                                                }
1056
 
                                        }
1057
 
 
1058
 
                                        // do not offset the node, just this point
1059
 
                                        offX = offY = 0;
1060
 
                                }
1061
 
                        }
1062
 
 
1063
 
            // draw nodeInst outline
1064
 
            if ((offX == 0 && offY == 0) || point < 0)
1065
 
            {
1066
 
                Poly niPoly = getNodeInstOutline(ni);
1067
 
                boolean niOpened = (niPoly.getStyle() == Poly.Type.OPENED);
1068
 
                Point2D [] points = niPoly.getPoints();
1069
 
                drawOutlineFromPoints(wnd, g, points, offX, offY, niOpened, false);
1070
 
            }
1071
 
 
1072
 
                        // draw the selected port
1073
 
                        if (pp != null)
1074
 
                        {
1075
 
                //@TODO MAYBE I need the main color
1076
 
//                              g.setColor(mainColor);
1077
 
                                Poly poly = ni.getShapeOfPort(pp);
1078
 
                                boolean opened = true;
1079
 
                                Point2D [] points = poly.getPoints();
1080
 
                                if (poly.getStyle() == Poly.Type.FILLED || poly.getStyle() == Poly.Type.CLOSED) opened = false;
1081
 
                                if (poly.getStyle() == Poly.Type.CIRCLE || poly.getStyle() == Poly.Type.THICKCIRCLE ||
1082
 
                                        poly.getStyle() == Poly.Type.DISC)
1083
 
                                {
1084
 
                                        double sX = points[0].distance(points[1]) * 2;
1085
 
                                        Point2D [] pts = Artwork.fillEllipse(points[0], sX, sX, 0, 360);
1086
 
                                        poly = new Poly(pts);
1087
 
                                        poly.transform(ni.rotateOut());
1088
 
                                        points = poly.getPoints();
1089
 
                                } else if (poly.getStyle() == Poly.Type.CIRCLEARC)
1090
 
                                {
1091
 
                                        double [] angles = ni.getArcDegrees();
1092
 
                                        double sX = points[0].distance(points[1]) * 2;
1093
 
                                        Point2D [] pts = Artwork.fillEllipse(points[0], sX, sX, angles[0], angles[1]);
1094
 
                                        poly = new Poly(pts);
1095
 
                                        poly.transform(ni.rotateOut());
1096
 
                                        points = poly.getPoints();
1097
 
                                }
1098
 
                                drawOutlineFromPoints(wnd, g, points, offX, offY, opened, false);
1099
 
//                              g.setColor(mainColor);
1100
 
 
1101
 
                // show name of port
1102
 
                if (ni.isCellInstance() && (g instanceof Graphics2D))
1103
 
                                {
1104
 
                                        // only show name if port is wired (because all other situations already show the port)
1105
 
                                        boolean wired = false;
1106
 
                                        for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); )
1107
 
                                        {
1108
 
                                                Connection con = cIt.next();
1109
 
                                                if (con.getPortInst().getPortProto() == pp) { wired = true;   break; }
1110
 
                                        }
1111
 
                                        if (wired)
1112
 
                                        {
1113
 
                            Font font = new Font(User.getDefaultFont(), Font.PLAIN, (int)(1.5*EditWindow.getDefaultFontSize()));
1114
 
                        GlyphVector v = wnd.getGlyphs(pp.getName(), font);
1115
 
                            Point2D point = wnd.databaseToScreen(poly.getCenterX(), poly.getCenterY());
1116
 
                        ((Graphics2D)g).drawGlyphVector(v, (float)point.getX()+offX, (float)point.getY()+offY);
1117
 
                                        }
1118
 
                }
1119
 
 
1120
 
                // if this is a port on an "example icon", show the equivalent port in the cell
1121
 
//                if (ni.isIconOfParent())
1122
 
//                {
1123
 
//                      // find export in parent
1124
 
//                      Export equiv = (Export)cell.findPortProto(pp.getName());
1125
 
//                      if (equiv != null)
1126
 
//                      {
1127
 
//                              PortInst ePi = equiv.getOriginalPort();
1128
 
//                              Poly ePoly = ePi.getPoly();
1129
 
//                                              Point eP = wnd.databaseToScreen(ePoly.getCenterX(), ePoly.getCenterY());
1130
 
//                                              Point p = wnd.databaseToScreen(poly.getCenterX(), poly.getCenterY());
1131
 
//                                              drawLine(g, wnd, eP.x, eP.y, p.x + offX, p.y + offY);
1132
 
//                      }
1133
 
//                }
1134
 
 
1135
 
                // highlight objects that are electrically connected to this object
1136
 
                // unless specified not to. HighlightConnected is set to false by addNetwork when
1137
 
                // it figures out what's connected and adds them manually. Because they are added
1138
 
                // in addNetwork, we shouldn't try and add connected objects here.
1139
 
                if (highlightConnected && onlyHighlight) {
1140
 
                    Netlist netlist = cell.acquireUserNetlist();
1141
 
                                        if (netlist == null) return;
1142
 
                                        NodeInst originalNI = ni;
1143
 
                            if (ni.isIconOfParent())
1144
 
                            {
1145
 
                                // find export in parent
1146
 
                                Export equiv = (Export)cell.findPortProto(pp.getName());
1147
 
                                if (equiv != null)
1148
 
                                                {
1149
 
                                        originalPi = equiv.getOriginalPort();
1150
 
                                                        ni = originalPi.getNodeInst();
1151
 
                                                        pp = originalPi.getPortProto();
1152
 
                                                }
1153
 
                            }
1154
 
                    Set<Network> networks = new HashSet<Network>();
1155
 
                    networks = NetworkTool.getNetworksOnPort(originalPi, netlist, networks);
1156
 
 
1157
 
                    HashSet<Geometric> markObj = new HashSet<Geometric>();
1158
 
                    for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
1159
 
                    {
1160
 
                        ArcInst ai = it.next();
1161
 
                        Name arcName = ai.getNameKey();
1162
 
                        for (int i=0; i<arcName.busWidth(); i++) {
1163
 
                            if (networks.contains(netlist.getNetwork(ai, i))) {
1164
 
                                markObj.add(ai);
1165
 
                                markObj.add(ai.getHeadPortInst().getNodeInst());
1166
 
                                markObj.add(ai.getTailPortInst().getNodeInst());
1167
 
                                break;
1168
 
                            }
1169
 
                        }
1170
 
                    }
1171
 
 
1172
 
                    for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) {
1173
 
                        Nodable no = it.next();
1174
 
                        NodeInst oNi = no.getNodeInst();
1175
 
                        if (oNi == originalNI) continue;
1176
 
                        if (markObj.contains(ni)) continue;
1177
 
 
1178
 
                        boolean highlightNo = false;
1179
 
                        for(Iterator<PortProto> eIt = no.getProto().getPorts(); eIt.hasNext(); )
1180
 
                        {
1181
 
                            PortProto oPp = eIt.next();
1182
 
                            Name opName = oPp.getNameKey();
1183
 
                            for (int j=0; j<opName.busWidth(); j++) {
1184
 
                                if (networks.contains(netlist.getNetwork(no, oPp, j))) {
1185
 
                                    highlightNo = true;
1186
 
                                    break;
1187
 
                                }
1188
 
                            }
1189
 
                            if (highlightNo) break;
1190
 
                        }
1191
 
                        if (highlightNo)
1192
 
                            markObj.add(oNi);
1193
 
                    }
1194
 
                    //System.out.println("Search took "+com.sun.electric.database.text.TextUtils.getElapsedTime(System.currentTimeMillis()-start));
1195
 
 
1196
 
                    // draw lines along all of the arcs on the network
1197
 
                    Stroke origStroke = g2.getStroke();
1198
 
                    g2.setStroke(dashedLine);
1199
 
                    for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
1200
 
                    {
1201
 
                        ArcInst ai = it.next();
1202
 
                        if (!markObj.contains(ai)) continue;
1203
 
                        Point c1 = wnd.databaseToScreen(ai.getHeadLocation());
1204
 
                        Point c2 = wnd.databaseToScreen(ai.getTailLocation());
1205
 
                        drawLine(g, wnd, c1.x, c1.y, c2.x, c2.y);
1206
 
                    }
1207
 
 
1208
 
                    // draw dots in all connected nodes
1209
 
                    g2.setStroke(solidLine);
1210
 
                    for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )
1211
 
                    {
1212
 
                        NodeInst oNi = it.next();
1213
 
                        if (!markObj.contains(oNi)) continue;
1214
 
 
1215
 
                        Point c = wnd.databaseToScreen(oNi.getTrueCenter());
1216
 
                        g.fillOval(c.x-4, c.y-4, 8, 8);
1217
 
 
1218
 
                        // connect the center dots to the input arcs
1219
 
                        Point2D nodeCenter = oNi.getTrueCenter();
1220
 
                        for(Iterator<Connection> pIt = oNi.getConnections(); pIt.hasNext(); )
1221
 
                        {
1222
 
                            Connection con = pIt.next();
1223
 
                            ArcInst ai = con.getArc();
1224
 
                            if (!markObj.contains(ai)) continue;
1225
 
                            Point2D arcEnd = con.getLocation();
1226
 
                            if (arcEnd.getX() != nodeCenter.getX() || arcEnd.getY() != nodeCenter.getY())
1227
 
                            {
1228
 
                                Point c1 = wnd.databaseToScreen(arcEnd);
1229
 
                                Point c2 = wnd.databaseToScreen(nodeCenter);
1230
 
                                //g2.setStroke(dottedLine);
1231
 
                                //if (c1.distance(c2) < 15) g2.setStroke(solidLine);
1232
 
                                drawLine(g, wnd, c1.x, c1.y, c2.x, c2.y);
1233
 
                            }
1234
 
                        }
1235
 
                    }
1236
 
                    g2.setStroke(origStroke);
1237
 
                }
1238
 
                        }
1239
 
                }
1240
 
 
1241
 
                // switch back to old color if switched
1242
 
                if (oldColor != null)
1243
 
                        g.setColor(oldColor);
1244
 
        }
1245
 
 
1246
 
        void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
1247
 
    {
1248
 
        getHighlightedEObjsInternal(getGeometric(), list, wantNodes, wantArcs);
1249
 
    }
1250
 
 
1251
 
    void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
1252
 
    {
1253
 
        getHighlightedNodesInternal(getGeometric(), list);
1254
 
    }
1255
 
 
1256
 
    void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
1257
 
    {
1258
 
        getHighlightedArcsInternal(getGeometric(), list);
1259
 
    }
1260
 
 
1261
 
    void getHighlightedNetworks(Set<Network> nets, Netlist netlist)
1262
 
    {
1263
 
        ElectricObject eObj = eobj;
1264
 
        if (eObj instanceof NodeInst)
1265
 
        {
1266
 
            NodeInst ni = (NodeInst)eObj;
1267
 
            if (ni.getNumPortInsts() == 1)
1268
 
            {
1269
 
                PortInst pi = ni.getOnlyPortInst();
1270
 
                if (pi != null) eObj = pi;
1271
 
            }
1272
 
        }
1273
 
        if (eObj instanceof PortInst)
1274
 
        {
1275
 
            PortInst pi = (PortInst)eObj;
1276
 
            nets = NetworkTool.getNetworksOnPort(pi, netlist, nets);
1277
 
//                                              boolean added = false;
1278
 
//                                              for(Iterator<Connection> aIt = pi.getNodeInst().getConnections(); aIt.hasNext(); )
1279
 
//                                              {
1280
 
//                                                      Connection con = aIt.next();
1281
 
//                                                      ArcInst ai = con.getArc();
1282
 
//                                                      int wid = netlist.getBusWidth(ai);
1283
 
//                                                      for(int i=0; i<wid; i++)
1284
 
//                                                      {
1285
 
//                                                              Network net = netlist.getNetwork(ai, i);
1286
 
//                                                              if (net != null)
1287
 
//                                                              {
1288
 
//                                                                      added = true;
1289
 
//                                                                      nets.add(net);
1290
 
//                                                              }
1291
 
//                                                      }
1292
 
//                                              }
1293
 
//                                              if (!added)
1294
 
//                                              {
1295
 
//                                                      Network net = netlist.getNetwork(pi);
1296
 
//                                                      if (net != null) nets.add(net);
1297
 
//                                              }
1298
 
        } else if (eObj instanceof ArcInst)
1299
 
        {
1300
 
            ArcInst ai = (ArcInst)eObj;
1301
 
            int width = netlist.getBusWidth(ai);
1302
 
            for(int i=0; i<width; i++)
1303
 
            {
1304
 
                Network net = netlist.getNetwork((ArcInst)eObj, i);
1305
 
                if (net != null) nets.add(net);
1306
 
            }
1307
 
        }
1308
 
    }
1309
 
 
1310
 
    Rectangle2D getHighlightedArea(EditWindow wnd)
1311
 
    {
1312
 
        ElectricObject eObj = eobj;
1313
 
        if (eObj instanceof PortInst) eObj = ((PortInst)eObj).getNodeInst();
1314
 
        if (eObj instanceof Geometric)
1315
 
        {
1316
 
            Geometric geom = (Geometric)eObj;
1317
 
            return geom.getBounds();
1318
 
        }
1319
 
        return null;
1320
 
    }
1321
 
 
1322
 
    public Geometric getGeometric()
1323
 
    {
1324
 
        Geometric retVal = null;
1325
 
        if (eobj instanceof PortInst) retVal = ((PortInst)eobj).getNodeInst(); else
1326
 
                if (eobj instanceof Geometric) retVal = (Geometric)eobj;
1327
 
        return retVal;
1328
 
    }
1329
 
 
1330
 
    boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter)
1331
 
    {
1332
 
        Point2D slop = wnd.deltaScreenToDatabase(Highlighter.EXACTSELECTDISTANCE*2, Highlighter.EXACTSELECTDISTANCE*2);
1333
 
        double directHitDist = slop.getX();
1334
 
        Point2D start = wnd.screenToDatabase(x, y);
1335
 
        Rectangle2D searchArea = new Rectangle2D.Double(start.getX(), start.getY(), 0, 0);
1336
 
 
1337
 
        ElectricObject eobj = this.eobj;
1338
 
        if (eobj instanceof PortInst) eobj = ((PortInst)eobj).getNodeInst();
1339
 
        if (eobj instanceof Geometric)
1340
 
        {
1341
 
                boolean specialSelect = ToolBar.isSelectSpecial();
1342
 
            Highlight2 got = Highlighter.checkOutObject((Geometric)eobj, true, false, specialSelect, searchArea, wnd, directHitDist, false);
1343
 
            if (got == null) return false;
1344
 
            if (!(got instanceof HighlightEOBJ))
1345
 
                System.out.println("Error?");
1346
 
            ElectricObject hObj = got.getElectricObject();
1347
 
            ElectricObject hReal = hObj;
1348
 
            if (hReal instanceof PortInst) hReal = ((PortInst)hReal).getNodeInst();
1349
 
            for(Highlight2 alreadyDone : highlighter.getHighlights())
1350
 
            {
1351
 
                if (!(alreadyDone instanceof HighlightEOBJ)) continue;
1352
 
                HighlightEOBJ alreadyHighlighted = (HighlightEOBJ)alreadyDone;
1353
 
                ElectricObject aHObj = alreadyHighlighted.getElectricObject();
1354
 
                ElectricObject aHReal = aHObj;
1355
 
                if (aHReal instanceof PortInst) aHReal = ((PortInst)aHReal).getNodeInst();
1356
 
                if (hReal == aHReal)
1357
 
                {
1358
 
                    // found it: adjust the port/point
1359
 
                    if (hObj != aHObj || alreadyHighlighted.point != ((HighlightEOBJ)got).point)
1360
 
                    {
1361
 
                        alreadyHighlighted.eobj = got.getElectricObject();
1362
 
                        alreadyHighlighted.point = ((HighlightEOBJ)got).point;
1363
 
                        synchronized(highlighter) {
1364
 
                            highlighter.setChanged(true);
1365
 
                        }
1366
 
                    }
1367
 
                    break;
1368
 
                }
1369
 
            }
1370
 
            return true;
1371
 
        }
1372
 
        return false;
1373
 
    }
1374
 
 
1375
 
    public String getInfo()
1376
 
    {
1377
 
        String description = "";
1378
 
        ElectricObject realObj = eobj;
1379
 
 
1380
 
        if (realObj instanceof PortInst)
1381
 
            realObj = ((PortInst)realObj).getNodeInst();
1382
 
        if (realObj instanceof NodeInst)
1383
 
        {
1384
 
            NodeInst ni = (NodeInst)realObj;
1385
 
            description = "Node " + ni.describe(true);
1386
 
        } else if (realObj instanceof ArcInst)
1387
 
        {
1388
 
            ArcInst ai = (ArcInst)eobj;
1389
 
            description = "Arc " + ai.describe(true);
1390
 
        }
1391
 
        return description;
1392
 
    }
1393
 
}
1394
 
 
1395
 
class HighlightText extends Highlight2
1396
 
{
1397
 
        /** The highlighted object. */                                                          protected final ElectricObject eobj;
1398
 
        /** The highlighted variable. */                                                        protected final Variable.Key varKey;
1399
 
 
1400
 
    public HighlightText(ElectricObject e, Cell c, Variable.Key key)
1401
 
    {
1402
 
        super(c);
1403
 
        this.eobj = e;
1404
 
        this.varKey = key;
1405
 
        Class cls = null;
1406
 
        if (key == NodeInst.NODE_NAME || key == NodeInst.NODE_PROTO)
1407
 
            cls = NodeInst.class;
1408
 
        else if (key == ArcInst.ARC_NAME)
1409
 
            cls = ArcInst.class;
1410
 
        else if (key == Export.EXPORT_NAME)
1411
 
            cls = Export.class;
1412
 
        if (cls != null && !cls.isInstance(e))
1413
 
            throw new IllegalArgumentException(key + " in " + e);
1414
 
    }
1415
 
 
1416
 
    void internalDescribe(StringBuffer desc)
1417
 
    {
1418
 
        if (varKey != null)
1419
 
        {
1420
 
                if (varKey == NodeInst.NODE_NAME)
1421
 
                {
1422
 
                    desc.append(", name: ");
1423
 
                    desc.append(((NodeInst)eobj).getName());
1424
 
                } else if (varKey == NodeInst.NODE_PROTO)
1425
 
                {
1426
 
                    desc.append(", instance: ");
1427
 
                    desc.append(((NodeInst)eobj).getProto().getName());
1428
 
                } else if (varKey == ArcInst.ARC_NAME)
1429
 
                {
1430
 
                    desc.append(", name: ");
1431
 
                    desc.append(((ArcInst)eobj).getName());
1432
 
                } else if (varKey == Export.EXPORT_NAME)
1433
 
                {
1434
 
                    desc.append(", export: ");
1435
 
                    desc.append(((Export)eobj).getName());
1436
 
                } else
1437
 
                {
1438
 
                    desc.append(", var: ");
1439
 
                    desc.append(eobj.getParameterOrVariable(varKey).describe(-1));
1440
 
                }
1441
 
        }
1442
 
    }
1443
 
 
1444
 
    public ElectricObject getElectricObject() { return eobj; }
1445
 
 
1446
 
    // creating so HighlightText is not a public class
1447
 
    public boolean isHighlightText() { return true; }
1448
 
 
1449
 
    public Variable.Key getVarKey() { return varKey; }
1450
 
 
1451
 
    boolean isValid()
1452
 
    {
1453
 
        if (!super.isValid()) return false;
1454
 
        if (eobj == null || varKey == null) return false;
1455
 
        if (!eobj.isLinked()) return false;
1456
 
 
1457
 
        if (varKey == NodeInst.NODE_NAME ||
1458
 
                        varKey == ArcInst.ARC_NAME ||
1459
 
                        varKey == NodeInst.NODE_PROTO ||
1460
 
                        varKey == Export.EXPORT_NAME) return true;
1461
 
        return eobj.getParameterOrVariable(varKey) != null;
1462
 
    }
1463
 
 
1464
 
    boolean sameThing(Highlight2 obj)
1465
 
    {
1466
 
        if (this == obj) return (true);
1467
 
 
1468
 
                // Consider already obj==null
1469
 
        if (obj == null || getClass() != obj.getClass())
1470
 
            return (false);
1471
 
 
1472
 
        HighlightText other = (HighlightText)obj;
1473
 
        if (eobj != other.eobj) return false;
1474
 
        if (cell != other.cell) return false;
1475
 
        if (varKey != other.varKey) return false;
1476
 
        return true;
1477
 
    }
1478
 
 
1479
 
    public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
1480
 
                                      boolean onlyHighlight, boolean setConnected)
1481
 
    {
1482
 
        Graphics2D g2 = (Graphics2D)g;
1483
 
        Point2D [] points = Highlighter.describeHighlightText(wnd, eobj, varKey);
1484
 
        if (points == null) return;
1485
 
        Point2D [] linePoints = new Point2D[2];
1486
 
        for(int i=0; i<points.length; i += 2)
1487
 
        {
1488
 
            linePoints[0] = points[i];
1489
 
            linePoints[1] = points[i+1];
1490
 
            drawOutlineFromPoints(wnd, g, linePoints, highOffX, highOffY, false, false);
1491
 
        }
1492
 
        if (onlyHighlight)
1493
 
        {
1494
 
            // this is the only thing highlighted: show the attached object
1495
 
            ElectricObject eObj = eobj;
1496
 
            if (eObj != null && eObj instanceof Geometric)
1497
 
            {
1498
 
                Geometric geom = (Geometric)eObj;
1499
 
                if (geom instanceof ArcInst || !((NodeInst)geom).isInvisiblePinWithText())
1500
 
                {
1501
 
                    Point c = wnd.databaseToScreen(geom.getTrueCenter());
1502
 
                    int lowX = Integer.MAX_VALUE, highX = Integer.MIN_VALUE;
1503
 
                    int lowY = Integer.MAX_VALUE, highY = Integer.MIN_VALUE;
1504
 
                    for(int i=0; i<points.length; i++)
1505
 
                    {
1506
 
                        Point a = wnd.databaseToScreen(points[i]);
1507
 
                        if (a.x < lowX) lowX = a.x;
1508
 
                        if (a.x > highX) highX = a.x;
1509
 
                        if (a.y < lowY) lowY = a.y;
1510
 
                        if (a.y > highY) highY = a.y;
1511
 
                    }
1512
 
                    int cX = (lowX+highX)/2;
1513
 
                    int cY = (lowY+highY)/2;
1514
 
                    if (Math.abs(cX - c.x) > 4 || Math.abs(cY - c.y) > 4)
1515
 
                    {
1516
 
                        g.fillOval(c.x-4, c.y-4, 8, 8);
1517
 
                        g2.setStroke(dottedLine);
1518
 
                        drawLine(g, wnd, c.x, c.y, cX, cY);
1519
 
                        g2.setStroke(solidLine);
1520
 
                    }
1521
 
                }
1522
 
            }
1523
 
        }
1524
 
    }
1525
 
 
1526
 
//    /**
1527
 
//       * Method to tell whether this Highlight is text that stays with its node.
1528
 
//       * The two possibilities are (1) text on invisible pins
1529
 
//       * (2) export names, when the option to move exports with their labels is requested.
1530
 
//       * @return true if this Highlight is text that should move with its node.
1531
 
//       */
1532
 
//    public boolean nodeMovesWithText()
1533
 
//      {
1534
 
//              if (varKey != null)
1535
 
//              {
1536
 
//                      // moving variable text
1537
 
//                      if (!(eobj instanceof NodeInst)) return false;
1538
 
//                      NodeInst ni = (NodeInst)eobj;
1539
 
//                      if (ni.isInvisiblePinWithText()) return true;
1540
 
//              } else
1541
 
//              {
1542
 
//                      // moving export text
1543
 
//                      if (!(eobj instanceof Export)) return false;
1544
 
//                      Export pp = (Export)eobj;
1545
 
//                      if (pp.getOriginalPort().getNodeInst().getProto() == Generic.tech.invisiblePinNode) return true;
1546
 
//                      if (User.isMoveNodeWithExport()) return true;
1547
 
//              }
1548
 
//              return false;
1549
 
//      }
1550
 
 
1551
 
    public Geometric getGeometric()
1552
 
    {
1553
 
        if (DisplayedText.objectMovesWithText(eobj, varKey))
1554
 
        {
1555
 
            if (eobj instanceof Export) return ((Export)eobj).getOriginalPort().getNodeInst();
1556
 
            if (eobj instanceof Geometric) return (Geometric)eobj;
1557
 
        }
1558
 
        return null;
1559
 
    }
1560
 
 
1561
 
    void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
1562
 
    {
1563
 
        getHighlightedEObjsInternal(getGeometric(), list, wantNodes, wantArcs);
1564
 
    }
1565
 
 
1566
 
    void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
1567
 
    {
1568
 
        getHighlightedNodesInternal(getGeometric(), list);
1569
 
    }
1570
 
 
1571
 
    void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
1572
 
    {
1573
 
        getHighlightedArcsInternal(getGeometric(), list);
1574
 
    }
1575
 
 
1576
 
    void getHighlightedNetworks(Set<Network> nets, Netlist netlist)
1577
 
    {
1578
 
        if (/*varKey == null &&*/ eobj instanceof Export)
1579
 
        {
1580
 
            Export pp = (Export)eobj;
1581
 
            int width = netlist.getBusWidth(pp);
1582
 
            for(int i=0; i<width; i++)
1583
 
            {
1584
 
                Network net = netlist.getNetwork(pp, i);
1585
 
                if (net != null) nets.add(net);
1586
 
            }
1587
 
        }
1588
 
    }
1589
 
 
1590
 
    DisplayedText makeDisplayedText()
1591
 
    {
1592
 
        if (varKey != null)
1593
 
                return new DisplayedText(eobj, varKey);
1594
 
        return null;
1595
 
    }
1596
 
 
1597
 
    void getHighlightedText(List<DisplayedText> list, boolean unique, List<Highlight2> getHighlights)
1598
 
    {
1599
 
        DisplayedText dt = makeDisplayedText();
1600
 
        if (dt == null) return;
1601
 
        if (list.contains(dt)) return;
1602
 
 
1603
 
        // if this text is on a selected object, don't include the text
1604
 
        if (unique)
1605
 
        {
1606
 
            ElectricObject onObj = null;
1607
 
            if (varKey != null)
1608
 
            {
1609
 
                if (eobj instanceof Export)
1610
 
                {
1611
 
                    onObj = ((Export)eobj).getOriginalPort().getNodeInst();
1612
 
                } else if (eobj instanceof PortInst)
1613
 
                {
1614
 
                    onObj = ((PortInst)eobj).getNodeInst();
1615
 
                } else if (eobj instanceof Geometric)
1616
 
                {
1617
 
                    onObj = eobj;
1618
 
                }
1619
 
            }
1620
 
 
1621
 
            // now see if the object is in the list
1622
 
            if (eobj != null)
1623
 
            {
1624
 
                boolean found = false;
1625
 
                for(Highlight2 oH : getHighlights)
1626
 
                {
1627
 
                    if (!(oH instanceof HighlightEOBJ)) continue;
1628
 
                    ElectricObject fobj = ((HighlightEOBJ)oH).eobj;
1629
 
                    if (fobj instanceof PortInst) fobj = ((PortInst)fobj).getNodeInst();
1630
 
                    if (fobj == onObj) { found = true;   break; }
1631
 
                }
1632
 
                if (found) return;
1633
 
            }
1634
 
        }
1635
 
 
1636
 
        // add this text
1637
 
        list.add(dt);
1638
 
    }
1639
 
 
1640
 
    Rectangle2D getHighlightedArea(EditWindow wnd)
1641
 
    {
1642
 
        if (wnd != null)
1643
 
        {
1644
 
            Poly poly = eobj.computeTextPoly(wnd, varKey);
1645
 
            if (poly != null) return poly.getBounds2D();
1646
 
        }
1647
 
        return null;
1648
 
    }
1649
 
 
1650
 
    boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter)
1651
 
    {
1652
 
        Point2D start = wnd.screenToDatabase(x, y);
1653
 
        Poly poly = eobj.computeTextPoly(wnd, varKey);
1654
 
        if (poly != null)
1655
 
            if (poly.isInside(start)) return true;
1656
 
        return false;
1657
 
    }
1658
 
 
1659
 
    public String describe()
1660
 
    {
1661
 
        String description = "Unknown";
1662
 
        if (varKey != null && eobj != null)
1663
 
        {
1664
 
                if (varKey == NodeInst.NODE_NAME)
1665
 
                {
1666
 
                        description = "Node name for " + ((NodeInst)eobj).describe(true);
1667
 
                } else if (varKey == ArcInst.ARC_NAME)
1668
 
                {
1669
 
                        description = "Arc name for " + ((ArcInst)eobj).describe(true);
1670
 
                } else if (varKey == Export.EXPORT_NAME)
1671
 
                {
1672
 
                        description = "Export '" + ((Export)eobj).getName() + "'";
1673
 
                } else if (varKey == NodeInst.NODE_PROTO)
1674
 
                {
1675
 
                        description = "Cell instance name " + ((NodeInst)eobj).describe(true);
1676
 
                } else
1677
 
                {
1678
 
                        description = eobj.getParameterOrVariable(varKey).getFullDescription(eobj);
1679
 
                }
1680
 
        }
1681
 
        return description;
1682
 
    }
1683
 
 
1684
 
    public String getInfo()
1685
 
    {
1686
 
        return "Text: " + describe();
1687
 
    }
1688
 
}