1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2010-2019 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 /*
14 * print.c: print helper functions
15 * written by Rodrigo Rodrigues da Silva
16 * modified by Reini Urban
17 */
18
19 #include "config.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24
25 #include "common.h"
26 #include "bits.h"
27 #include "dwg.h"
28 #include "decode.h"
29 #include "print.h"
30
31 #define DWG_LOGLEVEL DWG_LOGLEVEL_TRACE
32 #include "logging.h"
33
34 /* the current version per spec block */
35 static unsigned int cur_ver = 0;
36 static BITCODE_BL rcount1, rcount2;
37
38 /*--------------------------------------------------------------------------------
39 * MACROS
40 */
41
42 #define ACTION print
43 #define IS_PRINT
44 #undef USE_WRITE
45
46 #define FIELD(nam, type) FIELD_TRACE (nam, type)
47 #define FIELDG(nam, type, dxf) FIELD_G_TRACE (nam, type, dxf)
48 #define FIELD_TRACE(nam, type) \
49 LOG_TRACE (#nam ": " FORMAT_##type " [" #type "]\n", _obj->nam)
50 #define FIELD_G_TRACE(nam, type, dxf) \
51 LOG_TRACE (#nam ": " FORMAT_##type " [" #type " " #dxf "]\n", _obj->nam)
52 #define FIELD_CAST(nam, type, cast, dxf) \
53 LOG_TRACE (#nam ": " FORMAT_##type " [" #type " " #dxf "]\n", \
54 (BITCODE_##type)_obj->nam)
55 #define SUB_FIELD(o, nam, type, dxf) FIELDG (o.nam, type, dxf)
56 #define SUB_FIELD_CAST(o, nam, type, cast, dxf) \
57 FIELD_G_TRACE (o.nam, cast, dxf)
58
59 #define LOG_INSANE_TF(var, len)
60 #define FIELD_VALUE(name) _obj->name
61 #define FIELD_2PT_TRACE(name, type, dxf) \
62 { \
63 LOG_TRACE (#name ": (" FORMAT_BD ", " FORMAT_BD ") [" #type " %d]\n", \
64 _obj->name.x, _obj->name.y, dxf); \
65 }
66 #define FIELD_3PT_TRACE(name, type, dxf) \
67 { \
68 LOG_TRACE (#name ": (" FORMAT_BD ", " FORMAT_BD ", " FORMAT_BD \
69 ") [" #type " %d]\n", \
70 _obj->name.x, _obj->name.y, _obj->name.z, dxf); \
71 }
72
73 #define ANYCODE -1
74 #define VALUE_HANDLE(handleptr, name, handle_code, dxf) \
75 if (handleptr) \
76 { \
77 LOG_TRACE (#name ": HANDLE" FORMAT_REF " [%d]\n", ARGS_REF (handleptr), \
78 dxf); \
79 }
80 #define FIELD_HANDLE(nam, handle_code, dxf) \
81 VALUE_HANDLE (_obj->nam, nam, handle_code, dxf)
82 #define SUB_FIELD_HANDLE(o, nam, handle_code, dxf) \
83 VALUE_HANDLE (_obj->o.nam, nam, handle_code, dxf)
84 #define FIELD_DATAHANDLE(nam, code, dxf) FIELD_HANDLE (nam, code, dxf)
85 #define VALUE_HANDLE_N(handleptr, name, vcount, handle_code, dxf) \
86 if (handleptr) \
87 { \
88 LOG_TRACE (#name "[%d]: HANDLE" FORMAT_REF " [%d]\n", (int)vcount, \
89 ARGS_REF (handleptr), dxf); \
90 }
91 #define FIELD_HANDLE_N(name, vcount, handle_code, dxf) \
92 VALUE_HANDLE_N (_obj->name, name, vcount, handle_code, dxf)
93
94 #define FIELD_B(name, dxf) FIELDG (name, B, dxf);
95 #define FIELD_BB(name, dxf) FIELDG (name, BB, dxf);
96 #define FIELD_3B(name, dxf) FIELDG (name, 3B, dxf);
97 #define FIELD_BS(name, dxf) FIELDG (name, BS, dxf);
98 #define FIELD_BL(name, dxf) FIELDG (name, BL, dxf);
99 #define FIELD_BLL(name, dxf) FIELDG (name, BLL, dxf);
100 #define FIELD_BD(name, dxf) \
101 { \
102 if (bit_isnan (_obj->name)) \
103 { \
104 LOG_ERROR ("Invalid BD " #name); \
105 return DWG_ERR_VALUEOUTOFBOUNDS; \
106 } \
107 FIELDG (name, BD, dxf); \
108 }
109 #define FIELD_RC(name, dxf) FIELDG (name, RC, dxf);
110 #define FIELD_RS(name, dxf) FIELDG (name, RS, dxf);
111 #define FIELD_RD(name, dxf) \
112 { \
113 if (bit_isnan (_obj->name)) \
114 { \
115 LOG_ERROR ("Invalid BD " #name); \
116 return DWG_ERR_VALUEOUTOFBOUNDS; \
117 } \
118 FIELDG (name, RD, dxf); \
119 }
120 #define FIELD_RL(name, dxf) FIELDG (name, RL, dxf);
121 #define FIELD_RLL(name, dxf) FIELDG (name, RLL, dxf);
122 #define FIELD_RLx(name, dxf) \
123 LOG_TRACE (#name ": %x [RL " #dxf "]\n", _obj->name)
124 #define FIELD_MC(name, dxf) FIELDG (name, MC, dxf);
125 #define FIELD_MS(name, dxf) FIELDG (name, MS, dxf);
126 #define FIELD_TF(name, len, dxf) \
127 { \
128 LOG_TRACE (#name ": [%d TF " #dxf "]\n", len); \
129 LOG_INSANE_TF (FIELD_VALUE (name), (int)len); \
130 }
131 #define FIELD_TFF(name, len, dxf) \
132 { \
133 LOG_TRACE (#name ": [%d TFF " #dxf "]\n", len); \
134 LOG_INSANE_TF (FIELD_VALUE (name), (int)len); \
135 }
136
137 #define FIELD_TV(name, dxf) FIELDG (name, TV, dxf);
138 #define FIELD_TU(name, dxf) LOG_TRACE_TU (#name, (BITCODE_TU)_obj->name, dxf)
139 #define FIELD_T FIELD_TV /*TODO: implement version dependent string fields */
140 #define FIELD_BT(name, dxf) FIELDG (name, BT, dxf);
141 #define FIELD_4BITS(nam, dxf) \
142 { \
143 int _b = _obj->nam; \
144 LOG_TRACE (#nam ": b%d%d%d%d [4BITS %d]\n", _b & 8, _b & 4, _b & 2, \
145 _b & 1, dxf); \
146 }
147 #define FIELD_BE(name, dxf) FIELD_3RD (name, dxf)
148 #define FIELD_DD(name, _default, dxf)
149 #define FIELD_2DD(name, def, dxf) FIELD_2PT_TRACE (name, DD, dxf)
150 #define FIELD_3DD(name, def, dxf) FIELD_3PT_TRACE (name, DD, dxf)
151 #define FIELD_2RD(name, dxf) FIELD_2PT_TRACE (name, RD, dxf)
152 #define FIELD_2BD(name, dxf) FIELD_2PT_TRACE (name, BD, dxf)
153 #define FIELD_2BD_1(name, dxf) FIELD_2PT_TRACE (name, BD, dxf)
154 #define FIELD_3RD(name, dxf) FIELD_3PT_TRACE (name, RD, dxf)
155 #define FIELD_3BD(name, dxf) FIELD_3PT_TRACE (name, BD, dxf)
156 #define FIELD_3BD_1(name, dxf) FIELD_3PT_TRACE (name, BD, dxf)
157 #define FIELD_3DPOINT(name, dxf) FIELD_3BD (name, dxf)
158 #define FIELD_CMC(color, dxf) \
159 { \
160 LOG_TRACE (#color ".index: %d [CMC.BS %d]\n", _obj->color.index, dxf) \
161 if (dat->version >= R_2004) \
162 { \
163 LOG_TRACE (#color ".rgb: 0x%06x [CMC.BL %d]\n", \
164 (unsigned)_obj->color.rgb, dxf + 420 - 62); \
165 LOG_TRACE (#color ".flag: 0x%x [CMC.RC]\n", \
166 (unsigned)_obj->color.flag); \
167 if (_obj->color.flag & 1) \
168 LOG_TRACE (#color ".name: %s [CMC.TV]\n", _obj->color.name); \
169 if (_obj->color.flag & 2) \
170 LOG_TRACE (#color ".bookname: %s [CMC.TV]\n", \
171 _obj->color.book_name); \
172 } \
173 }
174 #define SUB_FIELD_CMC(o, color, dxf) \
175 { \
176 LOG_TRACE (#color ".index: %d [CMC.BS %d]\n", _obj->o.color.index, dxf) \
177 if (dat->version >= R_2004) \
178 { \
179 LOG_TRACE (#color ".rgb: 0x%06x [CMC.BL %d]\n", \
180 (unsigned)_obj->o.color.rgb, dxf + 420 - 62); \
181 LOG_TRACE (#color ".flag: 0x%x [CMC.RC]\n", \
182 (unsigned)_obj->o.color.flag); \
183 if (_obj->o.color.flag & 1) \
184 LOG_TRACE (#color ".name: %s [CMC.TV]\n", _obj->o.color.name); \
185 if (_obj->o.color.flag & 2) \
186 LOG_TRACE (#color ".bookname: %s [CMC.TV]\n", \
187 _obj->o.color.book_name); \
188 } \
189 }
190 #define FIELD_ENC(color, dxf1, dxf2) \
191 { \
192 LOG_TRACE (#color ".index: %d [ENC.BS %d]\n", _obj->color.index, dxf1); \
193 if (dat->version >= R_2004) \
194 { \
195 if (_obj->color.flag) \
196 LOG_TRACE (#color ".flag: 0x%x\n", (unsigned)_obj->color.flag); \
197 if (_obj->color.flag & 0x20) \
198 LOG_TRACE (#color ".alpha: 0%d [ENC.BL %d]\n", \
199 (int)_obj->color.alpha, dxf + 440 - 62); \
200 if (_obj->color.flag & 0x40) \
201 LOG_TRACE (#color ".handle: " FORMAT_REF " [ENC.H %d]\n", \
202 ARGS_REF (_obj->color.handle), dxf + 430 - 62); \
203 if (_obj->color.flag & 0x80) \
204 LOG_TRACE (#color ".rgb: 0x%06x [ENC.BL %d]\n", \
205 (unsigned)_obj->color.rgb, dxf + 420 - 62); \
206 } \
207 }
208
209 #define FIELD_TIMEBLL(name, dxf) \
210 LOG_TRACE (#name " " #dxf ": " FORMAT_BL "." FORMAT_BL "\n", \
211 _obj->name.days, _obj->name.ms)
212
213 #define VALUE(value, type, dxf) \
214 LOG_TRACE (FORMAT_##type " [" #type " " #dxf "]\n", value)
215 #define VALUE_RC(value, dxf) VALUE (value, RC, dxf)
216 #define VALUE_RS(value, dxf) VALUE (value, RS, dxf)
217 #define VALUE_RL(value, dxf) VALUE (value, RL, dxf)
218 #define VALUE_RLx(value, dxf) \
219 LOG_TRACE (FORMAT_RLx " [RL " #dxf "]\n", (BITCODE_RL)value)
220 #define VALUE_RD(value, dxf) VALUE (value, RD, dxf)
221 #define VALUE_BD(value, dxf) VALUE (value, BD, dxf)
222
223 // FIELD_VECTOR_N(name, type, size):
224 // reads data of the type indicated by 'type' 'size' times and stores
225 // it all in the vector called 'name'.
226 #define FIELD_VECTOR_N(name, type, size, dxf) \
227 if (size > 0 && _obj->name != NULL) \
228 { \
229 for (vcount = 0; vcount < (BITCODE_BL)size; vcount++) \
230 { \
231 LOG_TRACE (#name "[%ld]: " FORMAT_##type "\n", (long)vcount, \
232 _obj->name[vcount]) \
233 } \
234 }
235 #define FIELD_VECTOR_T(name, type, size, dxf) \
236 if (_obj->size > 0 && _obj->name != NULL) \
237 { \
238 for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++) \
239 { \
240 PRE (R_2007) \
241 { \
242 LOG_TRACE (#name "[%ld]: %s\n", (long)vcount, _obj->name[vcount]) \
243 } \
244 else \
245 { \
246 LOG_TRACE_TU (#name, _obj->name[vcount], dxf) \
247 } \
248 } \
249 }
250
251 #define FIELD_VECTOR(name, type, size, dxf) \
252 FIELD_VECTOR_N (name, type, _obj->size, dxf)
253
254 #define FIELD_2RD_VECTOR(name, size, dxf) \
255 if (_obj->name) \
256 { \
257 for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++) \
258 { \
259 FIELD_2RD (name[vcount], dxf); \
260 } \
261 }
262
263 #define FIELD_2DD_VECTOR(name, size, dxf) \
264 if (_obj->name) \
265 { \
266 FIELD_2RD (name[0], 0); \
267 for (vcount = 1; vcount < (BITCODE_BL)_obj->size; vcount++) \
268 { \
269 FIELD_2DD (name[vcount], name[vcount - 1], dxf); \
270 } \
271 }
272
273 #define FIELD_3DPOINT_VECTOR(name, size, dxf) \
274 if (_obj->name) \
275 { \
276 for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++) \
277 { \
278 FIELD_3DPOINT (name[vcount], dxf); \
279 } \
280 }
281
282 #define HANDLE_VECTOR_N(name, size, code, dxf) \
283 if (_obj->name) \
284 { \
285 for (vcount = 0; vcount < (BITCODE_BL)size; vcount++) \
286 { \
287 FIELD_HANDLE_N (name[vcount], vcount, code, dxf); \
288 } \
289 }
290
291 #define HANDLE_VECTOR(name, sizefield, code, dxf) \
292 HANDLE_VECTOR_N (name, FIELD_VALUE (sizefield), code, dxf)
293
294 #define FIELD_NUM_INSERTS(num_inserts, type, dxf) \
295 FIELD_G_TRACE (num_inserts, type, dxf)
296
297 #define FIELD_XDATA(name, size)
298
299 #define REACTORS(code) \
300 if (dat->version >= R_2000 && obj->tio.object->num_reactors > 0x1000) \
301 { \
302 LOG_ERROR ("Invalid num_reactors: %ld\n", \
303 (long)obj->tio.object->num_reactors); \
304 return DWG_ERR_VALUEOUTOFBOUNDS; \
305 } \
306 if (obj->tio.object->reactors) \
307 { \
308 for (vcount = 0; vcount < obj->tio.object->num_reactors; vcount++) \
309 { \
310 VALUE_HANDLE_N (obj->tio.object->reactors[vcount], reactors, \
311 vcount, code, -5); \
312 } \
313 }
314
315 #define XDICOBJHANDLE(code) \
316 SINCE (R_2004) \
317 { \
318 if (!obj->tio.object->is_xdic_missing) \
319 VALUE_HANDLE (obj->tio.object->xdicobjhandle, xdicobjhandle, code, 0); \
320 } \
321 PRIOR_VERSIONS \
322 { \
323 VALUE_HANDLE (obj->tio.object->xdicobjhandle, xdicobjhandle, code, 0); \
324 }
325
326 #define COMMON_ENTITY_HANDLE_DATA /* Empty */
327 #define SECTION_STRING_STREAM \
328 { \
329 Bit_Chain sav_dat = *dat; \
330 dat = str_dat;
331 #define START_STRING_STREAM \
332 obj->has_strings = bit_read_B (dat); \
333 if (obj->has_strings) \
334 { \
335 Bit_Chain sav_dat = *dat; \
336 obj_string_stream (dat, obj, dat);
337 #define END_STRING_STREAM \
338 *dat = sav_dat; \
339 }
340 #define START_HANDLE_STREAM \
341 *hdl_dat = *dat; \
342 if (dat->version >= R_2007) \
343 bit_set_position (hdl_dat, obj->hdlpos)
344
345 #define DWG_ENTITY(token) \
346 static int dwg_print_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
347 Bit_Chain *str_dat, \
348 const Dwg_Object *restrict obj) \
349 { \
350 return 0; \
351 } \
352 static int dwg_print_##token (Bit_Chain *restrict dat, \
353 const Dwg_Object *restrict obj) \
354 { \
355 BITCODE_BL vcount, rcount3, rcount4; \
356 Dwg_Entity_##token *ent, *_obj; \
357 Dwg_Object_Entity *_ent; \
358 Bit_Chain *hdl_dat = dat; \
359 Bit_Chain *str_dat = dat; \
360 Dwg_Data *dwg = obj->parent; \
361 int error = 0; \
362 LOG_INFO ("Entity " #token ":\n") \
363 _ent = obj->tio.entity; \
364 _obj = ent = _ent->tio.token; \
365 dwg_print_##token##_private (dat, hdl_dat, str_dat, obj); \
366 LOG_TRACE ("Entity handle: " FORMAT_H "\n", ARGS_H (obj->handle))
367
368 #define DWG_ENTITY_END \
369 return 0; \
370 }
371
372 #define DWG_OBJECT(token) \
373 static int dwg_print_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat, \
374 Bit_Chain *str_dat, \
375 const Dwg_Object *restrict obj) \
376 { \
377 return 0; \
378 } \
379 static int dwg_print_##token (Bit_Chain *restrict dat, \
380 const Dwg_Object *restrict obj) \
381 { \
382 BITCODE_BL vcount, rcount3, rcount4; \
383 Dwg_Object_##token *_obj; \
384 Bit_Chain *hdl_dat = dat; \
385 Bit_Chain *str_dat = dat; \
386 Dwg_Data *dwg = obj->parent; \
387 int error = 0; \
388 LOG_INFO ("Object " #token ":\n") \
389 dwg_print_##token##_private (dat, hdl_dat, str_dat, obj); \
390 _obj = obj->tio.object->tio.token; \
391 LOG_TRACE ("Object handle: " FORMAT_H "\n", ARGS_H (obj->handle))
392
393 #define DWG_OBJECT_END \
394 return 0; \
395 }
396
397 #include "dwg.spec"
398
399 /* Returns 0 on success
400 Dispatches on the variable types.
401 */
402 static int
403 dwg_print_variable_type (Dwg_Data *restrict dwg, Bit_Chain *restrict dat,
404 Dwg_Object *restrict obj)
405 {
406 int i;
407 int is_entity;
408 Dwg_Class *klass;
409
410 i = obj->type - 500;
411 if (i < 0 || i > (int)dwg->num_classes)
412 return DWG_ERR_INVALIDTYPE;
413
414 klass = &dwg->dwg_class[i];
415 if (!klass || !klass->dxfname)
416 return DWG_ERR_INTERNALERROR;
417 // almost always false
418 is_entity = dwg_class_is_entity (klass);
419
420 // clang-format off
421 #include "classes.inc"
422 // clang-format on
423
424 return DWG_ERR_UNHANDLEDCLASS;
425 }
426
427 /* prints to logging.h OUTPUT (ie stderr). Returns 0 on success
428 Dispatches on the fixed types.
429 */
430 int
431 dwg_print_object (Bit_Chain *restrict dat, Dwg_Object *restrict obj)
432 {
433 int error = 0;
434 unsigned int type;
435
436 if (!obj || !obj->parent)
437 return DWG_ERR_INTERNALERROR;
438 type = dat->version < R_13b1 ? (unsigned int)obj->fixedtype : obj->type;
439 // Bit_Chain * dat = (Bit_Chain *)obj->parent->bit_chain;
440 // Bit_Chain *hdl_dat = dat;
441 switch (obj->type)
442 {
443 case DWG_TYPE_TEXT:
444 return dwg_print_TEXT (dat, obj);
445 case DWG_TYPE_ATTRIB:
446 return dwg_print_ATTRIB (dat, obj);
447 case DWG_TYPE_ATTDEF:
448 return dwg_print_ATTDEF (dat, obj);
449 case DWG_TYPE_BLOCK:
450 return dwg_print_BLOCK (dat, obj);
451 case DWG_TYPE_ENDBLK:
452 return dwg_print_ENDBLK (dat, obj);
453 case DWG_TYPE_SEQEND:
454 return dwg_print_SEQEND (dat, obj);
455 case DWG_TYPE_INSERT:
456 return dwg_print_INSERT (dat, obj);
457 case DWG_TYPE_MINSERT:
458 return dwg_print_MINSERT (dat, obj);
459 case DWG_TYPE_VERTEX_2D:
460 return dwg_print_VERTEX_2D (dat, obj);
461 case DWG_TYPE_VERTEX_3D:
462 return dwg_print_VERTEX_3D (dat, obj);
463 case DWG_TYPE_VERTEX_MESH:
464 return dwg_print_VERTEX_MESH (dat, obj);
465 case DWG_TYPE_VERTEX_PFACE:
466 return dwg_print_VERTEX_PFACE (dat, obj);
467 case DWG_TYPE_VERTEX_PFACE_FACE:
468 return dwg_print_VERTEX_PFACE_FACE (dat, obj);
469 case DWG_TYPE_POLYLINE_2D:
470 return dwg_print_POLYLINE_2D (dat, obj);
471 case DWG_TYPE_POLYLINE_3D:
472 return dwg_print_POLYLINE_3D (dat, obj);
473 case DWG_TYPE_ARC:
474 return dwg_print_ARC (dat, obj);
475 case DWG_TYPE_CIRCLE:
476 return dwg_print_CIRCLE (dat, obj);
477 case DWG_TYPE_LINE:
478 return dwg_print_LINE (dat, obj);
479 case DWG_TYPE_DIMENSION_ORDINATE:
480 return dwg_print_DIMENSION_ORDINATE (dat, obj);
481 case DWG_TYPE_DIMENSION_LINEAR:
482 return dwg_print_DIMENSION_LINEAR (dat, obj);
483 case DWG_TYPE_DIMENSION_ALIGNED:
484 return dwg_print_DIMENSION_ALIGNED (dat, obj);
485 case DWG_TYPE_DIMENSION_ANG3PT:
486 return dwg_print_DIMENSION_ANG3PT (dat, obj);
487 case DWG_TYPE_DIMENSION_ANG2LN:
488 return dwg_print_DIMENSION_ANG2LN (dat, obj);
489 case DWG_TYPE_DIMENSION_RADIUS:
490 return dwg_print_DIMENSION_RADIUS (dat, obj);
491 case DWG_TYPE_DIMENSION_DIAMETER:
492 return dwg_print_DIMENSION_DIAMETER (dat, obj);
493 case DWG_TYPE_POINT:
494 return dwg_print_POINT (dat, obj);
495 case DWG_TYPE__3DFACE:
496 return dwg_print__3DFACE (dat, obj);
497 case DWG_TYPE_POLYLINE_PFACE:
498 return dwg_print_POLYLINE_PFACE (dat, obj);
499 case DWG_TYPE_POLYLINE_MESH:
500 return dwg_print_POLYLINE_MESH (dat, obj);
501 case DWG_TYPE_SOLID:
502 return dwg_print_SOLID (dat, obj);
503 case DWG_TYPE_TRACE:
504 return dwg_print_TRACE (dat, obj);
505 case DWG_TYPE_SHAPE:
506 return dwg_print_SHAPE (dat, obj);
507 case DWG_TYPE_VIEWPORT:
508 return dwg_print_VIEWPORT (dat, obj);
509 case DWG_TYPE_ELLIPSE:
510 return dwg_print_ELLIPSE (dat, obj);
511 case DWG_TYPE_SPLINE:
512 return dwg_print_SPLINE (dat, obj);
513 case DWG_TYPE_REGION:
514 return dwg_print_REGION (dat, obj);
515 case DWG_TYPE__3DSOLID:
516 return dwg_print__3DSOLID (dat, obj);
517 /* Check the type of the object? */
518 case DWG_TYPE_BODY:
519 return dwg_print_BODY (dat, obj);
520 case DWG_TYPE_RAY:
521 return dwg_print_RAY (dat, obj);
522 case DWG_TYPE_XLINE:
523 return dwg_print_XLINE (dat, obj);
524 case DWG_TYPE_DICTIONARY:
525 return dwg_print_DICTIONARY (dat, obj);
526 case DWG_TYPE_MTEXT:
527 return dwg_print_MTEXT (dat, obj);
528 case DWG_TYPE_LEADER:
529 return dwg_print_LEADER (dat, obj);
530 case DWG_TYPE_TOLERANCE:
531 return dwg_print_TOLERANCE (dat, obj);
532 case DWG_TYPE_MLINE:
533 return dwg_print_MLINE (dat, obj);
534 case DWG_TYPE_BLOCK_CONTROL:
535 return dwg_print_BLOCK_CONTROL (dat, obj);
536 case DWG_TYPE_BLOCK_HEADER:
537 return dwg_print_BLOCK_HEADER (dat, obj);
538 case DWG_TYPE_LAYER_CONTROL:
539 return dwg_print_LAYER_CONTROL (dat, obj);
540 case DWG_TYPE_LAYER:
541 return dwg_print_LAYER (dat, obj);
542 case DWG_TYPE_STYLE_CONTROL:
543 return dwg_print_STYLE_CONTROL (dat, obj);
544 case DWG_TYPE_STYLE:
545 return dwg_print_STYLE (dat, obj);
546 case DWG_TYPE_LTYPE_CONTROL:
547 return dwg_print_LTYPE_CONTROL (dat, obj);
548 case DWG_TYPE_LTYPE:
549 return dwg_print_LTYPE (dat, obj);
550 case DWG_TYPE_VIEW_CONTROL:
551 return dwg_print_VIEW_CONTROL (dat, obj);
552 case DWG_TYPE_VIEW:
553 return dwg_print_VIEW (dat, obj);
554 case DWG_TYPE_UCS_CONTROL:
555 return dwg_print_UCS_CONTROL (dat, obj);
556 case DWG_TYPE_UCS:
557 return dwg_print_UCS (dat, obj);
558 case DWG_TYPE_VPORT_CONTROL:
559 return dwg_print_VPORT_CONTROL (dat, obj);
560 case DWG_TYPE_VPORT:
561 return dwg_print_VPORT (dat, obj);
562 case DWG_TYPE_APPID_CONTROL:
563 return dwg_print_APPID_CONTROL (dat, obj);
564 case DWG_TYPE_APPID:
565 return dwg_print_APPID (dat, obj);
566 case DWG_TYPE_DIMSTYLE_CONTROL:
567 return dwg_print_DIMSTYLE_CONTROL (dat, obj);
568 case DWG_TYPE_DIMSTYLE:
569 return dwg_print_DIMSTYLE (dat, obj);
570 case DWG_TYPE_VX_CONTROL:
571 return dwg_print_VX_CONTROL (dat, obj);
572 case DWG_TYPE_VX_TABLE_RECORD:
573 return dwg_print_VX_TABLE_RECORD (dat, obj);
574 case DWG_TYPE_GROUP:
575 return dwg_print_GROUP (dat, obj);
576 case DWG_TYPE_MLINESTYLE:
577 return dwg_print_MLINESTYLE (dat, obj);
578 case DWG_TYPE_OLE2FRAME:
579 return dwg_print_OLE2FRAME (dat, obj);
580 case DWG_TYPE_DUMMY:
581 return dwg_print_DUMMY (dat, obj);
582 case DWG_TYPE_LONG_TRANSACTION:
583 return dwg_print_LONG_TRANSACTION (dat, obj);
584 case DWG_TYPE_LWPOLYLINE:
585 return dwg_print_LWPOLYLINE (dat, obj);
586 case DWG_TYPE_HATCH:
587 return dwg_print_HATCH (dat, obj);
588 case DWG_TYPE_XRECORD:
589 return dwg_print_XRECORD (dat, obj);
590 case DWG_TYPE_PLACEHOLDER:
591 return dwg_print_PLACEHOLDER (dat, obj);
592 case DWG_TYPE_OLEFRAME:
593 return dwg_print_OLEFRAME (dat, obj);
594 case DWG_TYPE_VBA_PROJECT:
595 LOG_ERROR ("Unhandled Object VBA_PROJECT. Has its own section\n");
596 // dwg_print_VBA_PROJECT(dat, obj);
597 break;
598 case DWG_TYPE_LAYOUT:
599 return dwg_print_LAYOUT (dat, obj);
600 case DWG_TYPE_PROXY_ENTITY:
601 return dwg_print_PROXY_ENTITY (dat, obj);
602 case DWG_TYPE_PROXY_OBJECT: // DXF name: PROXY
603 return dwg_print_PROXY_OBJECT (dat, obj);
604 case DWG_TYPE_REPEAT:
605 return dwg_print_REPEAT (dat, obj);
606 case DWG_TYPE_ENDREP:
607 return dwg_print_ENDREP (dat, obj);
608 case DWG_TYPE__3DLINE:
609 return dwg_print__3DLINE (dat, obj);
610 case DWG_TYPE_LOAD:
611 return dwg_print_LOAD (dat, obj);
612 case DWG_TYPE_JUMP:
613 return dwg_print_JUMP (dat, obj);
614 default:
615 if (obj->type == obj->parent->layout_type)
616 {
617 return dwg_print_LAYOUT (dat, obj);
618 }
619 /* > 500 */
620 else if ((error = dwg_print_variable_type (obj->parent, dat, obj))
621 & DWG_ERR_UNHANDLEDCLASS)
622 {
623 Dwg_Data *dwg = obj->parent;
624 int is_entity = 0;
625 int i = obj->type - 500;
626 Dwg_Class *klass = NULL;
627
628 if (i > 0 && i < (int)dwg->num_classes)
629 {
630 klass = &dwg->dwg_class[i];
631 is_entity = klass ? dwg_class_is_entity (klass) : 0;
632 }
633 // properly dwg_decode_object/_entity for eed, reactors, xdic
634 if (klass && !is_entity)
635 {
636 return dwg_print_UNKNOWN_OBJ (dat, obj);
637 }
638 else if (klass)
639 {
640 return dwg_print_UNKNOWN_ENT (dat, obj);
641 }
642 else // not a class
643 {
644 LOG_WARN ("Unknown object, skipping eed/reactors/xdic");
645 SINCE (R_2000)
646 {
647 LOG_INFO ("Object bitsize: %u\n", obj->bitsize);
648 }
649 LOG_INFO ("Object handle: " FORMAT_H "\n", ARGS_H (obj->handle));
650 return error | DWG_ERR_INVALIDTYPE;
651 }
652 }
653 }
654 return DWG_ERR_UNHANDLEDCLASS;
655 }
656
657 #undef IS_PRINT