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

« back to all changes in this revision

Viewing changes to com/sun/electric/tool/io/input/Applicon860.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:
 
1
/* -*- tab-width: 4 -*-
 
2
 *
 
3
 * Electric(tm) VLSI Design System
 
4
 *
 
5
 * File: Applicon860.java
 
6
 * Input tool: Applicon\860 input
 
7
 *
 
8
 * Copyright (c) 2008 Sun Microsystems and Static Free Software
 
9
 *
 
10
 * Electric(tm) is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 3 of the License, or
 
13
 * (at your option) any later version.
 
14
 *
 
15
 * Electric(tm) is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with Electric(tm); see the file COPYING.  If not, write to
 
22
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 
23
 * Boston, Mass 02111-1307, USA.
 
24
 *
 
25
 * This code only reads Apple/860 format, and it does not handle many of the
 
26
 * features.  It is built from Applicon document A-20482-002, November 1983.
 
27
 * The features that are not included are:
 
28
 * > Only polygons are read, not paths, areas, or CWHA rectangles
 
29
 * > Cell instances cannot scale or stretch and must be manhattan
 
30
 * > Groups are ignored
 
31
 * > Auxiliary records are ignored
 
32
 * > Multilevel polygons are not handled (must be on only one level)
 
33
 * > Polygon records must use default layer and not have their own color
 
34
 * > Text is handled poorly and should be commented out (see below)
 
35
 * The code can accomodate tape or disk format files with optional byte swapping.
 
36
 */
 
37
package com.sun.electric.tool.io.input;
 
38
 
 
39
import com.sun.electric.database.geometry.Orientation;
 
40
import com.sun.electric.database.geometry.Poly;
 
41
import com.sun.electric.database.hierarchy.Cell;
 
42
import com.sun.electric.database.hierarchy.Library;
 
43
import com.sun.electric.database.text.TextUtils;
 
44
import com.sun.electric.database.text.TextUtils.UnitScale;
 
45
import com.sun.electric.database.topology.NodeInst;
 
46
import com.sun.electric.database.variable.TextDescriptor;
 
47
import com.sun.electric.technology.Layer;
 
48
import com.sun.electric.technology.PrimitiveNode;
 
49
import com.sun.electric.technology.Technology;
 
50
import com.sun.electric.technology.Technology.NodeLayer;
 
51
import com.sun.electric.technology.technologies.Artwork;
 
52
 
 
53
import java.awt.geom.AffineTransform;
 
54
import java.awt.geom.Point2D;
 
55
import java.awt.geom.Rectangle2D;
 
56
import java.io.IOException;
 
57
import java.util.HashMap;
 
58
import java.util.HashSet;
 
59
import java.util.Iterator;
 
60
import java.util.Map;
 
61
import java.util.Set;
 
62
 
 
63
public class Applicon860 extends Input
 
