Statistics
| Revision:

root / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / readers / DwgFileV12Reader.java @ 10585

History | View | Annotate | Download (42.8 KB)

1 10289 azabala
/*
2
 * Created on 09-ene-2007
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.jdwglib.dwg.readers;
45
46 10481 azabala
import java.awt.geom.Point2D;
47 10289 azabala
import java.io.IOException;
48
import java.nio.ByteBuffer;
49
import java.nio.ByteOrder;
50 10421 azabala
import java.util.ArrayList;
51 10481 azabala
import java.util.List;
52 10289 azabala
53
import com.iver.cit.jdwglib.dwg.CorruptedDwgEntityException;
54
import com.iver.cit.jdwglib.dwg.DwgFile;
55 10481 azabala
import com.iver.cit.jdwglib.dwg.DwgHandleReference;
56 10289 azabala
import com.iver.cit.jdwglib.dwg.DwgObject;
57 10481 azabala
import com.iver.cit.jdwglib.dwg.DwgObjectFactory;
58
import com.iver.cit.jdwglib.dwg.DwgUtil;
59
import com.iver.cit.jdwglib.dwg.objects.DwgArc;
60
import com.iver.cit.jdwglib.dwg.objects.DwgBlockHeader;
61
import com.iver.cit.jdwglib.dwg.objects.DwgCircle;
62
import com.iver.cit.jdwglib.dwg.objects.DwgInsert;
63 10515 azabala
import com.iver.cit.jdwglib.dwg.objects.DwgLayer;
64 10481 azabala
import com.iver.cit.jdwglib.dwg.objects.DwgLine;
65
import com.iver.cit.jdwglib.dwg.objects.DwgPoint;
66
import com.iver.cit.jdwglib.dwg.objects.DwgSolid;
67
import com.iver.cit.jdwglib.dwg.objects.DwgText;
68 10515 azabala
import com.iver.cit.jdwglib.util.ByteUtils;
69 10289 azabala
70
/**
71 10481 azabala
 * Reads version 12 dwg files.
72 10289 azabala
 *
73 10481 azabala
 * DWG 13 and DWG 12 are very different formats (nor do DWG 13-14 and 2000).
74
 * Thats the reason why this IDwgFileReader is very different from the rest.
75
 *
76 10537 azabala
 * Documentation of reverse engineering of the format:
77
 *         http://www.iwriteiam.nl/DWG12.html
78 10435 azabala
 *
79 10289 azabala
 * @author azabala
80 10421 azabala
 *
81 10289 azabala
 */
