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