~ubuntu-branches/ubuntu/jaunty/electric/jaunty

« back to all changes in this revision

Viewing changes to com/sun/electric/technology/xml/Xml807.java

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2009-01-08 02:05:08 UTC
  • mfrom: (1.1.2 upstream) (3.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090108020508-0h3li7zt9mu5gf0i
Tags: 8.08-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 * Electric(tm) VLSI Design System
4
4
 *
5
 
 * File: Xml807.java
 
5
 * File: Xml.java
6
6
 *
7
7
 * Copyright (c) 2003 Sun Microsystems and Static Free Software
8
8
 *
25
25
 
26
26
import com.sun.electric.database.geometry.EGraphics;
27
27
import com.sun.electric.database.geometry.EPoint;
28
 
import com.sun.electric.database.geometry.ERectangle;
29
 
import com.sun.electric.database.geometry.Poly.Type;
 
28
import com.sun.electric.database.geometry.Poly;
30
29
import com.sun.electric.technology.DRCTemplate;
31
30
import com.sun.electric.technology.EdgeH;
32
31
import com.sun.electric.technology.EdgeV;
 
32
import com.sun.electric.technology.SizeOffset;
33
33
import com.sun.electric.technology.Technology.TechPoint;
34
34
import com.sun.electric.tool.Job;
35
35
 
45
45
import java.util.ArrayList;
46
46
import java.util.Arrays;
47
47
import java.util.Calendar;
48
 
import java.util.Collections;
49
48
import java.util.Date;
50
49
import java.util.HashMap;
51
50
import java.util.LinkedHashMap;
52
51
import java.util.List;
53
52
import java.util.Map;
 
53
import java.util.TreeMap;
54
54
 
55
55
import javax.xml.XMLConstants;
56
56
import javax.xml.parsers.SAXParser;
57
57
import javax.xml.parsers.SAXParserFactory;
58
 
 
59
58
import javax.xml.validation.Schema;
60
59
import javax.xml.validation.SchemaFactory;
61
60
import org.xml.sax.Attributes;
75
74
        public String className;
76
75
        public String shortTechName;
77
76
        public String description;
 
77
        public final List<Version> versions = new ArrayList<Version>();
78
78
        public int minNumMetals;
79
79
        public int maxNumMetals;
80
80
        public int defaultNumMetals;
83
83
        public String defaultFoundry;
84
84
        public double minResistance;
85
85
        public double minCapacitance;
86
 
        private final LinkedHashMap<String,Layer> layers = new LinkedHashMap<String,Layer>();
 
86
        public final List<Color> transparentLayers = new ArrayList<Color>();
 
87
        public final List<Layer> layers = new ArrayList<Layer>();
87
88
        public final List<ArcProto> arcs = new ArrayList<ArcProto>();
88
89
        public final List<PrimitiveNode> nodes = new ArrayList<PrimitiveNode>();
89
90
        public final List<SpiceHeader> spiceHeaders = new ArrayList<SpiceHeader>();
90
 
        public final List<DisplayStyle> displayStyles = new ArrayList<DisplayStyle>();
91
91
        public MenuPalette menuPalette;
92
 
        public final LinkedHashMap<String,RuleSet> ruleSets = new LinkedHashMap<String,RuleSet>();
93
92
        public final List<Foundry> foundries = new ArrayList<Foundry>();
94
93
 
95
 
        public Layer newLayer(String name) {
96
 
            if (name == null)
97
 
                throw new NullPointerException();
98
 
            if (layers.containsKey(name))
99
 
                throw new IllegalArgumentException("Duplicate Layer " + name);
100
 
            Layer layer = new Layer(name);
101
 
            layers.put(name, layer);
102
 
            return layer;
103
 
        }
104
 
        
105
 
        public RuleSet newRuleSet(String name) {
106
 
            if (name == null)
107
 
                throw new NullPointerException();
108
 
            if (ruleSets.containsKey(name))
109
 
                throw new IllegalArgumentException("Duplicate RuleSet " + name);
110
 
            RuleSet ruleSet = new RuleSet(name);
111
 
            ruleSets.put(name, ruleSet);
112
 
            return ruleSet;
113
 
        }
114
 
        
115
94
        public Layer findLayer(String name) {
116
 
            return layers.get(name);
 
95
            for (Layer layer: layers) {
 
96
                if (layer.name.equals(name))
 
97
                    return layer;
 
98
            }
 
99
            return null;
117
100
        }
118
101
 
119
102
        public ArcProto findArc(String name) {
146
129
        }
147
130
    }
148
131
 
 
132
    public static class Version implements Serializable {
 
133
        public int techVersion;
 
134
        public com.sun.electric.database.text.Version electricVersion;
 
135
    }
 
136
 
149
137
    public static class Layer implements Serializable {
150
 
        public final String name;
 
138
        public String name;
151
139
        public com.sun.electric.technology.Layer.Function function;
152
140
        public int extraFunction;
 
141
        public EGraphics desc;
 
142
        public double thick3D;
 
143
        public double height3D;
 
144
        public String mode3D;
 
145
        public double factor3D;
153
146
        public String cif;
154
147
        public String skill;
155
148
        public double resistance;
156
149
        public double capacitance;
157
150
        public double edgeCapacitance;
158
151
        public PureLayerNode pureLayerNode;
159
 
        
160
 
        private Layer(String name) {
161
 
            this.name = name;
162
 
        }
163
152
    }
164
153
 
165
154
    public static class PureLayerNode implements Serializable {
166
155
        public String name;
167
156
        public String oldName;
168
 
        public Type style;
 
157
        public Poly.Type style;
169
158
        public String port;
 
159
        public final Distance size = new Distance();
170
160
        public final List<String> portArcs = new ArrayList<String>();
171
161
    }
172
162
 
180
170
        public boolean notUsed;
181
171
        public boolean skipSizeInPalette;
182
172
 
 
173
        public final TreeMap<Integer,Double> diskOffset = new TreeMap<Integer,Double>();
 
174
        public final Distance defaultWidth = new Distance();
183
175
        public boolean extended;
184
176
        public boolean fixedAngle;
185
177
        public int angleIncrement;
186
178
        public double antennaRatio;
187
 
        public double elibWidthOffset;
188
179
        public final List<ArcLayer> arcLayers = new ArrayList<ArcLayer>();
189
 
        public ArcPin arcPin;
190
 
    }
191
 
 
192
 
    public static class ArcPin implements Serializable {
193
 
        public String name;
194
 
        public String portName;
195
 
        public double elibSize;
196
 
        public final List<String> portArcs = new ArrayList<String>();
197
180
    }
198
181
 
199
182
    public static class ArcLayer implements Serializable {
200
183
        public String layer;
201
184
        public final Distance extend = new Distance();
202
 
        public Type style;
 
185
        public Poly.Type style;
203
186
    }
204
187
 
205
188
    public static class PrimitiveNode implements Serializable {
221
204
        public boolean od33;
222
205
 
223
206
        public com.sun.electric.technology.PrimitiveNode.Function function;
224
 
        public EPoint diskOffset;
 
207
        public final TreeMap<Integer,EPoint> diskOffset = new TreeMap<Integer,EPoint>();
225
208
        public final Distance defaultWidth = new Distance();
226
209
        public final Distance defaultHeight = new Distance();
227
 
        public ERectangle nodeBase;
 
210
        public SizeOffset sizeOffset;
228
211
        public final List<NodeLayer> nodeLayers = new ArrayList<NodeLayer>();
229
212
        public final List<PrimitivePort> ports = new ArrayList<PrimitivePort>();
230
213
        public int specialType;
235
218
 
236
219
    public static class NodeLayer implements Serializable {
237
220
        public String layer;
238
 
        public Type style;
 
221
        public Poly.Type style;
239
222
        public int portNum;
240
223
        public boolean inLayers;
241
224
        public boolean inElectricalLayers;
246
229
        public final Distance hy = new Distance();
247
230
        public final List<TechPoint> techPoints = new ArrayList<TechPoint>();
248
231
        public double sizex, sizey, sep1d, sep2d;
249
 
        public String sizeRule, sepRule, sepRule2D;
250
232
        public double lWidth, rWidth, tExtent, bExtent;
251
233
    }
252
234
 
273
255
        public final List<String> spiceLines = new ArrayList<String>();
274
256
    }
275
257
 
276
 
    public static class DisplayStyle implements Serializable {
277
 
        public String name;
278
 
        public final List<Color> transparentLayers = new ArrayList<Color>();
279
 
        private final LinkedHashMap<Layer,LayerDisplayStyle> layerStylesInternal = new LinkedHashMap<Layer,LayerDisplayStyle>();
280
 
        public final Map<Layer,LayerDisplayStyle> layerStyles = Collections.unmodifiableMap(layerStylesInternal);
281
 
        
282
 
        public LayerDisplayStyle newLayer(Layer layer) {
283
 
            LayerDisplayStyle lds = new LayerDisplayStyle(layer);
284
 
            LayerDisplayStyle old = layerStylesInternal.put(layer, lds);
285
 
            assert old == null;
286
 
            return lds;
287
 
        }
288
 
    }
289
 
    
290
 
    public static class LayerDisplayStyle implements Serializable {
291
 
        public final Layer layer;
292
 
        public EGraphics desc;
293
 
        public String mode3D;
294
 
        public double factor3D;
295
 
        
296
 
        private LayerDisplayStyle(Layer layer) {
297
 
            this.layer = layer;
298
 
        }
299
 
    }