82
public class DwgFileV12Reader implements IDwgFileReader{
83
84
        private DwgFile dwgFile;
85
        private ByteBuffer bb;
86 10421 azabala
        ArrayList readers = new ArrayList();
87
        /*
88
         * En Python:
89
         *  if _version != 'AC1009':
90
        if _version == 'AC1010':
91
            r13 = True
92
        else:
93
            print "unknown version"
94
         *
95
         * */
96
        private boolean r13 = false;
97 10515 azabala
        int index = 0;
98 10421 azabala
99
100
        public DwgFileV12Reader(boolean isR13){
101
                r13 = isR13;
102
                readers.add(null);
103
                readers.add(new LineReader());
104
                readers.add(new PointReader());
105
                readers.add(new CircleReader());
106
                readers.add(new ShapeReader());
107
                readers.add(null);
108
                readers.add(null);
109
                readers.add(new TextReader());
110
                readers.add(new ArcReader());
111
                readers.add(new TraceReader());
112
                readers.add(null);
113
                readers.add(null);
114
                readers.add(new SolidReader());
115
                readers.add(new BlkReader());
116
                readers.add(new EndBlkReader());
117
                readers.add(new InsertReader());
118
                readers.add(new AttDefReader());
119
                readers.add(new AttribReader());
120
                readers.add(new SbEndReader());
121
                readers.add(null);
122
                readers.add(new PlineReader());
123
                readers.add(new VertexReader());
124
                readers.add(null);
125
                readers.add(new Face3DReader());
126
                readers.add(new DimReader());
127
                readers.add(new VPortReader());
128
        }
129
130
131 10289 azabala
132
        /* (non-Javadoc)
133
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#read(com.iver.cit.jdwglib.dwg.DwgFile, java.nio.ByteBuffer)
134
         */
135
        public void read(DwgFile dwgFile, ByteBuffer bb) throws IOException {
136
                this.dwgFile = dwgFile;
137
                this.bb = bb;
138
                try {
139 10515 azabala
////                        handle.seek(6, 1) # skip rest of version
140
//                        bb.position(12);
141 10455 azabala
//                        bb.position(bb.position() + 6);
142 10515 azabala
                        bb.position(0);
143
                        byte[] header = new byte[12];
144
                        bb.get(header);
145
                        String headerStr = new String(header);
146
                        System.out.println(headerStr);
147 10289 azabala
148
//                    (_b1, _w1, _w2, _w3, _b2) = struct.unpack("<BhhhB", handle.read(8))
149
                        bb.order(ByteOrder.LITTLE_ENDIAN);
150
                        byte b1 = bb.get();
151
                        short w1 = bb.getShort();
152
                        short w2 = bb.getShort();
153
                        short w3 = bb.getShort();
154
                        byte b2 = bb.get();
155
156
157
                        //To translate Python to Java, we must see the number
158
                        //of bytes of the reading
159
160
//                         _estart, _eend = struct.unpack("<ll", handle.read(8))
161 10515 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
162 10289 azabala
                        int eStart = bb.getInt();
163
                        int eEnd = bb.getInt();
164
165
//                        _bsstart, _l1, _bsend, _l2 = struct.unpack("<llll", handle.read(16))
166
                        int bsStart = bb.getInt();
167
                        int l1 = bb.getInt();
168
169
                        int bsEnd = bb.getInt();
170
                        int l2 = bb.getInt();
171
172
                        Dwg12Table blockTable = getTable();
173
174
                        Dwg12Table layerTable = getTable();
175
176
                        Dwg12Table styleTable = getTable();
177
178
                        Dwg12Table lineTypeTable = getTable();
179
180
                        Dwg12Table viewTable = getTable();
181
182
                        readHeader();
183
184
                        Dwg12Table ucsTable = getTable();
185
186
                        bb.position(0x500);
187
188
                        Dwg12Table vportTable = getTable();
189
190
                        bb.position(bb.position() + 8);
191
192
                        Dwg12Table appidTable = getTable();
193
194
                        bb.position(bb.position() + 6);
195
196
                        Dwg12Table dimStyleTable = getTable();
197 10537 azabala
                        bb.position(0x69f);
198
199 10289 azabala
                        Dwg12Table p13table = getTable();
200
201
                        bb.position(bb.position() + 38);
202
203
                        int currentPosition = bb.position();
204 10537 azabala
                        if(currentPosition != eStart){
205
                                //Se supone que deber?amos estar en eStart
206
                                throw new RuntimeException("Error: no se ha llegado al principio de las entidades de dibujo");
207
                        }
208 10289 azabala
209
                        //lee primero entidades normales?
210
                        readEntities(eStart, eEnd);
211
212
                        bb.position(bb.position() + 19);
213
214
                        readBlockTable(blockTable);
215
                        readLayerTable(layerTable);
216
                        readStyleTable(styleTable);
217
                        readLTypeTable(lineTypeTable);
218
                        readViewTable(viewTable);
219
                        readUcsTable(ucsTable);
220
                        readVportTable(vportTable);
221
                        readAppidTable(appidTable);
222
                        readDimStyleTable(dimStyleTable);
223 10435 azabala
//                        readP13Table(p13table);
224 10289 azabala
225
                        //luego lee entidades de bloque
226
                        readEntities(bsStart, bsEnd);
227
228
                        bb.position(bb.position() + 36);
229
230
                        bb.order(ByteOrder.LITTLE_ENDIAN);
231
232
                        int peStart, peEnd, pbStart, pbEnd;
233
234
                        peStart = bb.getInt();
235
                        peEnd = bb.getInt();
236
                        pbStart = bb.getInt();
237
                        pbEnd = bb.getInt();
238
239
                        if(peStart != eStart)
240
                                System.out.println("peStart="+peStart+" eStart="+eStart);
241
242
                        if(peEnd != eEnd)
243
                                System.out.println("peStart="+peEnd+" eStart="+eEnd);
244
245
                        if(pbStart != bsStart)
246
                                System.out.println("peStart="+pbStart+" eStart="+bsStart);
247
248
                        if(bsEnd != pbEnd)
249
                                System.out.println("peStart="+pbStart+" eStart="+bsStart);
250
251
                        bb.position(bb.position() + 12);
252
253
                        Dwg12TableTest bts = getTableTest();
254
255
                        Dwg12TableTest lyrTs = getTableTest();
256
257
                        Dwg12TableTest sts = getTableTest();
258
259
                        Dwg12TableTest ltts = getTableTest();
260
261
                        Dwg12TableTest vts = getTableTest();
262
263
                        Dwg12TableTest uts = getTableTest();
264
265
                        Dwg12TableTest vpts = getTableTest();
266
267
                        Dwg12TableTest ats = getTableTest();
268
269
                        Dwg12TableTest dts = getTableTest();
270
271
                        Dwg12TableTest pts = getTableTest();
272
273
274
275
276
                } catch (Exception e) {
277 10515 azabala
                        e.printStackTrace();
278 10289 azabala
//                        logger.error(e);
279
                }
280
        }
281
282
283 10435 azabala
        private void readP13Table(Dwg12Table p13table) {
284
                // TODO Auto-generated method stub
285
        }
286
287
288
289
        private void readDimStyleTable(Dwg12Table dimStyleTable) {
290
                short size = dimStyleTable.s1;
291
                int numRecs = dimStyleTable.i1;
292
                int start = dimStyleTable.i2;
293
                int end = -1;
294
                bb.position(start);
295
                for(int i = 0; i < numRecs; i++){
296
                        end = bb.position() + size;
297
298
                        byte flag = bb.get();
299
                        byte[] nameBytes = new byte[32];
300
                        bb.get(nameBytes);
301
                        String name = new String(nameBytes);
302
303
                        bb.order(ByteOrder.LITTLE_ENDIAN);
304
                        short word = bb.getShort();
305
306
                        double[] d4048 = new double[9];
307
                        for(int j = 0; j < 9; j++){
308
                                d4048[j] = bb.getDouble();
309
                        }
310
311
                        double[] d40145 = new double[6];
312
                        for(int j = 0; j < 6; j++){
313
                                d40145[j] = bb.getDouble();
314
                        }
315
316
                        byte[] b7078 = new byte[7];
317
                        for(int j = 0; j < 7; j++){
318
                                b7078[j] = bb.get();
319
                        }
320
321
                        byte[] b170175 = new byte[6];
322
                        for(int j = 0; j < 6; j++){
323
                                b170175[j] = bb.get();
324
                        }
325
326
                        bb.order(ByteOrder.nativeOrder());
327
                        byte[] s3 = new byte[16];
328
                        bb.get(s3);
329
330
                        byte[] s4 = new byte[16];
331
                        bb.get(s4);
332
333
                        byte[] s5 = new byte[32];
334
                        bb.get(s5);
335
336
                        byte[] s6 = new byte[32];
337
                        bb.get(s6);
338
339
                        byte[] s7 = new byte[32];
340
                        bb.get(s6);
341
342
                        bb.position(bb.position() + 3);
343
344
                        bb.order(ByteOrder.LITTLE_ENDIAN);
345
                        short w176 = bb.getShort();
346
                        short w177 = bb.getShort();
347
                        short w178 = bb.getShort();
348
349
                        double d146 = bb.getDouble();
350
                        double d147 = bb.getDouble();
351
352
353
                        int offset = end - bb.position();
354
                        if(offset > 0)
355
                                bb.position(bb.position() + offset);
356
357
                        bb.order(ByteOrder.LITTLE_ENDIAN);
358
                        short crc = bb.getShort();
359
                }
360
                byte[] crc32 = new byte[32];
361
                bb.get(crc32);
362
        }
363
364
365
366
        private void readAppidTable(Dwg12Table appidTable) {
367
                short size = appidTable.s1;
368
                int numRecs = appidTable.i1;
369
                int start = appidTable.i2;
370
                int end = -1;
371
                bb.position(start);
372
                for(int i = 0; i < numRecs; i++){
373
                        end = bb.position() + size;
374
375
                        byte flag = bb.get();
376
                        byte[] nameBytes = new byte[32];
377
                        bb.get(nameBytes);
378
                        String name = new String(nameBytes);
379
380
                        bb.order(ByteOrder.LITTLE_ENDIAN);
381
                        short word = bb.getShort();
382
383
                        int offset = end - bb.position();
384
                        if(offset > 0)
385
                                bb.position(bb.position() + offset);
386
387
                        bb.order(ByteOrder.LITTLE_ENDIAN);
388
                        short crc = bb.getShort();
389
                }
390
                byte[] crc32 = new byte[32];
391
                bb.get(crc32);
392
        }
393
394
395
396
        private void readVportTable(Dwg12Table vportTable) {
397
                short size = vportTable.s1;
398
                int numRecs = vportTable.i1;
399
                int start = vportTable.i2;
400
                int end = -1;
401
                bb.position(start);
402
                for(int i = 0; i < numRecs; i++){
403
                        end = bb.position() + size;
404
405
                        byte flag = bb.get();
406
                        byte[] nameBytes = new byte[32];
407
                        bb.get(nameBytes);
408
                        String name = new String(nameBytes);
409
410
                        bb.order(ByteOrder.LITTLE_ENDIAN);
411
                        short used = bb.getShort();
412
413
                        double[] pt10 = getPoint(false);
414
                        double[] pt11 = getPoint(false);
415
                        double[] pt17 = getPoint(false);
416
                        double[] pt16 = getPoint(true);
417
418
                        bb.order(ByteOrder.LITTLE_ENDIAN);
419
420
                        double d50 = bb.getDouble();
421
                        double d40 = bb.getDouble();
422
423
                        double[] pt12 = getPoint(false);
424
425
                        bb.order(ByteOrder.LITTLE_ENDIAN);
426
                        double d41 = bb.getDouble();
427
                        double d42 = bb.getDouble();
428
                        double d43 = bb.getDouble();
429
                        double d44 = bb.getDouble();
430
431
                        short[] w7178 = new short[8];
432
                        for(int j = 0; j < 8; j++){
433
                                w7178[j] = bb.getShort();
434
                        }
435
                        bb.order(ByteOrder.LITTLE_ENDIAN);
436
                        double d51 = bb.getDouble();
437
438
                        double[] pt13 = getPoint(false);
439
                        double[] pt14 = getPoint(false);
440
                        double[] pt15 = getPoint(false);
441
442
                        int offset = end - bb.position();
443
                        if(offset > 0)
444
                                bb.position(bb.position() + offset);
445
446
                        bb.order(ByteOrder.LITTLE_ENDIAN);
447
                        short crc = bb.getShort();
448
                }
449
                byte[] crc32 = new byte[32];
450
                bb.get(crc32);
451
        }
452
453
454
455
        private void readUcsTable(Dwg12Table ucsTable) {
456
                short size = ucsTable.s1;
457
                int numRecs = ucsTable.i1;
458
                int start = ucsTable.i2;
459
                int end = -1;
460
                bb.position(start);
461
                for(int i = 0; i < numRecs; i++){
462
                        end = bb.position() + size;
463
464
                        byte flag = bb.get();
465
                        byte[] nameBytes = new byte[32];
466
                        bb.get(nameBytes);
467
                        String name = new String(nameBytes);
468
469
                        bb.order(ByteOrder.LITTLE_ENDIAN);
470
                        short used = bb.getShort();
471
472
                        double[] pt10 = getPoint(true);
473
                        double[] pt11 = getPoint(true);
474
                        double[] pt12 = getPoint(true);
475
476
477
478
                        int offset = end - bb.position();
479
                        if(offset > 0)
480
                                bb.position(bb.position() + offset);
481
482
                        bb.order(ByteOrder.LITTLE_ENDIAN);
483
                        short crc = bb.getShort();
484
                }
485
                byte[] crc32 = new byte[32];
486
                bb.get(crc32);
487
488
489
        }
490
491
492
493
        private void readViewTable(Dwg12Table viewTable) {
494
                short size = viewTable.s1;
495
                int numRecs = viewTable.i1;
496
                int start = viewTable.i2;
497
                int end = -1;
498
                bb.position(start);
499
                for(int i = 0; i < numRecs; i++){
500
                        end = bb.position() + size;
501
502
                        byte flag = bb.get();
503
                        byte[] nameBytes = new byte[32];
504
                        bb.get(nameBytes);
505
                        String name = new String(nameBytes);
506
507
                        bb.order(ByteOrder.LITTLE_ENDIAN);
508
                        short used = bb.getShort();
509
                        double db40 = bb.getDouble();
510
511
                        double[] pt10 = getPoint(false);
512
513
                        bb.order(ByteOrder.LITTLE_ENDIAN);
514
                        double db41 = bb.getDouble();
515
516
                        double[] pt11 = getPoint(true);
517
518
                        double[] pt12 = getPoint(true);
519
520
521
                        bb.order(ByteOrder.LITTLE_ENDIAN);
522
                        short w71 = bb.getShort();
523
                        double db42 = bb.getDouble();
524
                        double db43 = bb.getDouble();
525
                        double db44 = bb.getDouble();
526
                        double db50 = bb.getDouble();
527
528
                        int offset = end - bb.position();
529
                        if(offset > 0)
530
                                bb.position(bb.position() + offset);
531
532
                        bb.order(ByteOrder.LITTLE_ENDIAN);
533
                        short crc = bb.getShort();
534
535
536
                }
537
                byte[] crc32 = new byte[32];
538
                bb.get(crc32);
539
        }
540
541
542
543
        private void readLTypeTable(Dwg12Table lineTypeTable) {
544
                short size = lineTypeTable.s1;
545
                int numRecs = lineTypeTable.i1;
546
                int start = lineTypeTable.i2;
547
                int end = -1;
548
                bb.position(start);
549
                for(int i = 0; i < numRecs; i++){
550
                        end = bb.position() + size;
551
                        byte flag = bb.get();
552
                        byte[] nameBytes = new byte[32];
553
                        bb.get(nameBytes);
554
                        String name = new String(nameBytes);
555
                        bb.order(ByteOrder.LITTLE_ENDIAN);
556
                        short w1 = bb.getShort();
557
558
                        byte[] s1 = new byte[48];
559
                        bb.get(s1);
560
                        String s1name = new String(s1);
561
562
                        bb.order(ByteOrder.nativeOrder());
563
                        byte b1 = bb.get();
564
                        byte b2 = bb.get();
565
566
                        bb.order(ByteOrder.LITTLE_ENDIAN);
567
                        double[] doubles = new double[13];
568
                        for(int j = 0; j < 13; j++){
569
                                doubles[j] = bb.getDouble();
570
                        }
571
572
                        short crc = bb.getShort();
573
574
                        int offset = end - bb.position();
575
                        if(offset > 0)
576
                                bb.position(bb.position() + offset);
577
                }
578
                byte[] crc32 = new byte[32];
579
                bb.get(crc32);
580
        }
581
582
583
584 10421 azabala
        /**
585
         * @param styleTable
586
         */
587
        private void readStyleTable(Dwg12Table styleTable) {
588
                short size = styleTable.s1;
589
                int numRecs = styleTable.i1;
590
                int start = styleTable.i2;
591
                int end = -1;
592
                bb.position(start);
593
                for(int i = 0; i < numRecs; i++){
594
                        end = bb.position() + size;
595
                        byte flag = bb.get();
596
                        byte[] nameBytes = new byte[32];
597
                        bb.get(nameBytes);
598
                        String name = new String(nameBytes);
599
                        bb.order(ByteOrder.LITTLE_ENDIAN);
600
                        short w1 = bb.getShort();
601
                        double d1 = bb.getDouble();
602
                        double d2 = bb.getDouble();
603
                        double d3 = bb.getDouble();
604
                        byte b1 = bb.get();
605
                        double d4 = bb.getDouble();
606
607
                        byte[] s1 = new byte[128];
608
                        bb.get(s1);
609
610
                        short crc = bb.getShort();
611
                        int offset = end - bb.position();
612
                        if(offset > 0)
613
                                bb.position(bb.position() + offset);
614
                }
615
                byte[] crc32 = new byte[32];
616
                bb.get(crc32);
617
        }
618
619
620
621
        /**
622
         * @param layerTable
623
         */
624
        private void readLayerTable(Dwg12Table layerTable) {
625
                short size = layerTable.s1;
626
                int numR = layerTable.i1;
627
                int start = layerTable.i2;
628
                int end = -1;
629
                bb.position(start);
630
631 10515 azabala
                DwgLayer layer = null;
632
633
634 10421 azabala
                for(int i = 0; i < numR; i++){
635 10515 azabala
636
                        layer = new DwgLayer(index);
637
                        index++;
638 10421 azabala
                        end = bb.position() + size;
639
                        byte flag = bb.get();
640 10515 azabala
                        /*
641
                         +=====================================================+
642
          | Flag bit | Meaning                                  |
643
          | value    |                                          |
644
          |----------|------------------------------------------|
645
          | 1        | If set, layer is frozen                  |
646
          |----------|------------------------------------------|
647
          | 2        | If set, layer is frozen by default in    |
648
          |          | new Viewports                            |
649
          |----------|------------------------------------------|
650
          | 4        | If set, layer is locked                  |
651
          +-----------------------------------------------------+
652
                         * */
653
                        if((flag & 0x1) > 0){
654
                                layer.setFrozen(true);
655
                        }
656
                        if((flag & 0x2) > 0){
657
                                layer.setFrozenInNew(true);
658
                        }
659
                        if((flag & 0x4) > 0){
660
                                layer.setLocked(true);
661
                        }
662
663 10421 azabala
                        byte[] nameByte = new byte[32];
664
                        bb.get(nameByte);
665
                        String name = new String(nameByte);
666 10515 azabala
                        layer.setName(name);
667 10421 azabala
668
                        bb.order(ByteOrder.LITTLE_ENDIAN);
669
                        short used = bb.getShort();
670
                        short color = bb.getShort();
671 10515 azabala
                        layer.setColor(color);
672 10421 azabala
                        short style = bb.getShort();
673
                        short crc = bb.getShort();
674
675
                        int offset = end - bb.position();
676 10515 azabala
677
                        //TODO Vemos si el indice que ocupa la layer en la tabla
678
                        //de layers se corresponde con el valor short de las entidades
679
                        //graficas
680
                        DwgHandleReference handle = new DwgHandleReference(0x5, i);
681
                        layer.setHandle(handle);
682
                        dwgFile.addDwgObject(layer);
683 10421 azabala
                        if(offset > 0)
684
                                bb.position(bb.position() + offset);
685
686
                }
687
                byte[] crc32 = new byte[32];
688
                bb.get(crc32);
689
        }
690
691
692
        interface EntityReader{
693 10481 azabala
                void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj);
694 10421 azabala
        }