64
{
 
65
        private static final int POLYSPLIT    = 999;    /* maximum polygon record size (was 62) */
 
66
        private static final int BYTESSWAPPED = 1;              /* bit set if bytes are swapped */
 
67
        private static final int TAPEFORMAT   = 2;              /* bit set if file is tape-blocked */
 
68
        private static final int INITIALIZED  = 4;              /* bit set if file status is known */
 
69
 
 
70
        private Map<Integer,PrimitiveNode> appleNodeMap = new HashMap<Integer,PrimitiveNode>();
 
71
        private int appleState;
 
72
 
 
73
        private int [] polylist;
 
74
        private int polylistcount = 0;
 
75
        private int [] px, py;
 
76
        private Point2D [] ptrace;
 
77
 
 
78
        /**
 
79
         * Method to import a library from disk.
 
80
         * @param lib the library to fill
 
81
         * @return the created library (null on error).
 
82
         */
 
83
        protected Library importALibrary(Library lib)
 
84
        {
 
85
                try
 
86
                {
 
87
                        if (!readAppleLibrary(lib)) return null; // error reading the file
 
88
                } catch (IOException e) {}
 
89
                return lib;
 
90
        }
 
91
 
 
92
        /**
 
93
         * Method to read the Applicon file.
 
94
         * @param lib the Library to fill.
 
95
         */
 
96
    /**
 
97
     * Method to read the Applicon file.
 
98
     * @param lib the Library to fill.
 
99
     * @return True if no error was found
 
100
     * @throws IOException
 
101
     */
 
102
    private boolean readAppleLibrary(Library lib)
 
103
                throws IOException
 
104
        {
 
105
                String str;
 
106
                int chain, length, type, i, eitype, offset, lvlgrp, layer, polyptr, nfl, nfh, nfe, tcount,
 
107
                        st, levels, a1, a2, a3, a4, lx, hx, ly, hy;
 
108
                int [] cidata = new int[32];
 
109
                String name, units, cellname;
 
110
                int x1, y1, xoff = 0, yoff = 0;
 
111
                Cell curfacet, subnp = null;
 
112
                PrimitiveNode layernp = null;
 
113
                NodeInst ni = null;
 
114
                double scale = 0;
 
115
                
 
116
                // establish linkage between Apple numbers and primitives
 
117
                setupAppleLayers();
 
118
        
 
119
                curfacet = null;
 
120
                Set<Integer> notFound = new HashSet<Integer>();
 
121
                appleState = 0;
 
122
                for(;;)
 
123
                {
 
124
                        chain = appleGetChain();
 
125
                        if (chain != 3 && chain != 1)
 
126
                        {
 
127
                                System.out.println("CHAIN=" + chain + " at byte " + byteCount);
 
128
                                return false;
 
129
                        }
 
130
                        length = appleGetWord();
 
131
                        type = appleGetWord();
 
132
                        switch (type)
 
133
                        {
 
134
                                case 2:         // top global parameter record
 
135
                                case 254:               // cell global parameter record
 
136
                                        if (length != 26)
 
137
                                        {
 
138
                                                if (type == 2)
 
139
                                                        System.out.println("Top global parameter length=" + length); else
 
140
                                                                System.out.println("Cell global parameter length=" + length);
 
141
                                                return false;
 
142
                                        }
 
143
                                        name = "";
 
144
                                        for(int k=0; k<30; k++) name += dataInputStream.readByte();
 
145
                                        st = name.indexOf(']') + 1;
 
146
                                        i = name.indexOf('.', st);
 
147
                                        if (i >= 0) name = name.substring(0, i);
 
148
 
 
149
                                        units = "";
 
150
                                        for(int k=0; k<4; k++) units += dataInputStream.readByte();
 
151
                                        nfl = appleGetWord();
 
152
                                        nfh = appleGetWord();
 
153
                                        nfe = appleGetWord();
 
154
                                        scale = appleFloat(nfl, nfh, nfe) / 2147483648.0;
 
155
                                        if (units.equals("MIL "))
 
156
                                        {
 
157
                                                // 25.4 microns to the mil
 
158
                                                scale = TextUtils.convertFromDistance(scale*25.4, Technology.getCurrent(), UnitScale.MICRO);
 
159
                                        } else if (units.equals("INCH"))
 
160
                                        {
 
161
                                                // 25400 microns to the inch
 
162
                                                TextUtils.convertFromDistance(scale*25400.0, Technology.getCurrent(), UnitScale.MICRO);
 
163
                                        } else
 
164
                                        {
 
165
                                                // presume microns
 
166
                                                scale = TextUtils.convertFromDistance(scale, Technology.getCurrent(), UnitScale.MICRO);
 
167
                                        }
 
168
                                        xoff = appleGetWord() & 0xFFFF;
 
169
                                        xoff |= (appleGetWord() & 0xFFFF) << 16;
 
170
                                        yoff = appleGetWord() & 0xFFFF;
 
171
                                        yoff |= (appleGetWord() & 0xFFFF) << 16;
 
172
                                        curfacet = Cell.makeInstance(lib, name.substring(st));
 
173
                                        if (curfacet == null)
 
174
                                        {
 
175
                                                System.out.println("Cannot create facet '" + name.substring(st) + "'");
 
176
                                                return false;
 
177
                                        }
 
178
                                        break;
 
179
        
 
180
                                case 3:         // element instance record
 
181
                                        if (length != 9)
 
182
                                        {
 
183
                                                System.out.println("Element instance length=" + length);
 
184
                                                return false;
 
185
                                        }
 
186
                                        lvlgrp = appleGetWord();
 
187
                                        levels = appleGetWord() & 0xFFFF;
 
188
                                        levels |= (appleGetWord() & 0xFFFF) << 16;
 
189
                                        for(i=0; i<32; i++) if (levels == (1 << i)) break;
 
190
                                        if (i >= 32)
 
191
                                        {
 
192
                                                System.out.println("Unknown layer code " + levels);
 
193
                                                return false;
 
194
                                        }
 
195
                                        layer = lvlgrp * 32 + i + 1;
 
196
                                        appleGetWord();
 
197
                                        eitype = appleGetWord();
 
198
                                        appleGetWord();         // numeir
 
199
                                        appleGetWord();         // textflg
 
200
                                        switch (eitype)
 
201
                                        {
 
202
                                                case 0: break;  // polygon
 
203
                                                case 1: break;  // area
 
204
                                                case 2: break;  // path
 
205
                                                case 3: break;  // rectangle
 
206
                                        }
 
207
 
 
208
                                        Integer layerInt = new Integer(layer);
 
209
                                        layernp = appleNodeMap.get(layerInt);
 
210
                                        if (layernp == null && !notFound.contains(layerInt))
 
211
                                        {
 
212
                                                System.out.println("Warning: Apple layer " + layer + " not found");
 
213
                                                notFound.add(layerInt);
 
214
                                        }
 
215
                                        break;
 
216
        
 
217
                                case 101:               // polygon record
 
218
                                        appleGetWord();         // color
 
219
                                        appleGetWord();         // draw
 
220
                                        offset = 4;
 
221
                                        if (length-offset > polylistcount)
 
222
                                        {
 
223
                                                polylistcount = 0;
 
224
                                                polylist = new int[length-offset];
 
225
                                                px = new int[((length-offset)+4)/5];
 
226
                                                py = new int[((length-offset)+4)/5];
 
227
                                                ptrace = new Point2D[((length-offset)+4)/5];
 
228
                                                polylistcount = length - offset;
 
229
                                        }
 
230
                                        polyptr = 0;
 
231
                                        while (length > POLYSPLIT)
 
232
                                        {
 
233
                                                for(i=0; i<POLYSPLIT-offset; i++)
 
234
                                                        polylist[polyptr++] = appleGetWord();
 
235
                                                chain = appleGetChain();
 
236
                                                if (chain != 2 && chain != 0)
 
237
                                                {
 
238
                                                        System.out.println("END CHAIN=" + chain + " at byte " + byteCount);
 
239
                                                        return false;
 
240
                                                }
 
241
                                                length -= POLYSPLIT;
 
242
                                                offset = 0;
 
243
                                        }
 
244
                                        for(i=0; i<length-offset; i++)
 
245
                                                polylist[polyptr++] = appleGetWord();
 
246
                                        if (polyptr > polylistcount)
 
247
                                                System.out.println("Just overflowed " + polylistcount + " long array with " + polyptr + " points");
 
248
                                        if ((chain&2) == 0) appleGetWord();
 
249
        
 
250
                                        // process data into a set of points
 
251
                                        polyptr /= 5;
 
252
                                        for(i=0; i<polyptr; i++)
 
253
                                        {
 
254
                                                px[i] = polylist[i*5] & 0xFFFF;
 
255
                                                px[i] |= (polylist[i*5+1] & 0xFFFF) << 16;
 
256
                                                py[i] = polylist[i*5+2] & 0xFFFF;
 
257
                                                py[i] |= (polylist[i*5+3] & 0xFFFF) << 16;
 
258
                                                px[i] = appleScale(px[i], xoff, scale);
 
259
                                                py[i] = appleScale(py[i], yoff, scale);
 
260
                                                if ((polylist[i*5+4]&2) != 0 && i != 0)
 
261
                                                        System.out.println("Warning: point " + i + " of polygon has s=" + polylist[i*5+4]);
 
262
                                                if ((polylist[i*5+4]&1) != 0 && i != polyptr-1)
 
263
                                                        System.out.println("Warning: point " + i + " of polygon has s=" + polylist[i*5+4]);
 
264
                                        }
 
265
                                        if (px[polyptr-1] == px[0] && py[polyptr-1] == py[0]) polyptr--;
 
266
                                        lx = hx = px[0];
 
267
                                        ly = hy = py[0];
 
268
                                        for(i=1; i<polyptr; i++)
 
269
                                        {
 
270
                                                if (px[i] < lx) lx = px[i];
 
271
                                                if (px[i] > hx) hx = px[i];
 
272
                                                if (py[i] < ly) ly = py[i];
 
273
                                                if (py[i] > hy) hy = py[i];
 
274
                                        }
 
275
                                        for(i=0; i<polyptr; i++)
 
276
                                                ptrace[i] = new Point2D.Double(px[i] - (lx+hx) / 2, py[i] - (ly+hy) / 2);
 
277
        
 
278
                                        // now create the polygon
 
279
                                        if (layernp != null && curfacet != null)
 
280
                                        {
 
281
                                                Point2D center = new Point2D.Double((lx+hx)/2, (ly+hy)/2);
 
282
                                                ni = NodeInst.newInstance(layernp, center, hx-lx, hy-ly, curfacet);
 
283
                                                if (ni == null) return false;
 
284
                                                ni.newVar(NodeInst.TRACE, ptrace);
 
285
                                        }
 
286
                                        break;
 
287
        
 
288
                                case 107:               // flag record
 
289
                                        if (length != 3)
 
290
                                        {
 
291
                                                System.out.println("Flag length=" + length);
 
292
                                                return false;
 
293
                                        }
 
294
                                        appleGetWord(); // flag
 
295
                                        break;
 
296
        
 
297
                                case 117:               // text record
 
298
                                        appleGetWord(); // vnumb
 
299
                                        appleGetWord(); // color
 
300
                                        appleGetWord(); // lvlgrp
 
301
                                        appleGetWord(); // levels1
 
302
                                        appleGetWord(); // levels2
 
303
                                        appleGetWord(); // txtdx low
 
304
                                        appleGetWord(); // txtdx high
 
305
                                        appleGetWord(); // txtdy low
 
306
                                        appleGetWord(); // txtdy high
 
307
                                        appleGetWord(); // txtsiz low
 
308
                                        appleGetWord(); // txtsiz high
 
309
                                        appleGetWord(); // tfield
 
310
                                        appleGetWord(); // torien
 
311
                                        tcount = appleGetWord();
 
312
                                        if ((tcount&1) != 0) tcount++;
 
313
        
 
314
                                        // allocate and read the string
 
315
                                        str = "";
 
316
                                        for(int k=0; k<tcount; k++) str += dataInputStream.readByte();
 
317
 
 
318
                                        // remove line-feeds, count carriage-returns
 
319
                                        i = 0;
 
320
                                        StringBuffer sb = new StringBuffer();
 
321
                                        for(int k=0; k<str.length(); k++)
 
322
                                        {
 
323
                                                char ch = str.charAt(k);
 
324
                                                if (ch == '\r')
 
325
                                                {
 
326
                                                        sb.append('\n');
 
327
                                                        i++;
 
328
                                                } else if (ch != '\n') sb.append(ch);
 
329
                                        }
 
330
                                        str = sb.toString();
 
331
        
 
332
                                        if (ni != null)
 
333
                                        {
 
334
                                                if (i <= 1)
 
335
                                                {
 
336
                                                        // one carriage return: simple message
 
337
                                                        int crPos = str.indexOf('\n');
 
338
                                                        if (crPos >= 0) str = str.substring(0, crPos);
 
339
                                                        TextDescriptor td = TextDescriptor.getNodeTextDescriptor().withDisplay(true);
 
340
                                                        ni.newVar(Artwork.ART_MESSAGE, str, td);
 
341
                                                } else
 
342
                                                {
 
343
                                                        // multi-line message
 
344
                                                        String [] message = str.split("\n");
 
345
                                                        TextDescriptor td = TextDescriptor.getNodeTextDescriptor().withDisplay(true);
 
346
                                                        ni.newVar(Artwork.ART_MESSAGE, message, td);
 
347
                                                }
 
348
                                        }
 
349
                                        break;
 
350
        
 
351
                                case 4:         // cell name record
 
352
                                        if (length != 17)
 
353
                                        {
 
354
                                                System.out.println("Cell name length=" + length);
 
355
                                                return false;
 
356
                                        }
 
357
                                        cellname = "";
 
358
                                        for(int k=0; k<30; k++) cellname += dataInputStream.readByte();
 
359
                                        st = cellname.indexOf(']') + 1;
 
360
                                        i = cellname.indexOf('.', st);
 
361
                                        if (i >= 0) cellname = cellname.substring(0, i);
 
362
                                        subnp = lib.findNodeProto(cellname);
 
363
                                        if (subnp == null)
 
364
                                        {
 
365
                                                System.out.println("Instance of cell '" + cellname.substring(st) + "' not found");
 
366
                                                return false;
 
367
                                        }
 
368
                                        break;
 
369
        
 
370
                                case 5:         // cell instance header record
 
371
                                        if (length != 6)
 
372
                                        {
 
373
                                                System.out.println("Cell instance header length=" + length);
 
374
                                                return false;
 
375
                                        }
 
376
                                        appleGetWord();
 
377
                                        appleGetWord();
 
378
                                        appleGetWord(); // numcir
 
379
                                        appleGetWord(); // textflg
 
380
                                        break;
 
381
        
 
382
                                case 105:               // cell instance record
 
383
                                        length -= 2;
 
384
                                        for(i=0; i<length; i++) cidata[i] = appleGetWord();
 
385
        
 
386
                                        // get first point
 
387
                                        x1 = cidata[0] & 0xFFFF;
 
388
                                        x1 |= (cidata[1] & 0xFFFF) << 16;
 
389
                                        y1 = cidata[2] & 0xFFFF;
 
390
                                        y1 |= (cidata[3] & 0xFFFF) << 16;
 
391
                                        x1 = appleScale(x1, xoff, scale);
 
392
                                        y1 = appleScale(y1, yoff, scale);
 
393
                                        i = 5;
 
394
        
 
395
                                        // ignore stretch point
 
396
                                        if ((cidata[length-1]&2) != 0) i += 5;
 
397
        
 
398
                                        // get transformation matrix
 
399
                                        int rot = 0, trans = 0;
 
400
                                        if ((cidata[length-1]&4) != 0)
 
401
                                        {
 
402
                                                a1 = cidata[i] & 0xFFFF;
 
403
                                                a1 |= (cidata[i+1] & 0xFFFF) << 16;
 
404
                                                if (a1 == -2147483647) a1 = -1; else
 
405
                                                        if (a1 == 2147483647) a1 = 1; else a1 = 0;
 
406
                                                a2 = cidata[i+2] & 0xFFFF;
 
407
                                                a2 |= (cidata[i+3] & 0xFFFF) << 16;
 
408
                                                if (a2 == -2147483647) a2 = -1; else
 
409
                                                        if (a2 == 2147483647) a2 = 1; else a2 = 0;
 
410
                                                a3 = cidata[i+4] & 0xFFFF;
 
411
                                                a3 |= (cidata[i+5] & 0xFFFF) << 16;
 
412
                                                if (a3 == -2147483647) a3 = -1; else
 
413
                                                        if (a3 == 2147483647) a3 = 1; else a3 = 0;
 
414
                                                a4 = cidata[i+6] & 0xFFFF;
 
415
                                                a4 |= (cidata[i+7] & 0xFFFF) << 16;
 
416
                                                if (a4 == -2147483647) a4 = -1; else
 
417
                                                        if (a4 == 2147483647) a4 = 1; else a4 = 0;
 
418
        
 
419
                                                // convert to rotation/transpose
 
420
                                                if (a1 == 0 && a2 == -1 && a3 == 1 && a4 == 0) rot = 900;
 
421
                                                if (a1 == -1 && a2 == 0 && a3 == 0 && a4 == -1) rot = 1800;
 
422
                                                if (a1 == 0 && a2 == 1 && a3 == -1 && a4 == 0) rot = 2700;
 
423
                                                if (a1 == 0 && a2 == -1 && a3 == -1 && a4 == 0)
 
424
                                                {
 
425
                                                        trans = 1;
 
426
                                                }
 
427
                                                if (a1 == -1 && a2 == 0 && a3 == 0 && a4 == 1)
 
428
                                                {
 
429
                                                        rot = 900;
 
430
                                                        trans = 1;
 
431
                                                }
 
432
                                                if (a1 == 0 && a2 == 1 && a3 == 1 && a4 == 0)
 
433
                                                {
 
434
                                                        rot = 1800;
 
435
                                                        trans = 1;
 
436
                                                }
 
437
                                                if (a1 == 1 && a2 == 0 && a3 == 0 && a4 == -1)
 
438
                                                {
 
439
                                                        rot = 2700;
 
440
                                                        trans = 1;
 
441
                                                }
 
442
                                                i += 8;
 
443
                                        }
 
444
                                        if (subnp != null && curfacet != null)
 
445
                                        {
 
446
                                                // determine center of instance
 
447
                                                Orientation orient = Orientation.fromC(rot, trans != 0);
 
448
                                                AffineTransform mat = orient.pureRotate();
 
449
                                                Rectangle2D subBounds = subnp.getBounds();
 
450
                                                Point2D dest = new Point2D.Double(0, 0);
 
451
                                                mat.transform(new Point2D.Double(subBounds.getCenterX(), subBounds.getCenterY()), dest);
 
452
                                                double vx = dest.getX() + x1;
 
453
                                                double vy = dest.getY() + y1;
 
454
                                                Point2D center = new Point2D.Double(subBounds.getWidth(), subBounds.getHeight());
 
455
                                                ni = NodeInst.newInstance(subnp, center, vx*2, vy*2, curfacet, orient, null, 0);
 
456
                                                if (ni == null) return false;
 
457
                                        }
 
458
                                        break;
 
459
        
 
460
                                case 255:               // end definition record
 
461
                                        if (length != 2)
 
462
                                        {
 
463
                                                System.out.println("End definition length=" + length);
 
464
                                                return false;
 
465
                                        }
 
466
                                        if (curfacet == null)
 
467
                                        {
 
468
                                                System.out.println("End definition has no associated begin");
 
469
                                                return false;
 
470
                                        }
 
471
 
 
472
                                        curfacet = null;
 
473
                                        break;
 
474
        
 
475
                                case 0:                 // format record
 
476
                                        for(i=0; i<length-2; i++) appleGetWord();
 
477
                                        break;
 
478
                                case 1:                 // title record
 
479
                                        for(i=0; i<length-2; i++) appleGetWord();
 
480
                                        break;
 
481
                                case 100:               // group record
 
482
                                        for(i=0; i<length-2; i++) appleGetWord();
 
483
                                        break;
 
484
                                case 104:               // auxiliary record
 
485
                                        for(i=0; i<length-2; i++) appleGetWord();
 
486
                                        break;
 
487
                                default:
 
488
                                        System.out.println("Unknown record type: " + type);
 
489
                return true;
 
490
                        }
 
491
                }
 
492
//        return true;
 
493
    }
 
494
        
 
495
        /**
 
496
         * Method to get the chain value from disk.
 
497
         * Automatically senses byte swapping and tape/disk format.
 
498
         */
 
499
        private int appleGetChain()
 
500
                throws IOException
 
501
        {
 
502
                int chain;
 
503
        
 
504
                if ((appleState&INITIALIZED) == 0)
 
505
                {
 
506
                        // on first call, evaluate nature of file
 
507
                        appleState |= INITIALIZED;
 
508
                        chain = appleGetWord();
 
509
                        if (chain == 3 || chain == 1) return(chain);
 
510
        
 
511
                        // tape header may be present
 
512
                        if (Character.isDigit(chain&0377) && Character.isDigit((chain>>8)&0377))
 
513
                        {
 
514
                                appleGetWord();
 
515
                                appleState |= TAPEFORMAT;
 
516
                                chain = appleGetWord();
 
517
                        }
 
518
        
 
519
                        // bytes may be swapped
 
520
                        if (chain == 0x300 || chain == 0x100)
 
521
                        {
 
522
                                appleState |= BYTESSWAPPED;
 
523
                                chain >>= 8;
 
524
                        }
 
525
                        return chain;
 
526
                }
 
527
        
 
528
                // normal chain request
 
529
                if ((appleState&TAPEFORMAT) != 0)
 
530
                {
 
531
                        // get 4-digit code, skip to end of block
 
532
                        for(int i=0; i<4; i++)
 
533
                        {
 
534
                                int val = dataInputStream.readByte();
 
535
                                updateProgressDialog(2);
 
536
                                if (Character.isDigit(val)) continue;
 
537
                                i--;
 
538
                        }
 
539
                }
 
540
                chain = appleGetWord();
 
541
                return chain;
 
542
        }
 
543
        
 
544
        private int appleGetWord()
 
545
                throws IOException
 
546
        {
 
547
                byte low = dataInputStream.readByte();
 
548
                byte high = dataInputStream.readByte();
 
549
                updateProgressDialog(2);
 
550
                if ((appleState&BYTESSWAPPED) == 0) return (low&0377) | ((high&0377)<<8);
 
551
                return (high&0377) | ((low&0377)<<8);
 
552
        }
 
553
        
 
554
        /**
 
555
         * Method to convert the Apple floating point representation in "lo", "hi"
 
556
         * and "exp" into a true floating point number
 
557
         */
 
558
        private double appleFloat(int lo, int hi, int exp)
 
559
        {
 
560
                int i;
 
561
                double fl;
 
562
        
 
563
                i = (lo & 0xFFFF) | ((hi & 0xFFFF) << 16);
 
564
                exp = 31 - exp;
 
565
                fl = i & 0x7FFFFFFF;
 
566
                fl /= (1 << exp);
 
567
                if ((i & 0x80000000) != 0) fl = -fl;
 
568
                return(fl);
 
569
        }
 
570
 
 
571
        static Poly poly = null;
 
572
 
 
573
        private void setupAppleLayers()
 
574
        {
 
575
                Technology tech = Technology.getCurrent();
 
576
                for(Iterator<PrimitiveNode> it = tech.getNodes(); it.hasNext(); )
 
577
                {
 
578
                        PrimitiveNode pn = it.next();
 
579
                        if (pn.getFunction() == PrimitiveNode.Function.NODE)
 
580
                        {
 
581
                                NodeLayer [] nls = pn.getLayers();
 
582
                                for(int i=0; i<nls.length; i++)
 
583
                                {
 
584
                                        NodeLayer nl = nls[i];
 
585
                                        Layer lay = nl.getLayer();
 
586
                                        int appleLayer = lay.getIndex();                // TODO: should get the user-specified apple/860 layer
 
587
                                        appleNodeMap.put(new Integer(appleLayer), pn);
 
588
                                }
 
589
                        }
 
590
                }
 
591
        }
 
592
        
 
593
        /**
 
594
         * Method to convert from Apple units, through offset "offset" and scale
 
595
         * "scale" and return the proper value
 
596
         */
 
597
        private int appleScale(int value, int offset, double scale)
 
598
        {
 
599
                double temp;
 
600
        
 
601
                temp = value - offset;
 
602
                temp = temp * scale;
 
603
                value = (int)temp;
 
604
        
 
605
                // round to the nearest quarter micron
 
606
                if ((value % 25) != 0)
 
607
                {
 
608
                        if (value > 0) value = (value+12) / 25 * 25; else
 
609
                                value = (value-12) / 25 * 25;
 
610
                }
 
611
                return(value);
 
612
        }
 
613
}
 
614