300
 
    
301
258
    public static class MenuPalette implements Serializable {
302
259
        public int numColumns;
303
260
        public List<List<Object>> menuBoxes = new ArrayList<List<Object>>();
305
262
        public String writeXml() {
306
263
            StringWriter sw = new StringWriter();
307
264
            PrintWriter out = new PrintWriter(sw);
308
 
            OneLineWriter writer = new OneLineWriter(out);
 
265
            Xml807.OneLineWriter writer = new Xml807.OneLineWriter(out);
309
266
            writer.writeMenuPaletteXml(this);
310
267
            out.close();
311
268
            return sw.getBuffer().toString();
313
270
    }
314
271
 
315
272
    public static class MenuNodeInst implements Serializable {
316
 
        public String protoName;
317
 
        public com.sun.electric.technology.PrimitiveNode.Function function;
318
 
        public String text;
319
 
        public double fontSize;
320
 
        public int rotation;
321
 
    }
322
 
 
323
 
    public static class MenuCell implements Serializable {
324
 
        public String cellName;
325
 
//        public String text;
326
 
//        public double fontSize;
 
273
        /** the name of the prototype in the menu */                    public String protoName;
 
274
        /** the function of the prototype */                                    public com.sun.electric.technology.PrimitiveNode.Function function;
 
275
        /** label to draw in the menu entry (may be null) */    public String text;
 
276
        /** the size of the menu entry label */                                 public double fontSize;
 
277
        /** the rotation of the node in the menu entry */               public int rotation;
327
278
    }
328
279
 
329
280
    public static class Distance implements Serializable {
330
281
        public double k;
331
 
        public double lambdaValue;
332
 
        public final List<DistanceRule> terms = new ArrayList<DistanceRule>();
333
 
 
334
 
        public void assign(Distance d) {
335
 
            k = d.k;
336
 
            lambdaValue = d.lambdaValue;
337
 
            for (DistanceRule term: d.terms)
338
 
                terms.add(term.clone());
339
 
        }
340
 
 
341
 
        public void assign(com.sun.electric.technology.Technology.Distance d) {
342
 
            k = d.k;
343
 
            lambdaValue = d.lambdaValue;
344
 
            for (com.sun.electric.technology.Technology.DistanceRule term: d.terms)
345
 
                terms.add(new DistanceRule(term));
346
 
        }
347
 
 
348
 
        public Distance clone() {
349
 
            Distance d = new Distance();
350
 
            d.assign(this);
351
 
            return d;
352
 
        }
353
 
 
354
 
        public double getLambda(DistanceContext context) {
355
 
            double value = lambdaValue;
356
 
            for (DistanceRule term: terms)
357
 
                value += term.getLambda(context);
358
 
            return value;
359
 
        }
360
 
        private void writeXml(Writer writer, boolean multiLine) {
361
 
            for (DistanceRule term: terms) {
362
 
                term.writeXml(writer);
363
 
                if (multiLine)
364
 
                    writer.l();
365
 
            }
366
 
            if (lambdaValue != 0) {
367
 
                writer.bcpe(XmlKeyword.lambda, lambdaValue);
368
 
                if (multiLine)
369
 
                    writer.l();
370
 
            }
371
 
        }
372
 
        public void addLambda(double value) {
373
 
            lambdaValue += value;
374
 
        }
375
 
        public void addRule(String ruleName, double k) {
376
 
            addRule(ruleName, null, k);
377
 
        }
378
 
        public void addRule(String ruleName, Layer layer, double k) {
379
 
            addRule(ruleName, layer, null, k);
380
 
        }
381
 
        public void addRule(String ruleName, Layer layer, Layer layer2, double k) {
382
 
            terms.add(new DistanceRule(ruleName, layer, layer2, k));
383
 
        }
384
 
        public boolean isEmpty() { return lambdaValue == 0 && terms.isEmpty(); }
385
 
    }
386
 
 
387
 
    public static interface DistanceContext {
388
 
        public double getRule(String ruleName);
389
 
    }
390
 
 
391
 
    public static class DistanceRule implements Serializable, Cloneable {
392
 
        final String ruleName;
393
 
        final Layer layer;
394
 
        final Layer layer2;
395
 
        final double k;
396
 
 
397
 
        public DistanceRule(com.sun.electric.technology.Technology.DistanceRule oldRule) {
398
 
            this(oldRule.ruleName, null, null, oldRule.k);
399
 
        }
400
 
        
401
 
        private DistanceRule(String ruleName, Layer layer, Layer layer2, double k) {
402
 
            this.ruleName = ruleName;
403
 
            this.layer = layer;
404
 
            this.layer2 = layer2;
405
 
            this.k = k;
406
 
        }
407
 
        
408
 
        public DistanceRule clone() {
409
 
            try {
410
 
                return (DistanceRule)super.clone();
411
 
            } catch (CloneNotSupportedException e) {
412
 
                throw new AssertionError();
413
 
            }
414
 
        }
415
 
 
416
 
        private void writeXml(Writer writer) {
417
 
            writer.b(XmlKeyword.rule);
418
 
            writer.a("ruleName", ruleName);
419
 
            if (layer != null) {
420
 
                writer.a("layer", layer.name);
421
 
                if (layer2 != null)
422
 
                    writer.a("layer2", layer2.name);
423
 
            }
424
 
            if (k != 1)
425
 
                writer.a("k", k);
426
 
            writer.e();
427
 
        }
428
 
 
429
 
        private double getLambda(DistanceContext context) {
430
 
            return context.getRule(ruleName)*k;
431
 
        }
432
 
    }
433
 
    
434
 
    public static class RuleSet implements Serializable {
435
 
        public final String name;
436
 
        public final Map<String,Map<Layer,Distance>> layerRules = new LinkedHashMap<String,Map<Layer,Distance>>();
437
 
        
438
 
        private RuleSet(String name) {
439
 
            this.name = name;
440
 
        }
441
 
        
442
 
        public Map<Layer,Distance> newLayerRule(String ruleName) {
443
 
            if (ruleName == null)
444
 
                throw new NullPointerException();
445
 
            if (layerRules.containsKey(ruleName))
446
 
                throw new IllegalArgumentException("Duplicate LayerRule " + ruleName);
447
 
            Map<Layer,Distance> layerRule = new LinkedHashMap<Layer,Distance>();
448
 
            layerRules.put(ruleName, layerRule);
449
 
            return layerRule;
 
282
        public double value;
 
283
 
 
284
        public void addLambda(double lambdaValue) {
 
285
            value += lambdaValue;
450
286
        }
451
287
    }
452
288
 
462
298
        technology,
463
299
        shortName(true),
464
300
        description(true),
 
301
        version,
465
302
        numMetals,
466
303
        scale,
467
304
        defaultFoundry,
468
305
        minResistance,
469
306
        minCapacitance,
 
307
        transparentLayer,
 
308
        r(true),
 
309
        g(true),
 
310
        b(true),
470
311
        layer,
 
312
        transparentColor,
 
313
        opaqueColor,
 
314
        patternedOnDisplay(true),
 
315
        patternedOnPrinter(true),
 
316
        pattern(true),
 
317
        outlined(true),
 
318
        opacity(true),
 
319
        foreground(true),
471
320
        display3D,
472
321
        cifLayer,
473
322
        skillLayer,
486
335
        fixedAngle(true),
487
336
        angleIncrement(true),
488
337
        antennaRatio(true),
489
 
        elibWidthOffset(true),
490
338
 
 
339
        diskOffset,
 
340
        defaultWidth,
491
341
        arcLayer,
492
 
        arcPin,
493
342
 
494
343
        primitiveNode,
495
344
        //oldName(true),
507
356
        od18,
508
357
        od25,
509
358
        od33,
510
 
        diskOffset,
511
 
        defaultWidth,
 
359
 //       defaultWidth,
512
360
        defaultHeight,
513
 
        nodeBase,
 
361
        sizeOffset,
514
362
        nodeLayer,
515
363
        box,
516
364
        multicutbox,
530
378
        spiceTemplate,
531
379
        spiceHeader,
532
380
        spiceLine,
533
 
        
534
 
        displayStyle,
535
 
        transparentLayer,
536
 
        r(true),
537
 
        g(true),
538
 
        b(true),
539
 
        transparentColor,
540
 
        opaqueColor,
541
 
        patternedOnDisplay(true),
542
 
        patternedOnPrinter(true),
543
 
        pattern(true),
544
 
        outlined(true),
545
 
        opacity(true),
546
 
        foreground(true),
547
 
        
548
381
        menuPalette,
549
382
        menuBox,
550
383
        menuArc(true),
551
384
        menuNode(true),
552
 
        menuCell,
553
385
        menuText(true),
554
386
        menuNodeInst,
555
387
        menuNodeText,
556
388
        lambda(true),
557
 
        rule,
558
 
        
559
 
        ruleSet,
560
 
        layerRule,
561
389
        Foundry,
562
390
        layerGds,
563
391
        LayerRule,
586
414
    private static synchronized void loadTechnologySchema() throws SAXException {
587
415
        if (schema != null) return;
588
416
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
589
 
        URL technologySchemaUrl = Technology.class.getResource("xml/Technology807.xsd");
 
417
        URL technologySchemaUrl = Technology.class.getResource("Technology.xsd");
590
418
        if (technologySchemaUrl != null)
591
419
            schema = schemaFactory.newSchema(technologySchemaUrl);
592
420
        else
593
421
        {
594
 
            System.err.println("Schema file Technology807.xsd, working without XML schema");
595
 
            System.out.println("Schema file Technology807.xsd, working without XML schema");
 
422
            System.err.println("Schema file Technology.xsd, working without XML schema");
 
423
            System.out.println("Schema file Technology.xsd, working without XML schema");
596
424
        }
597
425
    }
598
426
 
635
463
        }
636
464
        return null;
637
465
    }