695
696 10585 azabala
        /**
697
         * In DWG 12 version, some kind of objects (Polylines and Vertex) cannot be
698
         * instanciated until the EntityReader has readed some stuff (flags and so)
699
         * from the file.
700
         *
701
         * DifferedEntityReader has the responsability to create DwgObject instances,
702
         * and it has the precondition that DwgObject parameter of its method read must
703
         * be null.
704
         * */
705
        abstract class DifferedEntityReader implements EntityReader{
706
                abstract DwgObject getDwgObject();
707
708
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj){
709
                        if(dwgObj != null)
710
                                throw new RuntimeException("DifferedEntityReader es el encargado de construir los objetos, debe recibirlos a null");
711
                }
712
713
        }
714
715 10421 azabala
        class LineReader implements EntityReader{
716 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
717
                        if(! (dwgObj instanceof DwgLine))
718
                                throw new RuntimeException("No es entidad LINE");
719
                        DwgLine line = (DwgLine) dwgObj;
720
721 10435 azabala
                        boolean zflag = true;
722
                        if( (flags & 0x4) > 0)
723
                                zflag = false;
724
725
                        double[] pt10 = getPoint(zflag);
726
                        double[] pt11 = getPoint(zflag);
727
728 10481 azabala
                        line.setP1(pt10);
729
                        line.setP2(pt11);
730
731 10435 azabala
                        if((opts & 0x1) > 0){
732
                                double[] pt210 = getPoint(true);
733 10481 azabala
                                line.setExtrusion(pt210);
734 10435 azabala
                        }
735
736
                        if((opts & 0x2) > 0){
737 10481 azabala
                                /*
738
                                 * This field is only found in DWG12 prev
739
                                 * files. Since DWG 12, elevation is saved
740
                                 * in third coordinate of points.
741
                                 *
742
                                 * */
743 10435 azabala
                                bb.order(ByteOrder.LITTLE_ENDIAN);
744
                                double db38 = bb.getDouble();
745 10481 azabala
                                line.getP1()[2] = db38;
746
                                line.getP2()[2] = db38;
747 10435 azabala
                        }
748 10421 azabala
                }
749
        }
750
751 10435 azabala
752
753 10421 azabala
        class PointReader implements EntityReader{
754 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
755
                        if(! (dwgObj instanceof DwgPoint))
756
                                throw new RuntimeException("No es entidad POINT");
757
                        DwgPoint point = (DwgPoint) dwgObj;
758 10435 azabala
                        boolean zflag = true;
759
                        if((flags & 0x4) > 0)
760
                                zflag = false;
761
                        double[] pt10 = getPoint(zflag);
762 10481 azabala
                        point.setPoint(pt10);
763 10435 azabala
764
                        if((opts & 0x1) > 0){
765
                                double[] pt210 = getPoint(true);
766 10481 azabala
                                point.setExtrusion(pt210);
767 10435 azabala
                        }
768
769
                        if((opts & 0x2) > 0){
770
                                bb.order(ByteOrder.LITTLE_ENDIAN);
771
                                double db38 = bb.getDouble();
772 10481 azabala
                                point.getPoint()[2] = db38;
773 10435 azabala
                        }
774 10421 azabala
                }
775
        }
776 10435 azabala
777
778 10421 azabala
        class CircleReader implements EntityReader{
779 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
780
                        if(! (dwgObj instanceof DwgCircle))
781
                                throw new RuntimeException("No es entidad CIRCLE");
782
                        DwgCircle circle = (DwgCircle) dwgObj;
783
784 10435 azabala
                        boolean zflag = true;
785
                        if((flags & 0x4) > 0)
786
                                zflag = false;
787
                        double[] pt10 = getPoint(zflag);
788 10481 azabala
                        circle.setCenter(pt10);
789
790 10435 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
791
                        double d40 = bb.getDouble();
792 10481 azabala
                        circle.setRadius(d40);
793 10435 azabala
794
                        if((opts & 0x1) > 0){
795
                                double[] pt210 = getPoint(true);
796 10481 azabala
                                circle.setExtrusion(pt210);
797 10435 azabala
                        }
798
799
                        if((opts & 0x2) > 0){
800
                                bb.order(ByteOrder.LITTLE_ENDIAN);
801
                                double db38 = bb.getDouble();
802 10481 azabala
                                circle.getCenter()[2] = db38;
803 10435 azabala
                        }
804 10421 azabala
                }
805
        }
806 10435 azabala
807
808
809 10421 azabala
        class ShapeReader implements EntityReader{
810 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
811
812
                        //TODO POR IMPLEMENTAR DwgShape (referencia a un
813
                        //fichero de texto)
814
815 10435 azabala
                        double[] pt10 = getPoint(false);
816
                        bb.order(ByteOrder.LITTLE_ENDIAN);
817
                        short w2 = bb.getShort();
818
                        if((opts & 0x1) > 0){
819
                                double[] pt210 = getPoint(true);
820
                        }
821
                        if((opts & 0x2) > 0){
822
                                bb.order(ByteOrder.LITTLE_ENDIAN);
823
                                double db38 = bb.getDouble();
824
                        }
825 10421 azabala
                }
826
        }
827 10435 azabala
828
        public String getString(){
829
                bb.order(ByteOrder.LITTLE_ENDIAN);
830
                short len = bb.getShort();
831
                byte[] bytes = new byte[len];
832
                bb.order(ByteOrder.nativeOrder());
833
                bb.get(bytes);
834
                return new String(bytes);
835
        }
836 10481 azabala
837
838 10421 azabala
        class TextReader implements EntityReader{
839 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
840
841
                        if(! (dwgObj instanceof DwgText))
842
                                throw new RuntimeException("No es entidad TEXT");
843
                        DwgText txt = (DwgText) dwgObj;
844
845
846 10435 azabala
                        double[] pt10 = getPoint(false);
847 10481 azabala
                        txt.setInsertionPoint(new Point2D.Double(pt10[0], pt10[1]));
848
849
850 10435 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
851
                        double db40 = bb.getDouble();
852 10481 azabala
                        txt.setHeight(db40);
853
854
855
856 10435 azabala
                        String text = getString();
857 10481 azabala
                        txt.setText(text);
858 10435 azabala
                        if((opts & 0x1) > 0){
859
                                bb.order(ByteOrder.LITTLE_ENDIAN);
860
                                double db50 = bb.getDouble();
861 10481 azabala
                                txt.setRotationAngle(db50);
862 10435 azabala
                        }
863
                        if((opts & 0x2) > 0){
864
                                double db41 = bb.getDouble();
865 10481 azabala
                                txt.setWidthFactor(db41);//TODO 41 es width factor seguro?
866 10435 azabala
                        }
867
                        if((opts & 0x4) > 0){
868
                                double db51 = bb.getDouble();
869 10481 azabala
                                txt.setObliqueAngle(db51);
870 10435 azabala
                        }
871
                        if((opts & 0x8) > 0){
872
                                byte b7 = bb.get();
873
                        }
874
                        if((opts & 0x10) > 0){
875
                                byte b71 = bb.get();
876 10481 azabala
                                //parametros de mirroring
877
                                txt.setGeneration(b71);
878 10435 azabala
                        }
879
                        if((opts & 0x20) > 0){
880
                                byte b72 = bb.get();
881 10481 azabala
                                txt.setHalign(b72);
882 10435 azabala
                        }
883
                        if((opts & 0x40) > 0){
884
                                double[] pt11 = getPoint(false);
885 10481 azabala
                                txt.setAlignmentPoint(new Point2D.Double(pt11[0], pt11[1]));
886 10435 azabala
                        }
887
                        if((opts & 0x100) > 0){
888
                                byte b73 = bb.get();
889 10481 azabala
                                txt.setValign(b73);
890 10435 azabala
                        }
891 10537 azabala
892
                        //TODO La especificaci?n DXF 12 dice que la extrusion
893
                        //codigos DXF 210, 220, 230 se aplica sobre:
894
                        /*
895
                         Line, Point, Circle, Shape, Text, Arc, Trace,
896
                         Solid, Block Reference, Polyline,
897
                          Dimension, Attribute, and Attribute Definition entity
898

899
                          Pero aqu? no aparece por ningun lado la extrusion
900
                         * */
901
                        double[] ext = new double[]{0, 0, 1};
902
                        txt.setExtrusion(ext);
903 10421 azabala
                }
904
        }
905 10435 azabala
906
907 10421 azabala
        class ArcReader implements EntityReader{
908 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
909
                        if(! (dwgObj instanceof DwgArc))
910
                                throw new RuntimeException("No es entidad ARC");
911
                        DwgArc arc = (DwgArc) dwgObj;
912
913 10435 azabala
                        double[] pt10 = getPoint(false);
914 10481 azabala
                        arc.setCenter(pt10);
915
916 10435 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
917
                        double d40 = bb.getDouble();
918 10481 azabala
                        arc.setRadius(d40);
919
920 10435 azabala
                        double d50 = bb.getDouble();
921 10481 azabala
                        arc.setInitAngle(d50);
922
923 10435 azabala
                        double d51 = bb.getDouble();
924 10481 azabala
                        arc.setEndAngle(51);
925
926 10435 azabala
                        if((opts & 0x1) > 0){
927
                                double[] pt210 = getPoint(true);
928 10481 azabala
                                arc.setExtrusion(pt210);
929 10435 azabala
                        }
930
                        if((opts & 0x2) > 0){
931
                                bb.order(ByteOrder.LITTLE_ENDIAN);
932
                                double db38 = bb.getDouble();
933 10481 azabala
                                arc.getCenter()[2] = db38;
934 10435 azabala
                        }
935 10421 azabala
                }