638
 
 
639
466
    /**
640
467
     * Method to parse a string of XML that describes the component menu in a Technology Editing context.
641
468
     * Normal parsing of XML returns objects in the Xml class, but
668
495
        private static boolean DEBUG = false;
669
496
        private Locator locator;
670
497
 
671
 
        private Technology tech = new Technology();
672
 
        private Layer curLayer;
673
 
        private ArcProto curArc;
674
 
        private PrimitiveNode curNode;
675
 
        private NodeLayer curNodeLayer;
676
 
        private PrimitivePort curPort;
677
 
        private int curSpecialValueIndex;
678
 
        private ArrayList<Object> curMenuBox;
679
 
        private MenuNodeInst curMenuNodeInst;
680
 
        private MenuCell curMenuCell;
681
 
        private Distance curDistance;
682
 
        private SpiceHeader curSpiceHeader;
683
 
        
684
 
        private DisplayStyle curDisplayStyle;
 
498
        private Xml807.Technology tech = new Xml807.Technology();
685
499
        private int curTransparent = 0;
686
500
        private int curR;
687
501
        private int curG;
688
502
        private int curB;
689
 
        private LayerDisplayStyle curLayerDisplayStyle;
 
503
        private Layer curLayer;
690
504
        private boolean patternedOnDisplay;
691
505
        private boolean patternedOnPrinter;
692
506
        private final int[] pattern = new int[16];
694
508
        private EGraphics.Outline outline;
695
509
        private double opacity;
696
510
        private boolean foreground;
697
 
        
698
 
        private RuleSet curRuleSet;
699
 
        private Map<Layer,Distance> curLayerRule;
 
511
        private ArcProto curArc;
 
512
        private PrimitiveNode curNode;
 
513
        private NodeLayer curNodeLayer;
 
514
        private PrimitivePort curPort;
 
515
        private int curSpecialValueIndex;
 
516
        private ArrayList<Object> curMenuBox;
 
517
        private MenuNodeInst curMenuNodeInst;
 
518
        private Distance curDistance;
 
519
        private SpiceHeader curSpiceHeader;
700
520
        private Foundry curFoundry;
701
521
 
702
522
        private boolean acceptCharacters;
953
773
                    tech.className = a_("class");
954
774
//                    dump = true;
955
775
                    break;
 
776
                case version:
 
777
                    Version version = new Version();
 
778
                    version.techVersion = Integer.parseInt(a("tech"));
 
779
                    version.electricVersion = com.sun.electric.database.text.Version.parseVersion(a("electric"));
 
780
                    tech.versions.add(version);
 
781
                    break;
956
782
                case numMetals:
957
783
                    tech.minNumMetals = Integer.parseInt(a("min"));
958
784
                    tech.maxNumMetals = Integer.parseInt(a("max"));
971
797
                case minCapacitance:
972
798
                    tech.minCapacitance = Double.parseDouble(a("value"));
973
799
                    break;
 
800
                case transparentLayer:
 
801
                    curTransparent = Integer.parseInt(a("transparent"));
 
802
                    curR = curG = curB = 0;
 
803
                    break;
974
804
                case layer:
975
 
                    if (curDisplayStyle != null) {
976
 
                        curLayerDisplayStyle = curDisplayStyle.newLayer(tech.findLayer(a("name")));
977
 
                        curTransparent = 0;
978
 
                        curR = curG = curB = 0;
979
 
                        patternedOnDisplay = false;
980
 
                        patternedOnPrinter = false;
981
 
                        Arrays.fill(pattern, 0);
982
 
                        curPatternIndex = 0;
983
 
//                      EGraphics.Outline outline = null;
984
 
                    } else if (curLayerRule != null) {
985
 
                        curDistance = new Distance();
986
 
                        Distance old = curLayerRule.put(tech.findLayer(a("name")), curDistance);
987
 
                        if (old == null)
988
 
                            throw new IllegalArgumentException("Duplicate layer " + a("name"));
989
 
                    } else {
990
 
                        curLayer = tech.newLayer(a("name"));
991
 
                        curLayer.function = com.sun.electric.technology.Layer.Function.valueOf(a("fun"));
992
 
                        String extraFunStr = a_("extraFun");
993
 
                        if (extraFunStr != null) {
994
 
                            if (extraFunStr.equals("depletion_heavy"))
995
 
                                curLayer.extraFunction = com.sun.electric.technology.Layer.Function.DEPLETION|com.sun.electric.technology.Layer.Function.HEAVY;
996
 
                            else if (extraFunStr.equals("depletion_light"))
997
 
                                curLayer.extraFunction = com.sun.electric.technology.Layer.Function.DEPLETION|com.sun.electric.technology.Layer.Function.LIGHT;
998
 
                            else if (extraFunStr.equals("enhancement_heavy"))
999
 
                                curLayer.extraFunction = com.sun.electric.technology.Layer.Function.ENHANCEMENT|com.sun.electric.technology.Layer.Function.HEAVY;
1000
 
                            else if (extraFunStr.equals("enhancement_light"))
1001
 
                                curLayer.extraFunction = com.sun.electric.technology.Layer.Function.ENHANCEMENT|com.sun.electric.technology.Layer.Function.LIGHT;
1002
 
                            else
1003
 
                                curLayer.extraFunction = com.sun.electric.technology.Layer.Function.parseExtraName(extraFunStr);
1004
 
                        }
1005
 
                    }
 
805
                    curLayer = new Layer();
 
806
                    curLayer.name = a("name");
 
807
                    curLayer.function = com.sun.electric.technology.Layer.Function.valueOf(a("fun"));
 
808
                    String extraFunStr = a_("extraFun");
 
809
                    if (extraFunStr != null) {
 
810
                        if (extraFunStr.equals("depletion_heavy"))
 
811
                            curLayer.extraFunction = com.sun.electric.technology.Layer.Function.DEPLETION|com.sun.electric.technology.Layer.Function.HEAVY;
 
812
                        else if (extraFunStr.equals("depletion_light"))
 
813
                            curLayer.extraFunction = com.sun.electric.technology.Layer.Function.DEPLETION|com.sun.electric.technology.Layer.Function.LIGHT;
 
814
                        else if (extraFunStr.equals("enhancement_heavy"))
 
815
                            curLayer.extraFunction = com.sun.electric.technology.Layer.Function.ENHANCEMENT|com.sun.electric.technology.Layer.Function.HEAVY;
 
816
                        else if (extraFunStr.equals("enhancement_light"))
 
817
                            curLayer.extraFunction = com.sun.electric.technology.Layer.Function.ENHANCEMENT|com.sun.electric.technology.Layer.Function.LIGHT;
 
818
                        else
 
819
                            curLayer.extraFunction = com.sun.electric.technology.Layer.Function.parseExtraName(extraFunStr);
 
820
                    }
 
821
                    curTransparent = 0;
 
822
                    curR = curG = curB = 0;
 
823
                    patternedOnDisplay = false;
 
824
                    patternedOnPrinter = false;
 
825
                    Arrays.fill(pattern, 0);
 
826
                    curPatternIndex = 0;
 
827
//                    EGraphics.Outline outline = null;
 
828
                    break;
 
829
                case transparentColor:
 
830
                    curTransparent = Integer.parseInt(a("transparent"));
 
831
                    if (curTransparent > 0) {
 
832
                        Color color = tech.transparentLayers.get(curTransparent - 1);
 
833
                        curR = color.getRed();
 
834
                        curG = color.getGreen();
 
835
                        curB = color.getBlue();
 
836
                    }
 
837
                    break;
 
838
                case opaqueColor:
 
839
                    curR = Integer.parseInt(a("r"));
 
840
                    curG = Integer.parseInt(a("g"));
 
841
                    curB = Integer.parseInt(a("b"));
 
842
                    break;
 
843
                case display3D:
 
844
                    curLayer.thick3D = Double.parseDouble(a("thick"));
 
845
                    curLayer.height3D = Double.parseDouble(a("height"));
 
846
                    curLayer.mode3D = a_("mode");
 
847
                    String factor3DStr = a_("factor");
 
848
                    curLayer.factor3D = factor3DStr != null ? Double.parseDouble(factor3DStr) : 0;
1006
849
                    break;
1007
850
                case cifLayer:
1008
851
                    curLayer.cif = a("cif");
1019
862
                    curLayer.pureLayerNode = new PureLayerNode();
1020
863
                    curLayer.pureLayerNode.name = a("name");
1021
864
                    String styleStr = a_("style");
1022
 
                    curLayer.pureLayerNode.style = styleStr != null ? Type.valueOf(styleStr) : Type.FILLED;
 
865
                    curLayer.pureLayerNode.style = styleStr != null ? Poly.Type.valueOf(styleStr) : Poly.Type.FILLED;
1023
866
                    curLayer.pureLayerNode.port = a("port");
 
867
                    curDistance = curLayer.pureLayerNode.size;
1024
868
                    break;
1025
869
                case arcProto:
1026
870
                    curArc = new ArcProto();
1048
892
                    if (curNode != null)
1049
893
                        curNode.skipSizeInPalette = true;
1050
894
                    break;
 
895
                case diskOffset:
 
896
                    if (curArc != null)
 
897
                        curArc.diskOffset.put(Integer.parseInt(a("untilVersion")), Double.parseDouble(a("width")));
 
898
                    if (curNode != null)
 
899
                        curNode.diskOffset.put(Integer.parseInt(a("untilVersion")), EPoint.fromLambda(Double.parseDouble(a("x")), Double.parseDouble(a("y"))));
 
900
                    break;
 
901
                case defaultWidth:
 
902
                    if (curArc != null)
 
903
                        curDistance = curArc.defaultWidth;
 
904
                    if (curNode != null)
 
905
                        curDistance = curNode.defaultWidth;
 
906
                    break;
1051
907
                case arcLayer:
1052
 
                    ArcLayer arcLay = new ArcLayer();
1053
 
                    arcLay.layer = a("layer");
1054
 
                    curDistance = arcLay.extend;
1055
 
                    arcLay.style = Type.valueOf(a("style"));
1056
 
                    curArc.arcLayers.add(arcLay);
1057
 
                    break;
1058
 
                case arcPin:
1059
 
                    curArc.arcPin = new ArcPin();
1060
 
                    curArc.arcPin.name = a("name");
1061
 
                    curArc.arcPin.portName = a("port");
1062
 
                    curArc.arcPin.elibSize = Double.valueOf(a("elibSize"));
 
908
                    ArcLayer arcLayer = new ArcLayer();
 
909
                    arcLayer.layer = a("layer");
 
910
                    curDistance = arcLayer.extend;
 
911
                    arcLayer.style = Poly.Type.valueOf(a("style"));
 
912
                    curArc.arcLayers.add(arcLayer);
1063
913
                    break;
1064
914
                case primitiveNode:
1065
915
                    curNode = new PrimitiveNode();
1102
952
                case od33:
1103
953
                    curNode.od33 = true;
1104
954
                    break;
1105
 
                case diskOffset:
1106
 
                    curNode.diskOffset = EPoint.fromLambda(Double.parseDouble(a("x")), Double.parseDouble(a("y")));
1107
 
                    break;
1108
 
                case defaultWidth:
1109
 
                    curDistance = curNode.defaultWidth;
1110
 
                    break;
1111
955
                case defaultHeight:
1112
956
                    curDistance = curNode.defaultHeight;
1113
957
                    break;
1114
 
                case nodeBase:
 
958
                case sizeOffset:
1115
959
                    double lx = Double.parseDouble(a("lx"));
1116
960
                    double hx = Double.parseDouble(a("hx"));
1117
961
                    double ly = Double.parseDouble(a("ly"));
1118
962
                    double hy = Double.parseDouble(a("hy"));
1119
 
                    curNode.nodeBase = ERectangle.fromLambda(lx, ly, hx - lx, hy - ly);
 
963
                    curNode.sizeOffset = new SizeOffset(lx, hx, ly, hy);
1120
964
                    break;
1121
965
                case nodeLayer:
1122
966
                    curNodeLayer = new NodeLayer();
1123
967
                    curNodeLayer.layer = a("layer");
1124
 
                    curNodeLayer.style = Type.valueOf(a("style"));
 
968
                    curNodeLayer.style = Poly.Type.valueOf(a("style"));
1125
969
                    String portNum = a_("portNum");
1126
970
                    if (portNum != null)
1127
971
                        curNodeLayer.portNum = Integer.parseInt(portNum);
1159
1003
                    curNodeLayer.hx.k = da_("khx", 1);
1160
1004
                    curNodeLayer.ly.k = da_("kly", -1);
1161
1005
                    curNodeLayer.hy.k = da_("khy", 1);
1162
 
                    curNodeLayer.sizeRule = a("sizeRule");
1163
 
                    curNodeLayer.sepRule = a("sepRule");
1164
 
                    curNodeLayer.sepRule2D = a_("sepRule2D");
 
1006
                    curNodeLayer.sizex = Double.parseDouble(a("sizex"));
 
1007
                    curNodeLayer.sizey = Double.parseDouble(a("sizey"));
 
1008
                    curNodeLayer.sep1d = Double.parseDouble(a("sep1d"));
 
1009
                    curNodeLayer.sep2d = Double.parseDouble(a("sep2d"));
1165
1010
                    break;
1166
1011
                case serpbox:
1167
1012
                    curNodeLayer.representation = com.sun.electric.technology.Technology.NodeLayer.BOX;
1176
1021
                    break;
1177
1022
                case lambdaBox:
1178
1023
                    if (curNodeLayer != null) {
1179
 
                        curNodeLayer.lx.addLambda(Double.parseDouble(a("klx")));
1180
 
                        curNodeLayer.hx.addLambda(Double.parseDouble(a("khx")));
1181
 
                        curNodeLayer.ly.addLambda(Double.parseDouble(a("kly")));
1182
 
                        curNodeLayer.hy.addLambda(Double.parseDouble(a("khy")));
 
1024
                        curNodeLayer.lx.value = Double.parseDouble(a("klx"));
 
1025
                        curNodeLayer.hx.value = Double.parseDouble(a("khx"));
 
1026
                        curNodeLayer.ly.value = Double.parseDouble(a("kly"));
 
1027
                        curNodeLayer.hy.value = Double.parseDouble(a("khy"));
1183
1028
                    }
1184
1029
                    if (curPort != null) {
1185
 
                        curPort.lx.addLambda(Double.parseDouble(a("klx")));
1186
 
                        curPort.hx.addLambda(Double.parseDouble(a("khx")));
1187
 
                        curPort.ly.addLambda(Double.parseDouble(a("kly")));
1188
 
                        curPort.hy.addLambda(Double.parseDouble(a("khy")));
 
1030
                        curPort.lx.value = Double.parseDouble(a("klx"));
 
1031
                        curPort.hx.value = Double.parseDouble(a("khx"));
 
1032
                        curPort.ly.value = Double.parseDouble(a("kly"));
 
1033
                        curPort.hy.value = Double.parseDouble(a("khy"));
1189
1034
                    }
1190
1035
                    break;
1191
1036
                case techPoint:
1230
1075
                case spiceLine:
1231
1076
                    curSpiceHeader.spiceLines.add(a("line"));
1232
1077
                    break;
1233
 
                    
1234
 
                case displayStyle:
1235
 
                    curDisplayStyle = new DisplayStyle();
1236
 
                    curDisplayStyle.name = a("name");
1237
 
                    tech.displayStyles.add(curDisplayStyle);
1238
 
                    break;
1239
 
                case transparentLayer:
1240
 
                    curTransparent = Integer.parseInt(a("transparent"));
1241
 
                    curR = curG = curB = 0;
1242
 
                    break;
1243
 
                case transparentColor:
1244
 
                    curTransparent = Integer.parseInt(a("transparent"));
1245
 
                    if (curTransparent > 0) {
1246
 
                        Color color = curDisplayStyle.transparentLayers.get(curTransparent - 1);
1247
 
                        curR = color.getRed();
1248
 
                        curG = color.getGreen();
1249
 
                        curB = color.getBlue();
1250
 
                    }
1251
 
                    break;
1252
 
                case opaqueColor:
1253
 
                    curR = Integer.parseInt(a("r"));
1254
 
                    curG = Integer.parseInt(a("g"));
1255
 
                    curB = Integer.parseInt(a("b"));
1256
 
                    break;
1257
 
                case display3D:
1258
 
                    curLayerDisplayStyle.mode3D = a("mode");
1259
 
                    curLayerDisplayStyle.factor3D = Double.parseDouble(a("factor"));
1260
 
                    break;
1261
 
                    
1262
1078
                case menuPalette:
1263
1079
                    tech.menuPalette = new MenuPalette();
1264
1080
                    tech.menuPalette.numColumns = Integer.parseInt(a("numColumns"));
1267
1083
                    curMenuBox = new ArrayList<Object>();
1268
1084
                    tech.menuPalette.menuBoxes.add(curMenuBox);
1269
1085
                    break;
1270
 
                case menuCell:
1271
 
                    curMenuCell = new MenuCell();
1272
 
                    curMenuCell.cellName = a("cellName");
1273
 
                    break;
1274
1086
                case menuNodeInst:
1275
1087
                    curMenuNodeInst = new MenuNodeInst();
1276
1088
                    curMenuNodeInst.protoName = a("protoName");
1282
1094
                    curMenuNodeInst.text = a("text");
1283
1095
                    curMenuNodeInst.fontSize = Double.parseDouble(a("size"));
1284
1096
                    break;
1285
 
                case rule:
1286
 
                    String kStr = a_("k");
1287
 
                    Layer layer = null;
1288
 
                    Layer layer2 = null;
1289
 
                    String layerStr = a_("layer");
1290
 
                    if (layerStr != null) {
1291
 
                        layer = tech.findLayer(layerStr);
1292
 
                        assert layer != null;
1293
 
                    }
1294
 
                    String layerStr2 = layerStr != null ? a_("layer2") : null;
1295
 
                    if (layerStr2 != null) {
1296
 
                        layer2 = tech.findLayer(layerStr2);
1297
 
                        assert layer2 != null;
1298
 
                    }
1299
 
                    curDistance.addRule(a("ruleName"), layer, layer2, kStr != null ? Double.valueOf(kStr) : 1);
1300
 
                    break;
1301
 
                case ruleSet:
1302
 
                    curRuleSet = tech.newRuleSet(a("ruleName"));
1303
 
                    break;
1304
 
                case layerRule:
1305
 
                    curLayerRule = curRuleSet.newLayerRule(a("ruleName"));
1306
 
                    break;
1307
1097
                case Foundry:
1308
1098
                    curFoundry = new Foundry();
1309
1099
                    curFoundry.name = a("name");
1388
1178
                    case description:
1389
1179
                        tech.description = text;
1390
1180
                        break;
 
1181
                    case r:
 
1182
                        curR = Integer.parseInt(text);
 
1183
                        break;
 
1184
                    case g:
 
1185
                        curG = Integer.parseInt(text);
 
1186
                        break;
 
1187
                    case b:
 
1188
                        curB = Integer.parseInt(text);
 
1189
                        break;
 
1190
                    case patternedOnDisplay:
 
1191
                        patternedOnDisplay = Boolean.parseBoolean(text);
 
1192
                        break;
 
1193
                    case patternedOnPrinter:
 
1194
                        patternedOnPrinter = Boolean.parseBoolean(text);
 
1195
                        break;
 
1196
                    case pattern:
 
1197
                        int p = 0;
 
1198
                        assert text.length() == 16;
 
1199
                        for (int j = 0; j < text.length(); j++) {
 
1200
                            if (text.charAt(text.length() - j - 1) != ' ')
 
1201
                                p |= (1 << j);
 
1202
                        }
 
1203
                        pattern[curPatternIndex++] = p;
 
1204
                        break;
 
1205
                    case outlined:
 
1206
                        outline = EGraphics.Outline.valueOf(text);
 
1207
                        break;
 
1208
                    case opacity:
 
1209
                        opacity = Double.parseDouble(text);
 
1210
                        break;
 
1211
                    case foreground:
 
1212
                        foreground = Boolean.parseBoolean(text);
 
1213
                        break;
1391
1214
                    case oldName:
1392
1215
                        if (curLayer != null)
1393
1216
                            curLayer.pureLayerNode.oldName = text;
1411
1234
                    case antennaRatio:
1412
1235
                        curArc.antennaRatio = Double.parseDouble(text);
1413
1236
                        break;
1414
 
                    case elibWidthOffset:
1415
 
                        curArc.elibWidthOffset = Double.parseDouble(text);
1416
 
                        break;
1417
1237
                    case portTopology:
1418
1238
                        curPort.portTopology = Integer.parseInt(text);
1419
1239
                        break;
1420
1240
                    case portArc:
1421
1241
                        if (curLayer != null && curLayer.pureLayerNode != null)
1422
1242
                            curLayer.pureLayerNode.portArcs.add(text);
1423
 
                        if (curArc != null && curArc.arcPin != null)
1424
 
                            curArc.arcPin.portArcs.add(text);
1425
1243
                        if (curPort != null)
1426
1244
                            curPort.portArcs.add(text);
1427
1245
                        break;
1428
1246
                    case specialValue:
1429
1247
                        curNode.specialValues[curSpecialValueIndex++] = Double.parseDouble(text);
1430
1248
                        break;
1431
 
                        
1432
 
                    case r:
1433
 
                        curR = Integer.parseInt(text);
1434
 
                        break;
1435
 
                    case g:
1436
 
                        curG = Integer.parseInt(text);
1437
 
                        break;
1438
 
                    case b:
1439
 
                        curB = Integer.parseInt(text);
1440
 
                        break;
1441
 
                    case patternedOnDisplay:
1442
 
                        patternedOnDisplay = Boolean.parseBoolean(text);
1443
 
                        break;
1444
 
                    case patternedOnPrinter:
1445
 
                        patternedOnPrinter = Boolean.parseBoolean(text);
1446
 
                        break;
1447
 
                    case pattern:
1448
 
                        int p = 0;
1449
 
                        assert text.length() == 16;
1450
 
                        for (int j = 0; j < text.length(); j++) {
1451
 
                            if (text.charAt(text.length() - j - 1) != ' ')
1452
 
                                p |= (1 << j);
1453
 
                        }
1454
 
                        pattern[curPatternIndex++] = p;
1455
 
                        break;
1456
 
                    case outlined:
1457
 
                        outline = EGraphics.Outline.valueOf(text);
1458
 
                        break;
1459
 
                    case opacity:
1460
 
                        opacity = Double.parseDouble(text);
1461
 
                        break;
1462
 
                    case foreground:
1463
 
                        foreground = Boolean.parseBoolean(text);
1464
 
                        break;
1465
 
                        
1466
1249
                    case menuArc:
1467
1250
                        curMenuBox.add(tech.findArc(text));
1468
1251
                        break;
1484
1267
            switch (key) {
1485
1268
                case technology:
1486
1269
                    break;
 
1270
                case transparentLayer:
 
1271
                    while (curTransparent > tech.transparentLayers.size())
 
1272
                        tech.transparentLayers.add(null);
 
1273
                    Color oldColor = tech.transparentLayers.set(curTransparent - 1, new Color(curR, curG, curB));
 
1274
                    assert oldColor == null;
 
1275
                    break;
1487
1276
                case layer:
1488
 
                    if (curDisplayStyle != null) {
1489
 
                        assert curPatternIndex == pattern.length;
1490
 
                        curLayerDisplayStyle.desc = new EGraphics(patternedOnDisplay, patternedOnPrinter, outline, curTransparent,
 
1277
                    assert curPatternIndex == pattern.length;
 
1278
                    curLayer.desc = new EGraphics(patternedOnDisplay, patternedOnPrinter, outline, curTransparent,
1491
1279
                            curR, curG, curB, opacity, foreground, pattern.clone());
1492
 
                        curLayerDisplayStyle = null;
1493
 
                    } else if (curLayerRule != null) {
1494
 
                        curDistance = null;
1495
 
                    } else {
1496
 
                        curLayer = null;
1497
 
                    }
 
1280
                    assert tech.findLayer(curLayer.name) == null;
 
1281
                    tech.layers.add(curLayer);
 
1282
                    curLayer = null;
1498
1283
                    break;
1499
1284
                case arcProto:
1500
1285
                    tech.arcs.add(curArc);
1516
1301
                        curMenuBox.add(curMenuNodeInst);
1517
1302
                    curMenuNodeInst = null;
1518
1303
                    break;
1519
 
                    
1520
 
                case displayStyle:
1521
 
                    curDisplayStyle = null;
1522
 
                    break;
1523
 
                case transparentLayer:
1524
 
                    while (curTransparent > curDisplayStyle.transparentLayers.size())
1525
 
                        curDisplayStyle.transparentLayers.add(null);
1526
 
                    Color oldColor = curDisplayStyle.transparentLayers.set(curTransparent - 1, new Color(curR, curG, curB));
1527
 
                    assert oldColor == null;
1528
 
                    break;
1529
 
                    
1530
 
                case menuCell:
1531
 
                        curMenuBox.add("LOADCELL " + curMenuCell.cellName);
1532
 
//                      curMenuBox.add(curMenuCell);
1533
 
                    curMenuCell = null;
1534
 
                    break;
1535
 
                    
1536
 
                case ruleSet:
1537
 
                    curRuleSet = null;
1538
 
                    break;
1539
 
                case layerRule:
1540
 
                    curLayerRule = null;
1541
 
                    break;
1542
1304
 
 
1305
                case version:
 
1306
                case spiceHeader:
1543
1307
                case numMetals:
1544
1308
                case scale:
1545
1309
                case defaultFoundry:
1546
1310
                case minResistance:
1547
1311
                case minCapacitance:
 
1312
                case transparentColor:
 
1313
                case opaqueColor:
 
1314
                case display3D:
1548
1315
                case cifLayer:
1549
1316
                case skillLayer:
1550
1317
                case parasitics:
1555
1322
                case special:
1556
1323
                case notUsed:
1557
1324
                case skipSizeInPalette:
 
1325
                case diskOffset:
 
1326
                case defaultWidth:
1558
1327
                case arcLayer:
1559
 
                case arcPin:
1560
1328
 
1561
1329
                case shrinkArcs:
1562
1330
                case square:
1570
1338
                case od18:
1571
1339
                case od25:
1572
1340
                case od33:
1573
 
                case diskOffset:
1574
1341
 
1575
 
                case defaultWidth:
1576
1342
                case defaultHeight:
1577
 
                case nodeBase:
 
1343
                case sizeOffset:
1578
1344
                case box:
1579
1345
                case points:
1580
1346
                case multicutbox:
1585
1351
                case polygonal:
1586
1352
                case serpTrans:
1587
1353
                case minSizeRule:
1588
 
                    
1589
 
                case spiceHeader:
1590
1354
                case spiceLine:
1591
1355
                case spiceTemplate:
1592
 
                    
1593
 
                case transparentColor:
1594
 
                case opaqueColor:
1595
 
                case display3D:
1596
 
                    
1597
1356
                case menuPalette:
1598
1357
                case menuBox:
1599
1358
                case menuNodeText:
1600
 
                case rule:
1601
1359
                case Foundry:
1602
1360
                case layerGds:
1603
1361
                case LayerRule:
1794
1552
            this.out = out;
1795
1553
        }
1796
1554
 
1797
 
        private void writeTechnology(Technology t) {
 
1555
        private void writeTechnology(Xml807.Technology t) {
1798
1556
            Calendar cal = Calendar.getInstance();
1799
1557
            cal.setTime(new Date());
1800
1558
 
1832
1590
            b(XmlKeyword.technology); a("name", t.techName); a("class", t.className); l();
1833
1591
            a("xmlns", "http://electric.sun.com/Technology"); l();
1834
1592
            a("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); l();
1835
 
            a("xsi:schemaLocation", "http://electric.sun.com/Technology ../../technology/xml/Technology807.xsd"); cl();
 
1593
            a("xsi:schemaLocation", "http://electric.sun.com/Technology ../../technology/Technology.xsd"); cl();
1836
1594
            l();
1837
1595
 
1838
1596
            bcpel(XmlKeyword.shortName, t.shortTechName);
1839
1597
            bcpel(XmlKeyword.description, t.description);
 
1598
            for (Version version: t.versions) {
 
1599
                b(XmlKeyword.version); a("tech", version.techVersion); a("electric", version.electricVersion); el();
 
1600
            }
1840
1601
            b(XmlKeyword.numMetals); a("min", t.minNumMetals); a("max", t.maxNumMetals); a("default", t.defaultNumMetals); el();
1841
1602
            b(XmlKeyword.scale); a("value", t.scaleValue); a("relevant", t.scaleRelevant); el();
1842
1603
            b(XmlKeyword.defaultFoundry); a("value", t.defaultFoundry); el();
1847
1608
//        printlnAttribute("  groundNetInclusion", gi.includeGround);
1848
1609
            l();
1849
1610
 
 
1611
            if (t.transparentLayers.size() != 0) {
 
1612
                comment("Transparent layers");
 
1613
                for (int i = 0; i < t.transparentLayers.size(); i++) {
 
1614
                    Color color = t.transparentLayers.get(i);
 
1615
                    b(XmlKeyword.transparentLayer); a("transparent", i + 1); cl();
 
1616
                    bcpel(XmlKeyword.r, color.getRed());
 
1617
                    bcpel(XmlKeyword.g, color.getGreen());
 
1618
                    bcpel(XmlKeyword.b, color.getBlue());
 
1619
                    el(XmlKeyword.transparentLayer);
 
1620
                }
 
1621
                l();
 
1622
            }
 
1623
 
1850
1624
            comment("**************************************** LAYERS ****************************************");
1851
 
            for (Layer li: t.layers.values()) {
 
1625
            for (Xml807.Layer li: t.layers) {
1852
1626
                writeXml(li);
1853
1627
            }
1854
1628
 
1855
1629
            comment("******************** ARCS ********************");
1856
 
            for (ArcProto ai: t.arcs) {
 
1630
            for (Xml807.ArcProto ai: t.arcs) {
1857
1631
                writeXml(ai);
1858
1632
                l();
1859
1633
            }
1860
1634
 
1861
1635
            comment("******************** NODES ********************");
1862
 
            for (PrimitiveNode ni: t.nodes) {
 
1636
            for (Xml807.PrimitiveNode ni: t.nodes) {
1863
1637
                writeXml(ni);
1864
1638
                l();
1865
1639
            }
1866
1640
 
1867
 
            for (SpiceHeader spiceHeader: t.spiceHeaders)
 
1641
            for (Xml807.SpiceHeader spiceHeader: t.spiceHeaders)
1868
1642
                writeSpiceHeaderXml(spiceHeader);
1869
 
            
1870
 
            for (DisplayStyle displayStyle: t.displayStyles)
1871
 
                writeDisplayStyleXml(displayStyle);
1872
1643
 
1873
1644
            writeMenuPaletteXml(t.menuPalette);
1874
1645
 
1875
 
            for (RuleSet ruleSet: t.ruleSets.values())
1876
 
                writeXml(ruleSet);
1877
 
            
1878
 
            for (Foundry foundry: t.foundries)
 
1646
            for (Xml807.Foundry foundry: t.foundries)
1879
1647
                writeFoundryXml(foundry);
1880
1648
 
1881
1649
            el(XmlKeyword.technology);
1882
1650
        }
1883
1651
 
1884
 
        private void writeXml(Layer li) {
 
1652
        private void writeXml(Xml807.Layer li) {
 
1653
            EGraphics desc = li.desc;
1885
1654
            String funString = null;
1886
1655
            int funExtra = li.extraFunction;
1887
1656
            if (funExtra != 0) {
1897
1666
            }
1898
1667
            b(XmlKeyword.layer); a("name", li.name); a("fun", li.function.name()); a("extraFun", funString); cl();
1899
1668
 
 
1669
            if (desc.getTransparentLayer() > 0) {
 
1670
                b(XmlKeyword.transparentColor); a("transparent", desc.getTransparentLayer()); el();
 
1671
            } else {
 
1672
                Color color = desc.getColor();
 
1673
                b(XmlKeyword.opaqueColor); a("r", color.getRed()); a("g", color.getGreen()); a("b", color.getBlue()); el();
 
1674
            }
 
1675
 
 
1676
            bcpel(XmlKeyword.patternedOnDisplay, desc.isPatternedOnDisplay());
 
1677
            bcpel(XmlKeyword.patternedOnPrinter, desc.isPatternedOnPrinter());
 
1678
 
 
1679
            int [] pattern = desc.getPattern();
 
1680
            for(int j=0; j<16; j++) {
 
1681
                String p = "";
 
1682
                for(int k=0; k<16; k++)
 
1683
                    p += (pattern[j] & (1 << (15-k))) != 0 ? 'X' : ' ';
 
1684
                bcpel(XmlKeyword.pattern, p);
 
1685
            }
 
1686
 
 
1687
            if (li.desc.getOutlined() != null)
 
1688
                bcpel(XmlKeyword.outlined, desc.getOutlined().getConstName());
 
1689
            bcpel(XmlKeyword.opacity, desc.getOpacity());
 
1690
            bcpel(XmlKeyword.foreground, desc.getForeground());
 
1691
 
 
1692
            // write the 3D information
 
1693
            if (li.thick3D != 0 || li.height3D != 0 || li.mode3D != null) {
 
1694
                b(XmlKeyword.display3D); a("thick", li.thick3D); a("height", li.height3D);
 
1695
                if (li.mode3D != null) {
 
1696
                    a("mode", li.mode3D); a("factor", li.factor3D);
 
1697
                }
 
1698
                el();
 
1699
            }
 
1700
 
1900
1701
            if (li.cif != null && li.cif.length() > 0) {
1901
1702
                b(XmlKeyword.cifLayer); a("cif", li.cif); el();
1902
1703
            }
1910
1711
            }
1911
1712
            if (li.pureLayerNode != null) {
1912
1713
                String nodeName = li.pureLayerNode.name;
1913
 
                Type style = li.pureLayerNode.style;
1914
 
                String styleStr = style == Type.FILLED ? null : style.name();
 
1714
                Poly.Type style = li.pureLayerNode.style;
 
1715
                String styleStr = style == Poly.Type.FILLED ? null : style.name();
1915
1716
                String portName = li.pureLayerNode.port;
1916
 
                b(XmlKeyword.pureLayerNode); a("name", nodeName); a("style", styleStr); a("port", portName);
1917
 
                if (li.pureLayerNode.oldName == null && li.pureLayerNode.portArcs.isEmpty()) {
1918
 
                    el();
1919
 
                } else {
1920
 
                    cl();
1921
 
                    bcpel(XmlKeyword.oldName, li.pureLayerNode.oldName);
1922
 
                    for (String portArc: li.pureLayerNode.portArcs)
1923
 
                        bcpel(XmlKeyword.portArc, portArc);
1924
 
                    el(XmlKeyword.pureLayerNode);
1925
 
                }
 
1717
                b(XmlKeyword.pureLayerNode); a("name", nodeName); a("style", styleStr); a("port", portName); cl();
 
1718
                bcpel(XmlKeyword.oldName, li.pureLayerNode.oldName);
 
1719
                bcpel(XmlKeyword.lambda, li.pureLayerNode.size.value);
 
1720
                for (String portArc: li.pureLayerNode.portArcs)
 
1721
                    bcpel(XmlKeyword.portArc, portArc);
 
1722
                el(XmlKeyword.pureLayerNode);
1926
1723
            }
1927
1724
            el(XmlKeyword.layer);
1928
1725
            l();
1929
1726
        }
1930
1727
 
1931
 
        private void writeXml(ArcProto ai) {
 
1728
        private void writeXml(Xml807.ArcProto ai) {
1932
1729
            b(XmlKeyword.arcProto); a("name", ai.name); a("fun", ai.function.getConstantName()); cl();
1933
1730
            bcpel(XmlKeyword.oldName, ai.oldName);
1934
1731
 
1947
1744
            bcpel(XmlKeyword.angleIncrement, ai.angleIncrement);
1948
1745
            if (ai.antennaRatio != 0)
1949
1746
                bcpel(XmlKeyword.antennaRatio, ai.antennaRatio);
1950
 
            if (ai.elibWidthOffset != 0)
1951
 
                bcpel(XmlKeyword.elibWidthOffset, ai.elibWidthOffset);
1952
 
 
1953
 
            for (ArcLayer al: ai.arcLayers) {
1954
 
                String style = al.style == Type.FILLED ? "FILLED" : "CLOSED";
 
1747
 
 
1748
            for (Map.Entry<Integer,Double> e: ai.diskOffset.entrySet()) {
 
1749
                b(XmlKeyword.diskOffset); a("untilVersion", e.getKey()); a("width", e.getValue()); el();
 
1750
            }
 
1751
 
 
1752
            if (ai.defaultWidth.value != 0) {
 
1753
                bcl(XmlKeyword.defaultWidth);
 
1754
                bcpel(XmlKeyword.lambda, ai.defaultWidth.value);
 
1755
                el(XmlKeyword.defaultWidth);
 
1756
            }
 
1757
 
 
1758
            for (Xml807.ArcLayer al: ai.arcLayers) {
 
1759
                String style = al.style == Poly.Type.FILLED ? "FILLED" : "CLOSED";
1955
1760
                b(XmlKeyword.arcLayer); a("layer", al.layer); a("style", style);
1956
 
                if (al.extend.isEmpty()) {
 
1761
                double extend = al.extend.value;
 
1762
                if (extend == 0) {
1957
1763
                    el();
1958
1764
                } else {
1959
1765
                    cl();
1960
 
                    writeDistance(al.extend);
 
1766
                    bcpel(XmlKeyword.lambda, extend);
1961
1767
                    el(XmlKeyword.arcLayer);
1962
1768
                }
1963
1769
            }
1964
 
            if (ai.arcPin != null) {
1965
 
                b(XmlKeyword.arcPin); a("name", ai.arcPin.name); a("port", ai.arcPin.portName); a("elibSize", ai.arcPin.elibSize);
1966
 
                if (ai.arcPin.portArcs.isEmpty()) {
1967
 
                    el();
1968
 
                } else {
1969
 
                    cl();
1970
 
                    for (String portArc: ai.arcPin.portArcs)
1971
 
                        bcpel(XmlKeyword.portArc, portArc);
1972
 
                    el(XmlKeyword.arcPin);
1973
 
                }
1974
 
            }
1975
1770
            el(XmlKeyword.arcProto);
1976
1771
        }
1977
1772
 
1978
 
        private void writeXml(PrimitiveNode ni) {
 
1773
        private void writeXml(Xml807.PrimitiveNode ni) {
1979
1774
            b(XmlKeyword.primitiveNode); a("name", ni.name); a("fun", ni.function.name()); cl();
1980
1775
            bcpel(XmlKeyword.oldName, ni.oldName);
1981
1776
 
2008
1803
            if (ni.od33)
2009
1804
                bel(XmlKeyword.od33);
2010
1805
 
2011
 
            if (ni.diskOffset != null) {
2012
 
                b(XmlKeyword.diskOffset); a("x", ni.diskOffset.getLambdaX()); a("y", ni.diskOffset.getLambdaY()); el();
 
1806
            for (Map.Entry<Integer,EPoint> e: ni.diskOffset.entrySet()) {
 
1807
                EPoint p = e.getValue();
 
1808
                b(XmlKeyword.diskOffset); a("untilVersion", e.getKey()); a("x", p.getLambdaX()); a("y", p.getLambdaY()); el();
2013
1809
            }
2014
1810
 
2015
 
            if (!ni.defaultWidth.isEmpty()) {
 
1811
            if (ni.defaultWidth.value != 0) {
2016
1812
                bcl(XmlKeyword.defaultWidth);
2017
 
                writeDistance(ni.defaultWidth);
 
1813
                bcpel(XmlKeyword.lambda, ni.defaultWidth.value);
2018
1814
                el(XmlKeyword.defaultWidth);
2019
1815
            }
2020
1816
 
2021
 
            if (!ni.defaultHeight.isEmpty()) {
 
1817
            if (ni.defaultHeight.value != 0) {
2022
1818
                bcl(XmlKeyword.defaultHeight);
2023
 
                writeDistance(ni.defaultHeight);
 
1819
                bcpel(XmlKeyword.lambda, ni.defaultHeight.value);
2024
1820
                el(XmlKeyword.defaultHeight);
2025
1821
            }
2026
1822
 
2027
 
            if (ni.nodeBase != null) {
2028
 
                double lx = ni.nodeBase.getLambdaMinX();
2029
 
                double hx = ni.nodeBase.getLambdaMaxX();
2030
 
                double ly = ni.nodeBase.getLambdaMinY();
2031
 
                double hy = ni.nodeBase.getLambdaMaxY();
2032
 
                b(XmlKeyword.nodeBase); a("lx", lx); a("hx", hx); a("ly", ly); a("hy", hy); el();
 
1823
            if (ni.sizeOffset != null) {
 
1824
                double lx = ni.sizeOffset.getLowXOffset();
 
1825
                double hx = ni.sizeOffset.getHighXOffset();
 
1826
                double ly = ni.sizeOffset.getLowYOffset();
 
1827
                double hy = ni.sizeOffset.getHighYOffset();
 
1828
                b(XmlKeyword.sizeOffset); a("lx", lx); a("hx", hx); a("ly", ly); a("hy", hy); el();
2033
1829
            }
2034
1830
 
2035
1831
            for(int j=0; j<ni.nodeLayers.size(); j++) {
2036
 
                NodeLayer nl = ni.nodeLayers.get(j);
 
1832
                Xml807.NodeLayer nl = ni.nodeLayers.get(j);
2037
1833
                b(XmlKeyword.nodeLayer); a("layer", nl.layer); a("style", nl.style.name());
2038
1834
                if (nl.portNum != 0) a("portNum", Integer.valueOf(nl.portNum));
2039
1835
                if (!(nl.inLayers && nl.inElectricalLayers))
2044
1840
                        if (ni.specialType == com.sun.electric.technology.PrimitiveNode.SERPTRANS) {
2045
1841
                            writeBox(XmlKeyword.serpbox, nl.lx, nl.hx, nl.ly, nl.hy);
2046
1842
                            a("lWidth", nl.lWidth); a("rWidth", nl.rWidth); a("tExtent", nl.tExtent); a("bExtent", nl.bExtent); cl();
2047
 
                            writeLambdaBox(nl.lx, nl.hx, nl.ly, nl.hy);
 
1843
                            b(XmlKeyword.lambdaBox); a("klx", nl.lx.value); a("khx", nl.hx.value); a("kly", nl.ly.value); a("khy", nl.hy.value); el();
2048
1844
                            el(XmlKeyword.serpbox);
2049
1845
                        } else {
2050
1846
                            writeBox(XmlKeyword.box, nl.lx, nl.hx, nl.ly, nl.hy); cl();
2051
 
                            writeLambdaBox(nl.lx, nl.hx, nl.ly, nl.hy);
 
1847
                            b(XmlKeyword.lambdaBox); a("klx", nl.lx.value); a("khx", nl.hx.value); a("kly", nl.ly.value); a("khy", nl.hy.value); el();
2052
1848
                            el(XmlKeyword.box);
2053
1849
                        }
2054
1850
                        break;
2057
1853
                        break;
2058
1854
                    case com.sun.electric.technology.Technology.NodeLayer.MULTICUTBOX:
2059
1855
                        writeBox(XmlKeyword.multicutbox, nl.lx, nl.hx, nl.ly, nl.hy);
2060
 
                        a("sizeRule", nl.sizeRule); a("sepRule", nl.sepRule); a("sepRule2D", nl.sepRule2D);
2061
 
                        if (nl.lx.isEmpty() && nl.hx.isEmpty() && nl.ly.isEmpty() && nl.hy.isEmpty()) {
2062
 
                            el();
2063
 
                        } else {
2064
 
                            cl();
2065
 
                            writeLambdaBox(nl.lx, nl.hx, nl.ly, nl.hy);
2066
 
                            el(XmlKeyword.multicutbox);
2067
 
                        }
 
1856
                        a("sizex", nl.sizex); a("sizey", nl.sizey); a("sep1d", nl.sep1d);  a("sep2d", nl.sep2d); cl();
 
1857
                        b(XmlKeyword.lambdaBox); a("klx", nl.lx.value); a("khx", nl.hx.value); a("kly", nl.ly.value); a("khy", nl.hy.value); el();
 
1858
                        el(XmlKeyword.multicutbox);
2068
1859
                        break;
2069
1860
                }
2070
1861
                for (TechPoint tp: nl.techPoints) {
2077
1868
                el(XmlKeyword.nodeLayer);
2078
1869
            }
2079
1870
            for (int j = 0; j < ni.ports.size(); j++) {
2080
 
                PrimitivePort pd = ni.ports.get(j);
 
1871
                Xml807.PrimitivePort pd = ni.ports.get(j);
2081
1872
                b(XmlKeyword.primitivePort); a("name", pd.name); cl();
2082
1873
                b(XmlKeyword.portAngle); a("primary", pd.portAngle); a("range", pd.portRange); el();
2083
1874
                bcpel(XmlKeyword.portTopology, pd.portTopology);
2084
1875
 
2085
1876
                writeBox(XmlKeyword.box, pd.lx, pd.hx, pd.ly, pd.hy); cl();
2086
 
                writeLambdaBox(pd.lx, pd.hx, pd.ly, pd.hy);
 
1877
                b(XmlKeyword.lambdaBox); a("klx", pd.lx.value); a("khx", pd.hx.value); a("kly", pd.ly.value); a("khy", pd.hy.value); el();
2087
1878
                el(XmlKeyword.box);
2088
1879
 
2089
1880
                for (String portArc: pd.portArcs)
2114
1905
            el(XmlKeyword.primitiveNode);
2115
1906
        }
2116
1907
 
2117
 
        private void writeDistance(Distance d) {
2118
 
            d.writeXml(this, true);
2119
 
        }
2120
 
 
2121
1908
        private void writeBox(XmlKeyword keyword, Distance lx, Distance hx, Distance ly, Distance hy) {
2122
1909
            b(keyword);
2123
1910
            if (lx.k != -1) a("klx", lx.k);
2126
1913
            if (hy.k != 1) a("khy", hy.k);
2127
1914
        }
2128
1915
 
2129
 
        private void writeLambdaBox(Distance lx, Distance hx, Distance ly, Distance hy) {
2130
 
            double lxv = lx.getLambda(EMPTY_CONTEXT);
2131
 
            double hxv = hx.getLambda(EMPTY_CONTEXT);
2132
 
            double lyv = ly.getLambda(EMPTY_CONTEXT);
2133
 
            double hyv = hy.getLambda(EMPTY_CONTEXT);
2134
 
//            if (lxv == 0 && hxv == 0 && lyv == 0 && hyv == 0) return;
2135
 
            b(XmlKeyword.lambdaBox); a("klx", lxv); a("khx", hxv); a("kly", lyv); a("khy", hyv); el();
2136
 
        }
2137
 
 
2138
 
        private void writeSpiceHeaderXml(SpiceHeader spiceHeader) {
 
1916
        private void writeSpiceHeaderXml(Xml807.SpiceHeader spiceHeader) {
2139
1917
            b(XmlKeyword.spiceHeader); a("level", spiceHeader.level); cl();
2140
1918
            for (String line: spiceHeader.spiceLines) {
2141
1919
                b(XmlKeyword.spiceLine); a("line", line); el();
2143
1921
            el(XmlKeyword.spiceHeader);
2144
1922
            l();
2145
1923
        }
2146
 
        
2147
 
        private void writeDisplayStyleXml(DisplayStyle displayStyle) {
2148
 
            b(XmlKeyword.displayStyle); a("name", displayStyle.name); cl();
2149
 
            
2150
 
            if (displayStyle.transparentLayers.size() != 0) {
2151
 
                comment("Transparent layers");
2152
 
                for (int i = 0; i < displayStyle.transparentLayers.size(); i++) {
2153
 
                    Color color = displayStyle.transparentLayers.get(i);
2154
 
                    b(XmlKeyword.transparentLayer); a("transparent", i + 1); cl();
2155
 
                    bcpel(XmlKeyword.r, color.getRed());
2156
 
                    bcpel(XmlKeyword.g, color.getGreen());
2157
 
                    bcpel(XmlKeyword.b, color.getBlue());
2158
 
                    el(XmlKeyword.transparentLayer);
2159
 
                }
2160
 
                l();
2161
 
            }
2162
 
            
2163
 
            for (LayerDisplayStyle l: displayStyle.layerStyles.values()) {
2164
 
                b(XmlKeyword.layer); a("name", l.layer.name); cl();
2165
 
                EGraphics desc = l.desc;
2166
 
                if (desc.getTransparentLayer() > 0) {
2167
 
                    b(XmlKeyword.transparentColor); a("transparent", desc.getTransparentLayer()); el();
2168
 
                } else {
2169
 
                    Color color = desc.getColor();
2170
 
                    b(XmlKeyword.opaqueColor); a("r", color.getRed()); a("g", color.getGreen()); a("b", color.getBlue()); el();
2171
 
                }
2172
 
 
2173
 
                bcpel(XmlKeyword.patternedOnDisplay, desc.isPatternedOnDisplay());
2174
 
                bcpel(XmlKeyword.patternedOnPrinter, desc.isPatternedOnPrinter());
2175
 
 
2176
 
                int [] pattern = desc.getPattern();
2177
 
                for(int j=0; j<16; j++) {
2178
 
                    String p = "";
2179
 
                    for(int k=0; k<16; k++)
2180
 
                        p += (pattern[j] & (1 << (15-k))) != 0 ? 'X' : ' ';
2181
 
                    bcpel(XmlKeyword.pattern, p);
2182
 
                }
2183
 
 
2184
 
                if (desc.getOutlined() != null)
2185
 
                    bcpel(XmlKeyword.outlined, desc.getOutlined().getConstName());
2186
 
                bcpel(XmlKeyword.opacity, desc.getOpacity());
2187
 
                bcpel(XmlKeyword.foreground, desc.getForeground());
2188
 
                
2189
 
                // write the 3D information
2190
 
                if (l.mode3D != null) {
2191
 
                    b(XmlKeyword.display3D); a("mode", l.mode3D); a("factor", l.factor3D); el();
2192
 
                }
2193
 
 
2194
 
                el(XmlKeyword.layer);
2195
 
            }
2196
 
 
2197
 
            el(XmlKeyword.displayStyle);
2198
 
            l();
2199
 
        }
2200
 
 
2201
 
        public void writeMenuPaletteXml(MenuPalette menuPalette) {
 
1924
 
 
1925
        public void writeMenuPaletteXml(Xml807.MenuPalette menuPalette) {
2202
1926
            if (menuPalette == null) return;
2203
1927
            b(XmlKeyword.menuPalette); a("numColumns", menuPalette.numColumns); cl();
2204
1928
            for (int i = 0; i < menuPalette.menuBoxes.size(); i++) {
2219
1943
            }
2220
1944
            cl();
2221
1945
            for (Object o: list) {
2222
 
                if (o instanceof ArcProto) {
2223
 
                    bcpel(XmlKeyword.menuArc, ((ArcProto)o).name);
2224
 
                } else if (o instanceof PrimitiveNode) {
2225
 
                    bcpel(XmlKeyword.menuNode, ((PrimitiveNode)o).name);
2226
 
                } else if (o instanceof MenuCell) {
2227
 
                    MenuCell cell = (MenuCell)o;
2228
 
                    b(XmlKeyword.menuCell); a("cellName", cell.cellName); el();
2229
 
                } else if (o instanceof MenuNodeInst) {
2230
 
                    MenuNodeInst ni = (MenuNodeInst)o;
 
1946
                if (o instanceof Xml807.ArcProto) {
 
1947
                    bcpel(XmlKeyword.menuArc, ((Xml807.ArcProto)o).name);
 
1948
                } else if (o instanceof Xml807.PrimitiveNode) {
 
1949
                    bcpel(XmlKeyword.menuNode, ((Xml807.PrimitiveNode)o).name);
 
1950
                } else if (o instanceof Xml807.MenuNodeInst) {
 
1951
                    Xml807.MenuNodeInst ni = (Xml807.MenuNodeInst)o;
2231
1952
                    b(XmlKeyword.menuNodeInst); a("protoName", ni.protoName); a("function", ni.function.name());
2232
1953
                    if (ni.rotation != 0) a("rotation", ni.rotation);
2233
1954
                    if (ni.text == null) {
2244
1965
            }
2245
1966
            el(XmlKeyword.menuBox);
2246
1967
        }
2247
 
        
2248
 
        private void writeXml(RuleSet ruleSet) {
2249
 
            b(XmlKeyword.ruleSet); a("name", ruleSet.name); cl();
2250
 
            for (Map.Entry<String,Map<Layer,Distance>> e: ruleSet.layerRules.entrySet())
2251
 
                writeLayerRuleXml(e.getKey(), e.getValue());
2252
 
            el(XmlKeyword.ruleSet);
2253
 
            l();
2254
 
        }
2255
 
        
2256
 
        private void writeLayerRuleXml(String ruleName, Map<Layer,Distance> sizes) {
2257
 
            if (sizes.isEmpty()) return;
2258
 
            b(XmlKeyword.layerRule); a("ruleName", ruleName); cl();
2259
 
            int maxNameLength = 0;
2260
 
            for (Layer l: sizes.keySet())
2261
 
                maxNameLength = Math.max(maxNameLength, l.name.length());
2262
 
            for (Map.Entry<Layer,Distance> e: sizes.entrySet()) {
2263
 
                String layerName = e.getKey().name;
2264
 
                Distance d = e.getValue();
2265
 
                b(XmlKeyword.layer); a("name", layerName); c();
2266
 
                s(maxNameLength - layerName.length());
2267
 
                d.writeXml(this, false);
2268
 
                el(XmlKeyword.layer);
2269
 
            }
2270
 
            el(XmlKeyword.layerRule);
2271
 
        }
2272
1968
 
2273
 
        private void writeFoundryXml(Foundry foundry) {
 
1969
        private void writeFoundryXml(Xml807.Foundry foundry) {
2274
1970
            b(XmlKeyword.Foundry); a("name", foundry.name); cl();
2275
1971
            l();
2276
1972
            for (Map.Entry<String,String> e: foundry.layerGds.entrySet()) {
2303
1999
            out.print("\"");
2304
2000
        }
2305
2001
 
2306
 
        private void bcpe(XmlKeyword key, Object v) {
2307
 
            if (v == null) return;
2308
 
            b(key); c(); p(v.toString()); e(key);
2309
 
        }
2310
 
 
2311
2002
        private void bcpel(XmlKeyword key, Object v) {
2312
2003
            if (v == null) return;
2313
2004
            b(key); c(); p(v.toString()); el(key);
2383
2074
            e(); l();
2384
2075
        }
2385
2076
 
2386
 
        private void el(XmlKeyword key) {
2387
 
            e(key); l();
2388
 
        }
2389
 
 
2390
2077
        private void e() {
2391
2078
            assert indentEmitted;
2392
2079
            out.print("/>");
2393
2080
            indent -= INDENT_WIDTH;
2394
2081
        }
2395
2082
 
2396
 
        private void e(XmlKeyword key) {
 
2083
        private void el(XmlKeyword key) {
2397
2084
            indent -= INDENT_WIDTH;
2398
2085
            checkIndent();
2399
2086
            out.print("</");
2400
2087
            out.print(key.name());
2401
2088
            out.print(">");
 
2089
            l();
2402
2090
        }
2403
2091
 
2404
2092
        protected void checkIndent() {
2405
2093
            if (indentEmitted) return;
2406
 
            s(indent);
 
2094
            for (int i = 0; i < indent; i++)
 
2095
                out.print(' ');
2407
2096
            indentEmitted = true;
2408
2097
        }
2409
 
        
2410
 
        protected void s(int numSpaces) {
2411
 
            for (int i = 0; i < numSpaces; i++)
2412
 
                out.print(' ');
2413
 
        }
2414
2098
 
2415
2099
        /**
2416
2100
         *  Print new line.
2421
2105
        }
2422
2106
    }
2423
2107
 
2424
 
    public static DistanceContext EMPTY_CONTEXT = new DistanceContext() {
2425
 
        public double getRule(String ruleName) {
2426
 
            throw new UnsupportedOperationException();
2427
 
        }
2428
 
    };
2429
 
 
2430
2108
    /**
2431
2109
     * Class to write the XML without multiple lines and indentation.
2432
2110
     * Useful when the XML is to be a single string.