936
        }
937
938 10435 azabala
939
940 10421 azabala
        class TraceReader implements EntityReader{
941 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
942
                        //TODO Implementar DwgTrace
943 10435 azabala
                        double[] pt10 = getPoint(false);
944
                        double[] pt11 = getPoint(false);
945
                        double[] pt12 = getPoint(false);
946
                        double[] pt13 = getPoint(false);
947
                        if((opts & 0x1) > 0){
948
                                double[] pt210 = getPoint(true);
949
                        }
950
                        if((opts & 0x2) > 0){
951
                                bb.order(ByteOrder.LITTLE_ENDIAN);
952
                                double db38 = bb.getDouble();
953
                        }
954 10421 azabala
                }
955
        }
956
957
        class SolidReader implements EntityReader{
958 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
959
                        if(! (dwgObj instanceof DwgSolid))
960
                                throw new RuntimeException("No es entidad SOLID");
961
                        DwgSolid solid = (DwgSolid) dwgObj;
962
963
964
965 10435 azabala
                        double[] pt11 = getPoint(false);
966 10481 azabala
                        solid.setCorner1(pt11);
967
968 10435 azabala
                        double[] pt12 = getPoint(false);
969 10481 azabala
                        solid.setCorner2(pt12);
970
971 10435 azabala
                        double[] pt13 = getPoint(false);
972 10481 azabala
                        solid.setCorner3(pt13);
973
974 10435 azabala
                        double[] pt14 = getPoint(false);
975 10481 azabala
                        solid.setCorner4(pt14);
976
977
978 10435 azabala
                        if((opts & 0x1) > 0){
979
                                double[] pt210 = getPoint(true);
980 10481 azabala
                                solid.setExtrusion(pt210);
981 10435 azabala
                        }
982
                        if((opts & 0x2) > 0){
983
                                bb.order(ByteOrder.LITTLE_ENDIAN);
984
                                double db38 = bb.getDouble();
985 10481 azabala
                                solid.getCorner1()[2] = db38;
986
                                solid.getCorner2()[2] = db38;
987
                                solid.getCorner3()[2] = db38;
988
                                solid.getCorner4()[2] = db38;
989 10435 azabala
                        }
990 10421 azabala
                }
991
        }
992
993
        class BlkReader implements EntityReader{
994 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
995
                        if(! (dwgObj instanceof DwgBlockHeader))
996
                                throw new RuntimeException("No es entidad BLOCK");
997
                        DwgBlockHeader blk = (DwgBlockHeader) dwgObj;
998
999
1000 10435 azabala
                        double[] pt10 = getPoint(false);
1001 10481 azabala
                        blk.setBasePoint(pt10);
1002 10435 azabala
                        String blockName = getString();
1003 10481 azabala
1004
                        //TODO En DWG 12 no se distingue Block de BlockHeader, en ulteriores
1005
                        //versiones si
1006
                        //REVISAR EL CASO DE LOS BLOQUES
1007
1008
1009 10435 azabala
                        if((opts & 0x2) > 0)
1010
                        {
1011
                                //puede ser que se trate de referencias
1012
                                //externas??
1013
                                String s3 = getString();
1014
                        }
1015 10481 azabala
1016
                        if((flags & 1) > 0){
1017
                                blk.setAnonymous(true);
1018
                        }
1019
1020
                        if((flags & 2) > 0){
1021
                                blk.setHasAttrs(true);
1022
                        }
1023
1024
                        if((flags & 4) > 0){
1025
                                blk.setBlkIsXRef(true);
1026
                        }
1027
1028
                        if((flags & 16) > 0){
1029
                                blk.setXdep(true);
1030
                        }
1031
1032
                        if((flags & 32) > 0){
1033
                                blk.setXRefOverLaid(true);
1034
                        }
1035
1036
                        if((flags & 64) > 0){
1037
                                blk.setLoaded(true);
1038
                        }
1039
1040
1041
                        /*
1042

1043
                           1        | This is an anonymous Block generated by    |
1044
                  |          | hatching, associative dimensioning, other  |
1045
                  |          | internal operations, or an application     |
1046
                  |----------|--------------------------------------------|
1047
                  | 2        | This Block has Attributes                  |
1048
                  |----------|--------------------------------------------|
1049
                  | 4        | This Block is an external reference (Xref) |
1050
                  |----------|--------------------------------------------|
1051
                  | 8        | not used                                   |
1052
                  |----------|--------------------------------------------|
1053
                  | 16       | This Block is externally dependent         |
1054
                  |----------|--------------------------------------------|
1055
                  | 32       | This is a resolved external reference, or  |
1056
                  |          | dependent of an external reference         |
1057
                  |----------|--------------------------------------------|
1058
                  | 64       | This definition is referenced
1059

1060
                        */
1061 10435 azabala
1062 10421 azabala
                }
1063
        }
1064
        class EndBlkReader implements EntityReader{
1065 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {}
1066 10421 azabala
        }
1067
1068
        class InsertReader implements EntityReader{
1069 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1070
                        if(! (dwgObj instanceof DwgInsert))
1071
                                throw new RuntimeException("No es entidad INSERT");
1072
                        DwgInsert insert = (DwgInsert) dwgObj;
1073
1074 10446 azabala
                        bb.order(ByteOrder.nativeOrder());
1075
                        short w1 = bb.getShort();
1076 10481 azabala
1077
1078
1079 10446 azabala
                        double[] pt10 = getPoint(false);
1080 10481 azabala
                        insert.setInsertionPoint(pt10);
1081 10446 azabala
1082 10481 azabala
1083 10446 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1084 10481 azabala
1085
                        double x = 0d, y = 0d, z = 0d;
1086
1087 10446 azabala
                        if((opts & 0x1) > 0){
1088
                                double db41 = bb.getDouble();
1089 10481 azabala
                                x = db41;
1090 10446 azabala
                        }
1091
1092
                        if((opts & 0x2) > 0){
1093
                                double db42 = bb.getDouble();
1094 10481 azabala
                                y = db42;
1095 10446 azabala
                        }
1096
1097
                        if((opts & 0x4) > 0){
1098
                                double db43 = bb.getDouble();
1099 10481 azabala
                                z = db43;
1100 10446 azabala
                        }
1101
1102 10481 azabala
                        insert.setScale(new double[]{x, y, z});
1103
1104 10446 azabala
                        if((opts & 0x8) > 0){
1105
                                double db50 = bb.getDouble();
1106 10481 azabala
                                insert.setRotation(db50);
1107 10446 azabala
                        }
1108
1109
                        if((opts & 0x10) > 0){
1110 10455 azabala
                                short w70 = bb.getShort();
1111 10481 azabala
                                //column counts
1112 10446 azabala
                        }
1113
                        //creo que esto est? mal, y que debe poner 0x20
1114
                        if((opts & 0x10) > 0){
1115 10455 azabala
                                short w71 = bb.getShort();
1116 10481 azabala
                                //row counts
1117 10446 azabala
                        }
1118
1119 10455 azabala
                        if((opts & 0x40) > 0){
1120
                                double db44 = bb.getDouble();
1121 10481 azabala
                                //column spacing
1122 10455 azabala
                        }
1123 10446 azabala
1124 10455 azabala
                        if((opts & 0x80) > 0){
1125
                                double db45 = bb.getDouble();
1126 10481 azabala
                                //row spacing
1127 10455 azabala
                        }
1128 10421 azabala
                }
1129
        }
1130
1131
        class AttDefReader implements EntityReader{
1132 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1133 10455 azabala
                        double[] p10 = getPoint(false);
1134
                        String s1 = getString();
1135
                        String s3 = getString();
1136
                        String s2 = getString();
1137
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1138
                        byte b70 = bb.get();
1139
1140
                        if((opts & 0x1) > 0){
1141
                                byte b73 = bb.get();
1142
                        }
1143
1144
                        if((opts & 0x2) > 0){
1145
                                double d50 = bb.getDouble();
1146
                        }
1147
1148
                        if((opts & 0x4) > 0){
1149
                                double d41 = bb.getDouble();
1150
                        }
1151
1152
                        if((opts & 0x8) > 0){
1153
                                double d42 = bb.getDouble();
1154
                        }
1155
1156
                        if((opts & 0x10) > 0){
1157
                                byte b7 = bb.get();
1158
                        }
1159
1160
                        if((opts & 0x20) > 0){
1161
                                byte b71 = bb.get();
1162
                        }
1163
1164
                        if((opts & 0x40) > 0){
1165
                                byte b72 = bb.get();
1166
                        }
1167
1168
                        if((opts & 0x80) > 0){
1169
                                double[] p11 = getPoint(false);
1170
                        }
1171
1172
                        if((opts & 0x100) > 0){
1173
                                double[] p210 = getPoint(true);
1174
                        }
1175
1176
                        if((opts & 0x200) > 0){
1177
                                bb.order(ByteOrder.LITTLE_ENDIAN);
1178
                                double d38 = bb.getDouble();
1179
                        }
1180 10421 azabala
                }
1181
        }
1182
1183
        class AttribReader implements EntityReader{
1184 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1185 10455 azabala
                        double[] p10 = getPoint(false);
1186
1187
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1188
                        double d40 = bb.getDouble();
1189
1190
                        String s1 = getString();
1191
                        String s2 = getString();
1192
1193
                        if((opts & 0x1) > 0){
1194
                                byte b73 = bb.get();
1195
                        }
1196
1197
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1198
                        if((opts & 0x2) > 0){
1199
                                double d50 = bb.getDouble();
1200
                        }
1201
1202
                        if((opts & 0x4) > 0){
1203
                                double d41 = bb.getDouble();
1204
                        }
1205
1206
                        if((opts & 0x8) > 0){
1207
                                double d42 = bb.getDouble();
1208
                        }
1209
1210
                        if((opts & 0x10) > 0){
1211
                                byte b7 = bb.get();
1212
                        }
1213
1214
                        if((opts & 0x20) > 0){
1215
                                byte b71 = bb.get();
1216
                        }
1217
1218
                        if((opts & 0x40) > 0){
1219
                                byte b72 = bb.get();
1220
                        }
1221
1222
                        if((opts & 0x80) > 0){
1223
                                double[] p11 = getPoint(false);
1224
                        }
1225
1226
                        if((opts & 0x100) > 0){
1227
                                double[] p210 = getPoint(true);
1228
                        }
1229
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1230
                        if((opts & 0x200) > 0){
1231
                                double d38 = bb.getDouble();
1232
                        }
1233 10421 azabala
                }
1234
        }
1235 10455 azabala
1236
1237 10421 azabala
        class SbEndReader implements EntityReader{
1238 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1239 10455 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1240
                        int l = bb.getInt();
1241 10421 azabala
                }
1242
        }
1243
1244 10585 azabala
        class PlineReader extends DifferedEntityReader{
1245 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1246 10585 azabala
                        super.read(bb, flags, opts, dwgObj);
1247
1248
                        //TODO El byte 70 es el que determina el tipo de Polyline
1249 10455 azabala
                        if( (opts & 0x1) > 0){
1250
                                byte b70 = bb.get();
1251
                        }
1252
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1253
                        if( (opts & 0x2) > 0){
1254
                                double d40 = bb.getDouble();
1255
                        }
1256
1257
                        if( (opts & 0x4) > 0){
1258
                                byte b71 = bb.get();
1259
                        }
1260
1261
                        if( (opts & 0x8) > 0){
1262
                                byte b72 = bb.get();
1263
                        }
1264
1265
                        if( (opts & 0x10) > 0){
1266
                                byte b73 = bb.get();
1267
                        }
1268
1269
                        if( (opts & 0x20) > 0){
1270
                                byte b74 = bb.get();
1271
                        }
1272
1273
                        if( (opts & 0x40) > 0){
1274
                                byte b75 = bb.get();
1275
                        }
1276 10421 azabala
                }
1277 10585 azabala
1278
                DwgObject getDwgObject() {
1279
                        // TODO Auto-generated method stub
1280
                        return null;
1281
                }
1282 10421 azabala
        }
1283
1284 10585 azabala
        class VertexReader extends DifferedEntityReader{
1285 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1286 10455 azabala
                        double[] pt10 = getPoint(false);
1287
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1288
                        if((opts & 0x1) > 0){
1289
                                double d40 = bb.getDouble();
1290
                        }
1291
                        if((opts & 0x2) > 0){
1292
                                double d41 = bb.getDouble();
1293
                        }
1294
                        if((opts & 0x4) > 0){
1295
                                double d50 = bb.getDouble();
1296
                        }
1297
                        if((opts & 0x8) > 0){
1298
                                byte b70 = bb.get();
1299
                        }
1300 10421 azabala
                }
1301 10585 azabala
1302
                DwgObject getDwgObject() {
1303
                        // TODO Auto-generated method stub
1304
                        return null;
1305
                }
1306 10421 azabala
        }
1307
1308
        class Face3DReader implements EntityReader{
1309 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1310 10455 azabala
                        boolean zflag = false;
1311
                        if((flags & 0x4) > 0){
1312
                                zflag = true;
1313
                        }
1314
                        double[] pt10 = getPoint(zflag);
1315
                        double[] pt11 = getPoint(zflag);
1316
                        double[] pt12 = getPoint(zflag);
1317
                        double[] pt13 = getPoint(zflag);
1318
1319 10421 azabala
                }
1320
        }
1321
1322
        class DimReader implements EntityReader{
1323 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1324 10455 azabala
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1325
                        short w1 = bb.getShort();
1326
                        double[] pt10 = getPoint(true);
1327
                        double[] pt11 = getPoint(false);
1328
1329
                        if((opts & 0x2) > 0){
1330
                                byte b70 = bb.get();
1331
                        }
1332
1333
                        if((opts & 0x1) > 0){
1334
                                double[] pt12 = getPoint(true);
1335
                        }
1336
1337
                        if((opts & 0x4) > 0){
1338
                                String s1 = getString();
1339
                        }
1340
1341
                        if((opts & 0x8) > 0){
1342
                                double[] pt13 = getPoint(true);
1343
                        }
1344
1345
                        if((opts & 0x10) > 0){
1346
                                double[] pt13 = getPoint(true);
1347
                        }
1348
1349
                        if((opts & 0x20) > 0){
1350
                                double[] pt15 = getPoint(true);
1351
                        }
1352
1353
                        if((opts & 0x40) > 0){
1354
                                double[] pt16 = getPoint(true);
1355
                        }
1356
1357
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1358
                        if((opts & 0x80) > 0){
1359
                                double d40 = bb.getDouble();
1360
                        }
1361
1362
                        if((opts & 0x100) > 0){
1363
                                double d50 = bb.getDouble();
1364
                        }
1365
1366
                        if((opts & 0x200) > 0){
1367
                                double d51 = bb.getDouble();
1368
                        }
1369
                        if((opts & 0x400) > 0){
1370
                                double d52 = bb.getDouble();
1371
                        }
1372
                        if((opts & 0x800) > 0){
1373
                                double d53 = bb.getDouble();
1374
                        }
1375 10421 azabala
                }
1376
        }
1377
1378
        class VPortReader implements EntityReader{
1379 10481 azabala
                public void read(ByteBuffer bb, byte flags, short opts, DwgObject dwgObj) {
1380 10455 azabala
                        double[] pt10 = getPoint(true);
1381
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1382
                        double d40 = bb.getDouble();
1383
                        double d41 = bb.getDouble();
1384
                        short w68 = bb.getShort();
1385 10421 azabala
                }
1386
        }
1387
1388
1389
1390
        /**
1391
         * @param start
1392
         * @param end
1393
         */
1394
        private void readEntities(int start, int end) {
1395
                bb.position(start);
1396
                int ant = bb.position();
1397
                int emax = readers.size();
1398 10481 azabala
                EntityReader reader = null;
1399
1400 10421 azabala
                while(ant < (end - 32)){
1401
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1402 10537 azabala
1403 10455 azabala
                        byte kind = bb.get();
1404 10481 azabala
                        if(kind < emax){
1405
                                reader = (EntityReader) readers.get(kind);
1406
                        }//if
1407
1408 10537 azabala
1409 10481 azabala
                        //PROPERTIES COMMON TO ALL DWG 12 ENTITIES
1410 10455 azabala
                        byte flag = bb.get();
1411 10421 azabala
                        short lenght = bb.getShort();
1412
1413 10537 azabala
                        //segun esto los dos ultimos bytes son el CRC
1414 10421 azabala
                        int crcpos = ant + (lenght - 2);
1415 10537 azabala
1416
1417 10421 azabala
                        short layer = bb.getShort();
1418
                        short opts = bb.getShort();
1419
1420
                        byte color = 0;
1421
                        if ((flag & 0x1) > 0){
1422
                                color = bb.get();
1423
                        }
1424 10537 azabala
1425 10421 azabala
                        byte extra = 0;
1426
                        if ((flag & 0x40) > 0)
1427
                                extra = bb.get();
1428
1429 10537 azabala
1430 10481 azabala
                        String xdata = null;
1431 10421 azabala
                        if((extra & 0x2) > 0)
1432
                                xdata = readXdata();
1433
1434 10537 azabala
1435 10421 azabala
                        short type = 0;
1436
                        if((flag & 0x2) > 0)
1437
                                type = bb.getShort();
1438
1439 10537 azabala
1440 10421 azabala
                        double z = 0d;
1441
                        if( (flag & 0x4) > 0 && (kind > 2) && (kind != 22)){
1442
                                z = bb.getDouble();
1443
                        }
1444
1445
                        double th = 0d;
1446
                        if((flag & 0x8) > 0){
1447
                                th = bb.getDouble();
1448
                        }
1449
1450 10481 azabala
                        byte[] handle = null;
1451 10421 azabala
                        if((flag & 0x20) > 0)
1452
                                handle = getHandle();
1453 10537 azabala
1454 10421 azabala
                        short paper = 0;
1455
                        if((extra & 0x4) > 0){
1456
                                paper = bb.getShort();
1457
                        }
1458
1459 10481 azabala
                        if(reader != null){
1460
                                DwgObject entity = null;
1461
                                if(reader instanceof PlineReader){
1462 10537 azabala
                                        System.out.println("plinereader");
1463 10585 azabala
1464
1465
1466
1467
1468 10481 azabala
                                }else if(reader instanceof VertexReader){
1469 10537 azabala
                                        System.out.println("vertexreader");
1470 10585 azabala
1471
1472
1473
1474
1475
1476
1477
1478
1479 10481 azabala
                                }else{
1480
                                        entity = DwgObjectFactory.
1481
                                                                getInstance().
1482
                                                                create(kind, index);
1483 10421 azabala
                                }
1484 10481 azabala
                                entity.setColor(color);
1485
                                entity.setType(type);//TODO Este type es el mismo que para DWG 13-14-2000?
1486
                                entity.setSizeInBits(lenght);//TODO Este size es el mismo que para DWG 13-14-2000?
1487
                                /*
1488
                                 * TODO
1489
                                 * Parece ser que DWG 12 no gestiona las layers al igual que las
1490
                                 * versiones sucesivas (hay que descifrar si 'layer' significa
1491
                                 * un orden en la tabla de layers
1492
                                 *
1493
                                 * De ser as?, y si indexamos las layers de esta forma
1494
                                 * (con un HandleReference de code 0x5) ser? todo homogeneo
1495 10537 azabala
                                 *
1496
                                 * TODO Construir instancias de DwgLayer a partir de las entradas
1497
                                 * de la tabla de layers, e indexarlas con un handle igual a su orden
1498 10481 azabala
                                 * */
1499
1500
                                entity.setLayerHandle(new DwgHandleReference(0x5, layer));
1501
1502
                                //TODO El valor de elevation en 12 es comun a todas, en 13 y ulteriores
1503
                                //no. ver que se hace
1504
//                                entity.setZ(z);
1505
1506
                                List xdataAsList = new ArrayList();
1507
                                xdataAsList.add(xdata);
1508
                                entity.setExtendedData(xdataAsList);
1509
1510
                                //TODO con thickness tenemos el mismo problema que con
1511
                                //elevation. En dwg 12 es comun a todos
1512
//                                entity.setThickness(th);
1513
1514
1515
                                //TODO HANDLES. Tampoco se si en DWG 12 se leen
1516 10537 azabala
                                //igual que en DWG 13 y posteriores
1517
                                if(handle != null){
1518
                                        int offset = handle.hashCode();
1519
                                        DwgHandleReference hdl = new DwgHandleReference(0, offset);
1520
                                        entity.setHandle(hdl);
1521
                                }else{
1522
                                        System.out.println("HANDLE A NULL");
1523
                                        bb.position(crcpos);
1524
                                        short crc = bb.getShort();
1525
                                        continue;
1526
                                }
1527 10481 azabala
1528
                                //TODO Idem con el espacio papel o el espacio modelo
1529
                                boolean paperSpace = false;
1530
                                if(paper != 0){
1531
                                        paperSpace = true;
1532
                                }
1533
1534
                                reader.read(bb, flag, opts, entity);
1535 10585 azabala
1536
1537
1538 10481 azabala
                                ant = bb.position();
1539
                                if(ant < crcpos){
1540
                                        bb.position(bb.position() + (crcpos - ant));
1541
                                }
1542
                                short crc = bb.getShort();
1543
1544
//                                if(! paperSpace)//TODO solo a?adimos las entidades en espacio modelo????
1545
                                dwgFile.addDwgObject(entity);
1546
1547
                        }//if reader
1548 10537 azabala
                        else{
1549
                                System.out.println("Reader a NULL. DWG 12 MAL LEIDO");
1550
                                System.out.println("kind = " + kind);
1551
                                bb.position(crcpos);
1552
                                short crc = bb.getShort();
1553
                                continue;
1554
1555
                        }
1556 10421 azabala
                        ant = bb.position();
1557 10537 azabala
//                        byte[] crc32 = new byte[32];
1558
//                        bb.get(crc32);
1559 10515 azabala
                        index++;
1560 10421 azabala
                }//while
1561 10537 azabala
                byte[] crc32 = new byte[32];//TODO va dentro o fuera del while??
1562
                bb.get(crc32);
1563 10421 azabala
        }
1564
1565
1566
        /**
1567
         * @return
1568
         */
1569
        private byte[] getHandle() {
1570
                 byte[] bytes = null;
1571
                 bb.order(ByteOrder.nativeOrder());
1572
                 byte len = bb.get();
1573
                 bytes = new byte[len];
1574
                 bb.get(bytes);
1575
                 return bytes;
1576
//Ver si los handles de DWG 12 concurdan con nuestra clase
1577
//DwgHandleReference
1578
//             return (5, _len) + tuple(_bytes)
1579
        }
1580
1581
1582
1583
        /**
1584
         * @return
1585
         */
1586
        private String readXdata() {
1587
                String extData = "";
1588
                short xlen = bb.getShort();
1589
                while (xlen > 0){
1590
                        byte xval = bb.get();
1591
                        xlen--;
1592
                        if(xval == 0){
1593
                                if(xlen < 1)
1594
                                        break;
1595
                                byte val = bb.get();
1596
                                xlen--;
1597
                                if(r13){
1598
                                        if(xlen < 1)
1599
                                                break;
1600
                                        byte codePage = bb.get();
1601
                                        xlen--;
1602
                                }//if r13
1603
                                if(xlen < val)
1604
                                        break;
1605
                                byte[] strByte = new byte[val];
1606
                                bb.get(strByte);
1607
                                xlen -= val;
1608
                                extData += new String(strByte);
1609
                        }//if xval == 0
1610
                        else if(xval == 1 || xval == 3 || xval == 70){
1611
                                if(xlen < 2)
1612
                                        break;
1613
                                short val = bb.getShort();
1614
                                extData += val;
1615
                                xlen += 2;
1616
                        }else if(xval == 2){
1617
                                if(xlen < 1)
1618
                                        break;
1619
                                byte val = bb.get();
1620
                                if(val == 0)
1621
                                        extData += "{";
1622
                                else if(val == 1)
1623
                                        extData += "}";
1624
                                else
1625 10455 azabala
                                        System.out.println("Byte no esperado:"+val);
1626 10421 azabala
                        }else if(xval == 5){
1627
                                if(xlen < 8)
1628
                                        break;
1629
                                long val = bb.getLong();
1630
                                //probably it is an entity handle
1631
                                xlen -= 8;
1632
                        }else if (xval == 40 || xval == 41 || xval == 42){
1633
                                if (xlen < 8)
1634
                                        break;
1635
                                double val = bb.getDouble();
1636
                                xlen -= 8;
1637
                                extData += val;
1638
1639
                        }else if (xval == 10 || xval == 11 || xval == 12 || xval == 13){
1640
                                //13 not in R12 spec, is in R13/R14
1641
                                if(xlen < 24)
1642
                                        break;
1643
                                Object point = getPoint(true);
1644
                                extData += point.toString();
1645
                                xlen -= 24;
1646
                        }else if(xval == 71){
1647
                                if (xlen < 4)
1648
                                        break;
1649
                                int val = bb.getInt();
1650
                                extData += val;
1651
                                xlen -= 4;
1652
                        }else
1653
                                xlen = 0;
1654
                        return extData;
1655
                }
1656
                /*
1657

1658

1659

1660
        elif _xval == 71:
1661
            if _xlen < 4: break
1662
            _val = struct.unpack('<l', handle.read(4))[0]
1663
            _data.append(_val)
1664
            _xlen = _xlen - 4
1665
        else:
1666
            _xlen = 0
1667
    return _data
1668
                 * */
1669
                return null;
1670
        }
1671
1672
1673
1674
        /**
1675
         * @param b
1676
         * @return
1677
         */
1678
        private double[] getPoint(boolean b) {
1679
                bb.order(ByteOrder.LITTLE_ENDIAN);
1680
                double x = bb.getDouble();
1681
                double y = bb.getDouble();
1682
                double z = 0d;
1683
                if(b){
1684
                        z = bb.getDouble();
1685
                }
1686
                return new double[]{x, y, z};
1687
        }
1688
1689
1690
1691
        //TODO Que se hacen con los registros que se leen???
1692
        private void readBlockTable(Dwg12Table blockTable) {
1693
                short size = blockTable.s1;
1694
                int numRecords = blockTable.i1;
1695
                int start = blockTable.i2;
1696
                bb.position(start);
1697
1698
                int end = -1;
1699
1700
                for(int i = 0; i < numRecords; i++){
1701
                        end = bb.position() + size;
1702 10481 azabala
                        byte flag = bb.get();
1703 10421 azabala
                        //TODO No estoy muy seguro de que esto sea
1704
                        //igual que handle.read(32) en Python
1705
                        byte[] nameByte = new byte[32];
1706
                        bb.get(nameByte);
1707
                        String name = new String(nameByte);
1708
1709
                        bb.order(ByteOrder.LITTLE_ENDIAN);
1710
1711
                        short used = bb.getShort();
1712 10481 azabala
                        byte b1 = bb.get();
1713 10421 azabala
                        short w1 = bb.getShort();
1714 10481 azabala
                        byte b2 = bb.get();
1715 10421 azabala
                        short w2 = bb.getShort();
1716
                        short crc = bb.getShort();
1717
1718
                        int offset = end - bb.position();
1719
                        if(offset > 0)
1720
                                bb.position(bb.position() + end);
1721
                }
1722
                byte[] crc32 = new byte[32];
1723
                bb.get(crc32);
1724
        }
1725
1726 10289 azabala
        public void readHeader(){
1727 10435 azabala
                bb.order(ByteOrder.LITTLE_ENDIAN);
1728
                short w1 = bb.getShort();
1729
                double[] inBase = getPoint(true);
1730
                double[] extMin = getPoint(true);
1731
                double[] extMax = getPoint(true);
1732
                double[] limMin = getPoint(false);
1733
                double[] limMax = getPoint(false);
1734 10289 azabala
1735 10435 azabala
                bb.order(ByteOrder.LITTLE_ENDIAN);
1736
                double vcx = bb.getDouble();
1737
                double vcy = bb.getDouble();
1738
                double d3 = bb.getDouble();
1739
                double d4 = bb.getDouble();
1740 10289 azabala
1741 10435 azabala
                byte b1 = bb.get();
1742
                byte b2 = bb.get();
1743 10289 azabala
1744 10435 azabala
                double sx = bb.getDouble();
1745
                double sy = bb.getDouble();
1746
1747
                bb.order(ByteOrder.nativeOrder());
1748
                byte[] b56 = new byte[56];
1749
                bb.get(b56);
1750
1751
                bb.order(ByteOrder.LITTLE_ENDIAN);
1752
                double d7 = bb.getDouble();
1753
                double d8 = bb.getDouble();
1754
                double d9 = bb.getDouble();
1755
1756
                bb.order(ByteOrder.nativeOrder());
1757
                byte[] b18 = new byte[18];
1758
                bb.get(b18);
1759
1760
                bb.order(ByteOrder.LITTLE_ENDIAN);
1761
                double d10 = bb.getDouble();
1762
1763
                int at = bb.position();
1764
1765
                bb.order(ByteOrder.LITTLE_ENDIAN);
1766
                short w2 = bb.getShort();
1767
                short w3 = bb.getShort();
1768
1769
                bb.order(ByteOrder.nativeOrder());
1770
                byte[] b44 = new byte[44];
1771
                bb.get(b44);
1772
1773
                at = bb.position();
1774
1775
                bb.order(ByteOrder.nativeOrder());
1776
                byte[] b354 = new byte[354];
1777
                bb.get(b354);
1778
1779
                if( (b354[0] == 0x61) && (b354[1] == 0x63) && (b354[2] == 0x61 ) && (b354[2] == 0x64 ))
1780
                        System.out.println("Encontrada la cadena 'acad' al comienzo del bloque de 354 bytes");
1781
1782
                bb.position(0x3ef);
1783 10289 azabala
        }
1784
1785
1786
1787
1788
1789
        class Dwg12Table{
1790
                short s1;
1791
                int i1;
1792
                int i2;
1793
        }
1794
1795
        public Dwg12Table getTable(){
1796
1797
                Dwg12Table solution = null;
1798
                bb.order(ByteOrder.LITTLE_ENDIAN);
1799
1800
                short s1 = bb.getShort();
1801
                int i1 = bb.getInt();
1802
                int i2 = bb.getInt();
1803
1804
                solution = new Dwg12Table();
1805
                solution.s1 = s1;
1806
                solution.i1 = i1;
1807
                solution.i2 = i2;
1808
                return solution;
1809
        }
1810
1811
1812
        class Dwg12TableTest{
1813
                short s1, s2, s3;
1814
                int i1;
1815
        }
1816
        public Dwg12TableTest getTableTest(){
1817
                Dwg12TableTest solution = null;
1818
1819
1820
                bb.order(ByteOrder.LITTLE_ENDIAN);
1821
                short s1 = bb.getShort();
1822
                short s2 = bb.getShort();
1823
                short s3 = bb.getShort();
1824
                int i1 = bb.getInt();
1825
1826
                solution = new Dwg12TableTest();
1827
                solution.s1 = s1;
1828
                solution.s2 = s2;
1829
                solution.s3 = s3;
1830
                solution.i1 = i1;
1831
1832
                return solution;
1833
        }
1834
1835
        /* (non-Javadoc)
1836
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#readObjectHeader(int[], int, com.iver.cit.jdwglib.dwg.DwgObject)
1837
         */
1838
        public int readObjectHeader(int[] data, int offset, DwgObject dwgObject) throws RuntimeException, CorruptedDwgEntityException {
1839
                return 0;
1840
        }
1841
1842
        /* (non-Javadoc)
1843
         * @see com.iver.cit.jdwglib.dwg.readers.IDwgFileReader#readObjectTailer(int[], int, com.iver.cit.jdwglib.dwg.DwgObject)
1844
         */
1845
        public int readObjectTailer(int[] data, int offset, DwgObject dwgObject) throws RuntimeException, CorruptedDwgEntityException {
1846
                return 0;
1847
        }
1848
1849
}