Coverage Report

Created: 2025-02-15 06:35

/src/libredwg/src/out_dxfb.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
/*  LibreDWG - free implementation of the DWG file format                    */
3
/*                                                                           */
4
/*  Copyright (C) 2018-2021 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
 * out_dxfb.c: write as Binary DXF
15
 * Does not work yet.
16
 * written 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
#define IS_DXF
26
#include "common.h"
27
#include "bits.h"
28
#include "dwg.h"
29
#include "decode.h"
30
#include "decode_r11.h"
31
#include "out_dxf.h"
32
33
static unsigned int loglevel;
34
0
#define DWG_LOGLEVEL loglevel
35
#include "logging.h"
36
37
/* the current version per spec block. */
38
static unsigned int cur_ver = 0;
39
static char buf[4096];
40
static BITCODE_BL rcount1, rcount2;
41
42
// imported
43
char *dwg_obj_table_get_name (const Dwg_Object *restrict obj,
44
                              int *restrict error);
45
#ifndef _DWG_API_H_
46
Dwg_Object *dwg_obj_generic_to_object (const void *restrict obj,
47
                                       int *restrict error);
48
#endif
49
50
// private
51
static int dxfb_common_entity_handle_data (Bit_Chain *restrict dat,
52
                                           const Dwg_Object *restrict obj);
53
static int dwg_dxfb_object (Bit_Chain *restrict dat,
54
                            const Dwg_Object *restrict obj, int *restrict);
55
static int dxfb_3dsolid (Bit_Chain *restrict dat,
56
                         const Dwg_Object *restrict obj,
57
                         Dwg_Entity_3DSOLID *restrict _obj);
58
/*static void dxfb_cvt_tablerecord (Bit_Chain *restrict dat,
59
                                  const Dwg_Object *restrict obj,
60
                                  char *restrict name, const int dxf); */
61
62
/*--------------------------------------------------------------------------------
63
 * MACROS
64
 */
65
66
#define ACTION dxfb
67
68
#define FMT_H "%" PRIX64
69
#define FIELD(nam, type)
70
#define FIELDG(nam, type, dxf)                                                \
71
0
  if (dxf)                                                                    \
72
0
    {                                                                         \
73
0
      FIELD_##type (nam, dxf);                                                \
74
0
    }
75
0
#define SUB_FIELD(o, nam, type, dxf) FIELDG (o.nam, type, dxf)
76
77
#define HEADER_VALUE(nam, type, dxf, value)                                   \
78
0
  if (dxf)                                                                    \
79
0
    {                                                                         \
80
0
      GROUP (9);                                                              \
81
0
      fprintf (dat->fh, "$%s%c", #nam, 0);                                    \
82
0
      VALUE_##type (value, dxf);                                              \
83
0
    }
84
85
#define HEADER_VAR(nam, type, dxf)                                            \
86
  HEADER_VALUE (nam, type, dxf, dwg->header_vars.nam)
87
0
#define HEADER_VALUE_TV(nam, dxf, value) HEADER_VALUE (nam, TV, dxf, value)
88
#define HEADER_VALUE_TU(nam, dxf, value) HEADER_VALUE (nam, TU, dxf, value)
89
#define HEADER_VALUE_TU0(nam, dxf, value)                                     \
90
  if (dxf && value && !bit_empty_T (dat, (BITCODE_T)value))                   \
91
    {                                                                         \
92
      HEADER_VALUE (nam, TU, dxf, value);                                     \
93
    }
94
95
0
#define FIELD_CAST(nam, type, cast, dxf) FIELDG (nam, cast, dxf)
96
#define SUB_FIELD_CAST(o, nam, type, cast, dxf) FIELDG (o.nam, cast, dxf)
97
#define FIELD_TRACE(nam, type)
98
#define VALUE_TV(value, dxf)                                                  \
99
0
  {                                                                           \
100
0
    GROUP (dxf);                                                              \
101
0
    fprintf (dat->fh, "%s%c", value, 0);                                      \
102
0
  }
103
#define VALUE_TV0(value, dxf)                                                 \
104
0
  if (dxf && value && *value)                                                 \
105
0
    {                                                                         \
106
0
      GROUP (dxf);                                                            \
107
0
      fprintf (dat->fh, "%s%c", value, 0);                                    \
108
0
    }
109
#define VALUE_TU(wstr, dxf)                                                   \
110
0
  {                                                                           \
111
0
    if (dxf)                                                                  \
112
0
      {                                                                       \
113
0
        char *_u8 = bit_convert_TU ((BITCODE_TU)wstr);                        \
114
0
        GROUP (dxf);                                                          \
115
0
        if (_u8)                                                              \
116
0
          fprintf (dat->fh, "%s%c", _u8, 0);                                  \
117
0
        else                                                                  \
118
0
          fprintf (dat->fh, "%c", 0);                                         \
119
0
        free (_u8);                                                           \
120
0
      }                                                                       \
121
0
  }
122
0
#define VALUE_TFF(str, dxf) VALUE_TV (str, dxf)
123
#define VALUE_BINARY(value, size, dxf)                                        \
124
0
  {                                                                           \
125
0
    long _len = (long)(size);                                                 \
126
0
    do                                                                        \
127
0
      {                                                                       \
128
0
        short j;                                                              \
129
0
        long _l = _len > 127 ? 127 : _len;                                    \
130
0
        GROUP (dxf);                                                          \
131
0
        if (value)                                                            \
132
0
          for (j = 0; j < _l; j++)                                            \
133
0
            {                                                                 \
134
0
              fprintf (dat->fh, "%c", value[j]);                              \
135
0
            }                                                                 \
136
0
        fprintf (dat->fh, "%c", '\0');                                        \
137
0
        _len -= 127;                                                          \
138
0
      }                                                                       \
139
0
    while (_len > 127);                                                       \
140
0
  }
141
0
#define FIELD_BINARY(name, size, dxf) VALUE_BINARY (_obj->name, size, dxf)
142
143
#define FIELD_VALUE(nam) _obj->nam
144
#define ANYCODE -1
145
// a null-terminated string of the value as %X
146
#define VALUE_HANDLE(ref, nam, handle_code, dxf)                              \
147
0
  if (dxf)                                                                    \
148
0
    {                                                                         \
149
0
      char _s[18];                                                            \
150
0
      snprintf (_s, sizeof (_s), FMT_H, ref ? ref->absolute_ref : 0UL);       \
151
0
      _s[sizeof (_s) - 1] = '\0';                                             \
152
0
      VALUE_TV (_s, dxf);                                                     \
153
0
    }
154
// TODO: try to resolve the handle. rather write 0 than in invalid handle:
155
// if (_obj->nam->obj) ...
156
#define FIELD_HANDLE(nam, handle_code, dxf)                                   \
157
0
  VALUE_HANDLE (_obj->nam, nam, handle_code, dxf)
158
#define FIELD_HANDLE0(nam, handle_code, dxf)                                  \
159
0
  if (dxf && _obj->nam && _obj->nam->absolute_ref)                            \
160
0
    {                                                                         \
161
0
      FIELD_HANDLE (nam, handle_code, dxf);                                   \
162
0
    }
163
#define SUB_FIELD_HANDLE(o, nam, handle_code, dxf)                            \
164
0
  VALUE_HANDLE (_obj->o.nam, nam, handle_code, dxf)
165
#define SUB_FIELD_HANDLE0(o, nam, handle_code, dxf)                           \
166
  if (dxf && _obj->o.nam && _obj->o.nam->absolute_ref)                        \
167
    {                                                                         \
168
      VALUE_HANDLE (_obj->o.nam, nam, handle_code, dxf)                       \
169
    }
170
171
#define GROUP(code)                                                           \
172
0
  if (dat->version < R_14)                                                    \
173
0
    {                                                                         \
174
0
      if (code >= 1000)                                                       \
175
0
        {                                                                     \
176
0
          uint16_t icode = (uint16_t)(code);                                  \
177
0
          fputc (0xff, dat->fh);                                              \
178
0
          fwrite (&icode, 2, 1, dat->fh);                                     \
179
0
        }                                                                     \
180
0
      else                                                                    \
181
0
        {                                                                     \
182
0
          uint8_t icode = (uint8_t)((code) & 0xff);                           \
183
0
          fwrite (&icode, 1, 1, dat->fh);                                     \
184
0
        }                                                                     \
185
0
    }                                                                         \
186
0
  else                                                                        \
187
0
    {                                                                         \
188
0
      uint16_t icode = (uint16_t)(code);                                      \
189
0
      fwrite (&icode, 2, 1, dat->fh);                                         \
190
0
    }
191
#define FIELD_TV(nam, dxf)                                                    \
192
0
  if (_obj->nam != NULL && dxf != 0)                                          \
193
0
    {                                                                         \
194
0
      VALUE_TV (_obj->nam, dxf)                                               \
195
0
    }
196
#define FIELD_TU(nam, dxf)                                                    \
197
0
  if (_obj->nam != NULL && dxf != 0)                                          \
198
0
    {                                                                         \
199
0
      VALUE_TU (_obj->nam, dxf)                                               \
200
0
    }
201
#define VALUE_T(value, dxf)                                                   \
202
0
  {                                                                           \
203
0
    if (IS_FROM_TU (dat))                                                     \
204
0
      {                                                                       \
205
0
        VALUE_TU (value, dxf)                                                 \
206
0
      }                                                                       \
207
0
    else                                                                      \
208
0
      {                                                                       \
209
0
        VALUE_TV ((char *)value, dxf)                                         \
210
0
      }                                                                       \
211
0
  }
212
#define VALUE_T0(value, dxf)                                                  \
213
0
  if (!bit_empty_T (dat, value))                                              \
214
0
  VALUE_T (value, dxf)
215
#define FIELD_T(nam, dxf)                                                     \
216
0
  {                                                                           \
217
0
    if (IS_FROM_TU (dat))                                                     \
218
0
      {                                                                       \
219
0
        FIELD_TU (nam, dxf)                                                   \
220
0
      }                                                                       \
221
0
    else                                                                      \
222
0
      {                                                                       \
223
0
        FIELD_TV (nam, dxf)                                                   \
224
0
      }                                                                       \
225
0
  }
226
0
#define FIELD_TF(nam, len, dxf) VALUE_TV (_obj->nam, dxf)
227
0
#define FIELD_TFF(nam, len, dxf) VALUE_TV (_obj->nam, dxf)
228
229
// skip if 0
230
0
#define FIELD_RD0(nam, dxf) FIELD_BD0 (nam, dxf)
231
#define FIELD_BD0(nam, dxf)                                                   \
232
0
  {                                                                           \
233
0
    if (_obj->nam != 0.0)                                                     \
234
0
      FIELD_BD (nam, dxf)                                                     \
235
0
  }
236
// for scale (1.0, 1.0, 1.0) and width_factor
237
0
#define FIELD_RD1(nam, dxf) FIELD_BD1 (nam, dxf)
238
#define FIELD_BD1(nam, dxf)                                                   \
239
0
  {                                                                           \
240
0
    if (_obj->nam != 1.0)                                                     \
241
0
      FIELD_BD (nam, dxf)                                                     \
242
0
  }
243
#define FIELD_BL0(nam, dxf)                                                   \
244
0
  {                                                                           \
245
0
    if (_obj->nam != 0)                                                       \
246
0
      FIELD_BL (nam, dxf)                                                     \
247
0
  }
248
#define SUB_FIELD_BL0(o, nam, dxf)                                            \
249
  {                                                                           \
250
    if (_obj->o.nam != 0)                                                     \
251
      SUB_FIELD_BL (o, nam, dxf)                                              \
252
  }
253
#define FIELD_BS0(nam, dxf)                                                   \
254
0
  {                                                                           \
255
0
    if (_obj->nam != 0)                                                       \
256
0
      FIELD_BS (nam, dxf)                                                     \
257
0
  }
258
#define FIELD_BS1(nam, dxf)                                                   \
259
0
  {                                                                           \
260
0
    if (_obj->nam != 1)                                                       \
261
0
      FIELD_BS (nam, dxf)                                                     \
262
0
  }
263
#define FIELD_B0(nam, dxf)                                                    \
264
0
  {                                                                           \
265
0
    if (_obj->nam)                                                            \
266
0
      FIELD_B (nam, dxf)                                                      \
267
0
  }
268
#define FIELD_B1(nam, dxf)                                                    \
269
0
  {                                                                           \
270
0
    if (! _obj->nam)                                                          \
271
0
      FIELD_B (nam, dxf)                                                      \
272
0
  }
273
#define FIELD_RC0(nam, dxf)                                                   \
274
0
  {                                                                           \
275
0
    if (_obj->nam != 0)                                                       \
276
0
      FIELD_RC (nam, dxf)                                                     \
277
0
  }
278
#define FIELD_RS0(nam, dxf)                                                   \
279
0
  {                                                                           \
280
0
    if (_obj->nam != 0)                                                       \
281
0
      FIELD_RS (nam, dxf)                                                     \
282
0
  }
283
#define FIELD_RL0(nam, dxf)                                                   \
284
  {                                                                           \
285
    if (_obj->nam != 0)                                                       \
286
      FIELD_RL (nam, dxf)                                                     \
287
  }
288
#define FIELD_BT0(nam, dxf)                                                   \
289
0
  {                                                                           \
290
0
    if (_obj->nam != 0)                                                       \
291
0
      FIELD_BT (nam, dxf)                                                     \
292
0
  }
293
#define FIELD_T0(nam, dxf)                                                    \
294
0
  if (!bit_empty_T (dat, _obj->nam))                                          \
295
0
    {                                                                         \
296
0
      FIELD_T (nam, dxf)                                                      \
297
0
    }
298
#define FIELD_TV0(nam, dxf) VALUE_TV0 (_obj->nam, dxf)
299
300
#define HEADER_TV(nam, dxf)                                                   \
301
0
  {                                                                           \
302
0
    HEADER_9 (nam);                                                           \
303
0
    VALUE_TV (dwg->header_vars.nam, dxf);                                     \
304
0
  }
305
#define HEADER_TU(nam, dxf)                                                   \
306
  {                                                                           \
307
    HEADER_9 (nam);                                                           \
308
    VALUE_TU (dwg->header_vars.nam, dxf);                                     \
309
  }
310
#define HEADER_T(nam, dxf)                                                    \
311
0
  {                                                                           \
312
0
    HEADER_9 (nam);                                                           \
313
0
    VALUE_T (dwg->header_vars.nam, dxf);                                      \
314
0
  }
315
#define HEADER_T0(nam, dxf)                                                   \
316
0
  if (dxf && !bit_empty_T (dat, _obj->nam))                                   \
317
0
    {                                                                         \
318
0
      HEADER_9 (nam);                                                         \
319
0
      VALUE_T (_obj->nam, dxf);                                               \
320
0
    }
321
#define HEADER_VALUE_T(nam, dxf, value)                                       \
322
0
  if (dxf)                                                                    \
323
0
    {                                                                         \
324
0
      HEADER_9 (nam);                                                         \
325
0
      if (IS_FROM_TU (dat))                                                   \
326
0
        VALUE_T (value, dxf)                                                  \
327
0
      else                                                                    \
328
0
        VALUE_TV ((char *)value, dxf)                                         \
329
0
    }
330
#define HEADER_VALUE_T0(nam, dxf, value)                                      \
331
0
  if (dxf && !bit_empty_T (dat, value))                                       \
332
0
    {                                                                         \
333
0
      HEADER_9 (nam);                                                         \
334
0
      if (IS_FROM_TU (dat))                                                   \
335
0
        VALUE_T (value, dxf)                                                  \
336
0
      else                                                                    \
337
0
        VALUE_TV ((char *)value, dxf)                                         \
338
0
    }
339
#define POINT_3D(nam, var, c1, c2, c3)                                        \
340
0
  {                                                                           \
341
0
    VALUE_RD (dwg->var.x, c1);                                                \
342
0
    VALUE_RD (dwg->var.y, c2);                                                \
343
0
    VALUE_RD (dwg->var.z, c3);                                                \
344
0
  }
345
#define POINT_2D(nam, var, c1, c2)                                            \
346
0
  {                                                                           \
347
0
    VALUE_RD (dwg->var.x, c1);                                                \
348
0
    VALUE_RD (dwg->var.x, c2);                                                \
349
0
  }
350
#define HEADER_3D(nam)                                                        \
351
0
  {                                                                           \
352
0
    HEADER_9 (nam);                                                           \
353
0
    POINT_3D (nam, header_vars.nam, 10, 20, 30);                              \
354
0
  }
355
#define HEADER_2D(nam)                                                        \
356
0
  {                                                                           \
357
0
    HEADER_9 (nam);                                                           \
358
0
    POINT_2D (nam, header_vars.nam, 10, 20);                                  \
359
0
  }
360
#define SECTION(token)                                                        \
361
0
  VALUE_TV ("SECTION", 0);                                                    \
362
0
  VALUE_TV (#token, 2)
363
0
#define ENDSEC() VALUE_TV ("ENDSEC", 0)
364
#define TABLE(token)                                                          \
365
0
  VALUE_TV ("TABLE", 0);                                                      \
366
0
  VALUE_TV (#token, 2)
367
0
#define ENDTAB() VALUE_TV ("ENDTAB", 0)
368
0
#define RECORD(token) VALUE_TV (#token, 0)
369
#define SUBCLASS(text)                                                        \
370
0
  if (dat->version >= R_13b1)                                                 \
371
0
    {                                                                         \
372
0
      VALUE_TV (#text, 100)                                                   \
373
0
    }
374
375
/*
376
#define VALUE(code, value) \
377
  { \
378
    GCC30_DIAG_IGNORE (-Wformat-nonliteral) \
379
    snprintf (buf, 4096, "%3i\n%s\n", code, dxfb_format (code)); \
380
    fprintf(dat->fh, buf, value); \
381
    GCC_DIAG_RESTORE \
382
  }
383
 */
384
385
#define FIELD_HANDLE_N(nam, vcount, handle_code, dxf)                         \
386
0
  FIELD_HANDLE (nam, handle_code, dxf)
387
388
0
#define FIELD_B(nam, dxf) FIELD_RC (nam, dxf)
389
0
#define FIELD_BB(nam, dxf) FIELD_RC (nam, dxf)
390
#define FIELD_3B(nam, dxf) FIELD_RC (nam, dxf)
391
0
#define FIELD_BS(nam, dxf) FIELD_RS (nam, dxf)
392
0
#define FIELD_BL(nam, dxf) FIELD_RL (nam, dxf)
393
0
#define HEADER_BLL(nam, dxf) HEADER_RLL (nam, dxf)
394
0
#define FIELD_BD(nam, dxf) FIELD_RD (nam, dxf)
395
396
#define HEADER_9(nam)                                                         \
397
0
  {                                                                           \
398
0
    GROUP (9);                                                                \
399
0
    fprintf (dat->fh, "$%s%c", #nam, 0);                                      \
400
0
  }
401
0
#define VALUE(value, type, dxf) VALUE_##type (value, dxf)
402
0
#define VALUE_B(value, dxf) VALUE_INT (value, dxf)
403
#define VALUE_BB(value, dxf) VALUE_INT (value, dxf)
404
#define VALUE_3B(value, dxf) VALUE_INT (value, dxf)
405
#define VALUE_RCs(value, dxf) VALUE_INT (value, dxf)
406
0
#define VALUE_BS(value, dxf) VALUE_INT (value, dxf)
407
0
#define VALUE_BL(value, dxf) VALUE_INT (value, dxf)
408
0
#define VALUE_BD(value, dxf) VALUE_RD (value, dxf)
409
#define VALUE_RC(value, dxf)                                                  \
410
0
  {                                                                           \
411
0
    BITCODE_RC _c = (BITCODE_RC)(value);                                      \
412
0
    GROUP (dxf);                                                              \
413
0
    fwrite (&_c, 1, 1, dat->fh);                                              \
414
0
  }
415
#define VALUE_RS(value, dxf)                                                  \
416
0
  {                                                                           \
417
0
    BITCODE_RS _s = (BITCODE_RS)(value);                                      \
418
0
    GROUP (dxf);                                                              \
419
0
    fwrite (&_s, 2, 1, dat->fh);                                              \
420
0
  }
421
#define VALUE_RSd(value, dxf)                                                 \
422
0
  {                                                                           \
423
0
    BITCODE_RSd _s = (BITCODE_RSd)(value);                                    \
424
0
    GROUP (dxf);                                                              \
425
0
    fwrite (&_s, 2, 1, dat->fh);                                              \
426
0
  }
427
#define VALUE_RL(value, dxf)                                                  \
428
0
  {                                                                           \
429
0
    BITCODE_RL _s = (BITCODE_RL)value;                                        \
430
0
    GROUP (dxf);                                                              \
431
0
    fwrite (&_s, 4, 1, dat->fh);                                              \
432
0
  }
433
#define VALUE_RLL(value, dxf)                                                 \
434
0
  {                                                                           \
435
0
    BITCODE_RLL _s = (BITCODE_RLL)value;                                      \
436
0
    GROUP (dxf);                                                              \
437
0
    fwrite (&_s, 8, 1, dat->fh);                                              \
438
0
  }
439
// most DXFB FIELD_RC are written as int16 actually
440
// we need to check dwg_resbuf_value_type()
441
0
#define FIELD_RC(nam, dxf) VALUE_INT (_obj->nam, dxf)
442
#define VALUE_INT(value, dxf)                                                 \
443
0
  {                                                                           \
444
0
    if (dxf == 0)                                                             \
445
0
      VALUE_RS (value, dxf)                                                   \
446
0
    else                                                                      \
447
0
      switch (dwg_resbuf_value_type (dxf))                                    \
448
0
        {                                                                     \
449
0
        case DWG_VT_BOOL:                                                     \
450
0
        case DWG_VT_INT8:                                                     \
451
0
          VALUE_RC (value, dxf);                                              \
452
0
          break;                                                              \
453
0
        case DWG_VT_INT16:                                                    \
454
0
          VALUE_RS (value, dxf);                                              \
455
0
          break;                                                              \
456
0
        case DWG_VT_INT32:                                                    \
457
0
          VALUE_RL (value, dxf);                                              \
458
0
          break;                                                              \
459
0
        case DWG_VT_INT64:                                                    \
460
0
          VALUE_RLL (value, dxf);                                             \
461
0
          break;                                                              \
462
0
        case DWG_VT_STRING:                                                   \
463
0
        case DWG_VT_POINT3D:                                                  \
464
0
        case DWG_VT_REAL:                                                     \
465
0
        case DWG_VT_BINARY:                                                   \
466
0
        case DWG_VT_HANDLE:                                                   \
467
0
        case DWG_VT_OBJECTID:                                                 \
468
0
        case DWG_VT_INVALID:                                                  \
469
0
        default:                                                              \
470
0
          LOG_ERROR ("Unhandled VALUE_INT code %d", dxf);                     \
471
0
        }                                                                     \
472
0
  }
473
474
#define VALUE_3BD(value, dxf)                                                 \
475
0
  {                                                                           \
476
0
    VALUE_RD (value.x, dxf);                                                  \
477
0
    VALUE_RD (value.y, dxf + 10);                                             \
478
0
    VALUE_RD (value.z, dxf + 20);                                             \
479
0
  }
480
#define HEADER_RC(nam, dxf)                                                   \
481
0
  {                                                                           \
482
0
    HEADER_9 (nam);                                                           \
483
0
    VALUE_INT (dwg->header_vars.nam, dxf);                                    \
484
0
  }
485
#define HEADER_RC0(nam, dxf)                                                  \
486
  if (dwg->header_vars.nam)                                                   \
487
    {                                                                         \
488
      HEADER_9 (nam);                                                         \
489
      VALUE_INT (dwg->header_vars.nam, dxf);                                  \
490
    }
491
#define HEADER_RS0(nam, dxf)                                                  \
492
0
  if (dwg->header_vars.nam)                                                   \
493
0
    {                                                                         \
494
0
      HEADER_9 (nam);                                                         \
495
0
      VALUE_RS (dwg->header_vars.nam, dxf);                                   \
496
0
    }
497
#define HEADER_B(nam, dxf) HEADER_RC (nam, dxf)
498
0
#define FIELD_RS(nam, dxf) VALUE_INT (_obj->nam, dxf)
499
#define HEADER_RS(nam, dxf)                                                   \
500
0
  {                                                                           \
501
0
    HEADER_9 (nam);                                                           \
502
0
    VALUE_RS (dwg->header_vars.nam, dxf);                                     \
503
0
  }
504
#define HEADER_RSd(nam, dxf)                                                  \
505
0
  {                                                                           \
506
0
    HEADER_9 (nam);                                                           \
507
0
    VALUE_RSd (dwg->header_vars.nam, dxf);                                    \
508
0
  }
509
#define VALUE_RD(value, dxf)                                                  \
510
0
  {                                                                           \
511
0
    double d = (value);                                                       \
512
0
    GROUP (dxf);                                                              \
513
0
    fwrite (&d, 8, 1, dat->fh);                                               \
514
0
  }
515
0
#define FIELD_RD(nam, dxf) VALUE_RD (_obj->nam, dxf)
516
#define HEADER_RD(nam, dxf)                                                   \
517
0
  {                                                                           \
518
0
    HEADER_9 (nam);                                                           \
519
0
    VALUE_RD (dwg->header_vars.nam, dxf);                                     \
520
0
  }
521
522
0
#define FIELD_RL(nam, dxf) VALUE_INT (_obj->nam, dxf)
523
#define HEADER_RL(nam, dxf)                                                   \
524
0
  {                                                                           \
525
0
    HEADER_9 (nam);                                                           \
526
0
    VALUE_RL (dwg->header_vars.nam, dxf);                                     \
527
0
  }
528
529
0
#define HEADER_B(nam, dxf) HEADER_RC (nam, dxf)
530
0
#define HEADER_BS(nam, dxf) HEADER_RS (nam, dxf)
531
0
#define HEADER_BSd(nam, dxf) HEADER_RS (nam, dxf)
532
0
#define HEADER_BD(nam, dxf) HEADER_RD (nam, dxf)
533
#define HEADER_BL(nam, dxf) HEADER_RL (nam, dxf)
534
0
#define HEADER_BLd(nam, dxf) HEADER_RL (nam, dxf)
535
536
#define FIELD_DATAHANDLE(nam, code, dxf)                                      \
537
0
  {                                                                           \
538
0
    Dwg_Object_Ref *ref = _obj->nam;                                          \
539
0
    HEADER_9 (nam);                                                           \
540
0
    VALUE_H (ref ? ref->handleref.value : 0UL, dxf);                          \
541
0
  }
542
// I would rather assume 8-byte LE
543
#define VALUE_H(value, dxf)                                                   \
544
0
  if (dxf)                                                                    \
545
0
    {                                                                         \
546
0
      char _s[18];                                                            \
547
0
      snprintf (_s, sizeof (_s), FMT_H, (BITCODE_RLL)(value));                \
548
0
      _s[sizeof (_s) - 1] = '\0';                                             \
549
0
      VALUE_TV (_s, dxf);                                                     \
550
0
    }
551
#define HEADER_H(nam, dxf)                                                    \
552
  if (dxf)                                                                    \
553
    {                                                                         \
554
      HEADER_9 (nam);                                                         \
555
      VALUE_HANDLE (dwg->header_vars.nam, nam, 0, dxf);                       \
556
    }
557
#define HEADER_H0(nam, dxf)                                                   \
558
0
  if (dxf && dwg->header_vars.nam && dwg->header_vars.nam->absolute_ref)      \
559
0
    {                                                                         \
560
0
      HEADER_9 (nam);                                                         \
561
0
      VALUE_H (dwg->header_vars.nam->absolute_ref, dxf);                      \
562
0
    }
563
564
#define HANDLE_NAME(nam, code, table)                                         \
565
  VALUE_HANDLE_NAME (dwg->header_vars.nam, dxf, table)
566
// TODO: convert STANDARD to Standard?
567
#define VALUE_HANDLE_NAME(value, dxf, table)                                  \
568
0
  {                                                                           \
569
0
    Dwg_Object_Ref *ref = value;                                              \
570
0
    if (ref && obj && obj->parent                                             \
571
0
        && (!ref->obj || ref->obj->supertype != DWG_SUPERTYPE_OBJECT          \
572
0
            || ref->obj->fixedtype != DWG_TYPE_##table))                      \
573
0
      ref->obj = dwg_resolve_handle (obj->parent, ref->absolute_ref);         \
574
0
    if (ref && ref->obj && ref->obj->supertype == DWG_SUPERTYPE_OBJECT        \
575
0
        && ref->obj->fixedtype == DWG_TYPE_##table)                           \
576
0
      {                                                                       \
577
0
        VALUE_TV (ref->obj->tio.object->tio.table->name, dxf)                 \
578
0
      }                                                                       \
579
0
    else                                                                      \
580
0
      VALUE_TV ("", dxf)                                                      \
581
0
  }
582
#define FIELD_HANDLE_NAME(nam, dxf, table)                                    \
583
0
  VALUE_HANDLE_NAME (_obj->nam, dxf, table)
584
#define SUB_FIELD_HANDLE_NAME(ob, nam, dxf, table)                            \
585
  VALUE_HANDLE_NAME (_obj->ob.nam, dxf, table)
586
#define HEADER_HANDLE_NAME(nam, dxf, table)                                   \
587
0
  HEADER_9 (nam);                                                             \
588
0
  VALUE_HANDLE_NAME (dwg->header_vars.nam, dxf, table)
589
590
#define FIELD_BLL(nam, dxf)                                                   \
591
0
  {                                                                           \
592
0
    BITCODE_BLL s = _obj->nam;                                                \
593
0
    GROUP (dxf);                                                              \
594
0
    fwrite (&s, 8, 1, dat->fh);                                               \
595
0
  }
596
0
#define FIELD_RLL(nam, dxf) FIELD_BLL (nam, dxf)
597
#define HEADER_RLL(nam, dxf)                                                  \
598
0
  {                                                                           \
599
0
    GROUP (9);                                                                \
600
0
    fprintf (dat->fh, "$%s%c", #nam, 0);                                      \
601
0
    FIELD_BLL (nam, dxf);                                                     \
602
0
  }
603
604
#define FIELD_MC(nam, dxf) FIELD_RC (nam, dxf)
605
#define FIELD_MS(nam, dxf) FIELD_RS (nam, dxf)
606
0
#define FIELD_BT(nam, dxf) FIELD_BD (nam, dxf);
607
0
#define FIELD_4BITS(nam, dxf) FIELD_RC (nam, dxf)
608
#define FIELD_BE(nam, dxf)                                                    \
609
0
  {                                                                           \
610
0
    if (dxf                                                                   \
611
0
        && !(_obj->nam.x == 0.0 && _obj->nam.y == 0.0 && _obj->nam.z == 1.0)) \
612
0
      FIELD_3RD (nam, dxf)                                                    \
613
0
  }
614
0
#define FIELD_DD(nam, _default, dxf) FIELD_RD (nam, dxf)
615
#define FIELD_2DD(nam, def, dxf)                                              \
616
0
  if (dxf)                                                                    \
617
0
    {                                                                         \
618
0
      FIELD_DD (nam.x, FIELD_VALUE (def.x), dxf);                             \
619
0
      FIELD_DD (nam.y, FIELD_VALUE (def.y), dxf + 10);                        \
620
0
    }
621
#define FIELD_3DD(nam, def, dxf)                                              \
622
0
  if (dxf)                                                                    \
623
0
    {                                                                         \
624
0
      FIELD_DD (nam.x, FIELD_VALUE (def.x), dxf);                             \
625
0
      FIELD_DD (nam.y, FIELD_VALUE (def.y), dxf + 10);                        \
626
0
      FIELD_DD (nam.z, FIELD_VALUE (def.z), dxf + 20);                        \
627
0
    }
628
#define FIELD_2RD(nam, dxf)                                                   \
629
0
  if (dxf)                                                                    \
630
0
    {                                                                         \
631
0
      FIELD_RD (nam.x, dxf);                                                  \
632
0
      FIELD_RD (nam.y, dxf + 10);                                             \
633
0
    }
634
#define FIELD_2RD0(nam, dxf)                                                  \
635
0
  if (dxf && _obj->nam.x != 0.0 && _obj->nam.y != 0.0)                        \
636
0
    {                                                                         \
637
0
      FIELD_RD (nam.x, dxf);                                                  \
638
0
      FIELD_RD (nam.y, dxf + 10);                                             \
639
0
    }
640
#define FIELD_2BD(nam, dxf) FIELD_2RD (nam, dxf)
641
#define FIELD_2BD_1(nam, dxf)                                                 \
642
0
  if (dxf)                                                                    \
643
0
    {                                                                         \
644
0
      FIELD_RD (nam.x, dxf);                                                  \
645
0
      FIELD_RD (nam.y, dxf + 1);                                              \
646
0
    }
647
#define FIELD_3RD(nam, dxf)                                                   \
648
0
  if (dxf)                                                                    \
649
0
    {                                                                         \
650
0
      FIELD_RD (nam.x, dxf);                                                  \
651
0
      FIELD_RD (nam.y, dxf + 10);                                             \
652
0
      FIELD_RD (nam.z, dxf + 20);                                             \
653
0
    }
654
0
#define FIELD_3BD(nam, dxf) FIELD_3RD (nam, dxf)
655
#define FIELD_3BD_1(nam, dxf)                                                 \
656
0
  if (dxf)                                                                    \
657
0
    {                                                                         \
658
0
      FIELD_RD (nam.x, dxf);                                                  \
659
0
      FIELD_RD (nam.y, dxf + 1);                                              \
660
0
      FIELD_RD (nam.z, dxf + 2);                                              \
661
0
    }
662
0
#define FIELD_3DPOINT(nam, dxf) FIELD_3RD (nam, dxf)
663
#define FIELD_CMC(color, dxf)                                                 \
664
0
  {                                                                           \
665
0
    if (dat->version < R_2004)                                                \
666
0
      {                                                                       \
667
0
        if (dat->from_version >= R_2004)                                      \
668
0
          bit_downconvert_CMC (dat, (Dwg_Color *)&_obj->color);               \
669
0
        VALUE_RS (_obj->color.index, dxf);                                    \
670
0
      }                                                                       \
671
0
    else                                                                      \
672
0
      {                                                                       \
673
0
        if (dat->from_version < R_2004)                                       \
674
0
          bit_upconvert_CMC (dat, (Dwg_Color *)&_obj->color);                 \
675
0
        if (dxf >= 90)                                                        \
676
0
          {                                                                   \
677
0
            VALUE_RL (_obj->color.rgb, dxf);                                  \
678
0
          }                                                                   \
679
0
        else if (_obj->color.method == 0xc3)                                  \
680
0
          {                                                                   \
681
0
            VALUE_RL (_obj->color.rgb & 0x00ffffff, dxf);                     \
682
0
          }                                                                   \
683
0
        else if (_obj->color.method == 0xc8)                                  \
684
0
          {                                                                   \
685
0
            VALUE_RS (257, dxf);                                              \
686
0
          }                                                                   \
687
0
        else                                                                  \
688
0
          {                                                                   \
689
0
            VALUE_RS (_obj->color.index, dxf);                                \
690
0
            if (_obj->color.method == 0xc2)                                   \
691
0
              VALUE_RL (_obj->color.rgb, (unsigned)(dxf + 420 - 62));         \
692
0
          }                                                                   \
693
0
      }                                                                       \
694
0
  }
695
#define FIELD_CMC0(color, dxf)                                                \
696
0
  {                                                                           \
697
0
    if (dat->version < R_2004)                                                \
698
0
      {                                                                       \
699
0
        if (dat->from_version >= R_2004)                                      \
700
0
          bit_downconvert_CMC (dat, (Dwg_Color *)&_obj->color);               \
701
0
        if (_obj->color.index)                                                \
702
0
          VALUE_RS (_obj->color.index, dxf);                                  \
703
0
      }                                                                       \
704
0
    else                                                                      \
705
0
      {                                                                       \
706
0
        if (dat->from_version < R_2004)                                       \
707
0
          bit_upconvert_CMC (dat, (Dwg_Color *)&_obj->color);                 \
708
0
        if (dxf >= 90)                                                        \
709
0
          {                                                                   \
710
0
            VALUE_RL (_obj->color.rgb, dxf);                                  \
711
0
          }                                                                   \
712
0
        else if (_obj->color.method == 0xc3)                                  \
713
0
          {                                                                   \
714
0
            VALUE_RL (_obj->color.rgb & 0x00ffffff, dxf);                     \
715
0
          }                                                                   \
716
0
        else if (_obj->color.method == 0xc8)                                  \
717
0
          {                                                                   \
718
0
            VALUE_RS (257, dxf);                                              \
719
0
          }                                                                   \
720
0
        else                                                                  \
721
0
          {                                                                   \
722
0
            if (_obj->color.index)                                            \
723
0
              VALUE_RS (_obj->color.index, dxf);                              \
724
0
            if (_obj->color.method == 0xc2)                                   \
725
0
              VALUE_RL (_obj->color.rgb, (unsigned)(dxf + 420 - 62));         \
726
0
          }                                                                   \
727
0
      }                                                                       \
728
0
  }
729
#define SUB_FIELD_CMC(o, color, dxf)                                          \
730
0
  {                                                                           \
731
0
    if (dat->version < R_2004)                                                \
732
0
      {                                                                       \
733
0
        if (dat->from_version >= R_2004)                                      \
734
0
          bit_downconvert_CMC (dat, (Dwg_Color *)&_obj->o.color);             \
735
0
        VALUE_RS (_obj->o.color.index, dxf);                                  \
736
0
      }                                                                       \
737
0
    else                                                                      \
738
0
      {                                                                       \
739
0
        if (dat->from_version < R_2004)                                       \
740
0
          bit_upconvert_CMC (dat, (Dwg_Color *)&_obj->o.color);               \
741
0
        if (dxf >= 90)                                                        \
742
0
          {                                                                   \
743
0
            VALUE_RL (_obj->o.color.rgb, dxf);                                \
744
0
          }                                                                   \
745
0
        else if (_obj->o.color.method == 0xc8)                                \
746
0
          {                                                                   \
747
0
            VALUE_RS (257, dxf);                                              \
748
0
          }                                                                   \
749
0
        else if (_obj->o.color.method == 0xc3)                                \
750
0
          {                                                                   \
751
0
            VALUE_RL (_obj->o.color.rgb & 0x00ffffff, dxf);                   \
752
0
          }                                                                   \
753
0
        else                                                                  \
754
0
          {                                                                   \
755
0
            VALUE_RS (_obj->o.color.index, dxf);                              \
756
0
            if (_obj->o.color.method == 0xc2)                                 \
757
0
              VALUE_RL (_obj->o.color.rgb, (unsigned)(dxf + 420 - 62));       \
758
0
          }                                                                   \
759
0
      }                                                                       \
760
0
  }
761
#define HEADER_CMC(nam, dxf)                                                  \
762
0
  {                                                                           \
763
0
    HEADER_9 (nam);                                                           \
764
0
    VALUE_RS (dwg->header_vars.nam.index, dxf);                               \
765
0
  }
766
#define HEADER_TIMEBLL(nam, dxf)                                              \
767
0
  {                                                                           \
768
0
    HEADER_9 (nam);                                                           \
769
0
    FIELD_TIMEBLL (nam, dxf);                                                 \
770
0
  }
771
0
#define FIELD_TIMEBLL(nam, dxf) VALUE_RD (_obj->nam.value, dxf)
772
773
// FIELD_VECTOR_N(nam, type, size):
774
// reads data of the type indicated by 'type' 'size' times and stores
775
// it all in the vector called 'nam'.
776
#define FIELD_VECTOR_N(nam, type, size, dxf)                                  \
777
0
  if (dxf && _obj->nam)                                                       \
778
0
    {                                                                         \
779
0
      for (vcount = 0; vcount < (BITCODE_BL)size; vcount++)                   \
780
0
        VALUE (_obj->nam[vcount], type, dxf);                                 \
781
0
    }
782
#define FIELD_VECTOR_T(nam, type, size, dxf)                                  \
783
0
  if (dxf && _obj->nam)                                                       \
784
0
    {                                                                         \
785
0
      if (!IS_FROM_TU (dat))                                                  \
786
0
        {                                                                     \
787
0
          for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++)         \
788
0
            VALUE_TV (_obj->nam[vcount], dxf)                                 \
789
0
        }                                                                     \
790
0
      else                                                                    \
791
0
        {                                                                     \
792
0
          for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++)         \
793
0
            VALUE_TU (_obj->nam[vcount], dxf)                                 \
794
0
        }                                                                     \
795
0
    }
796
797
#define FIELD_VECTOR(nam, type, size, dxf)                                    \
798
0
  FIELD_VECTOR_N (nam, type, _obj->size, dxf)
799
800
#define FIELD_2RD_VECTOR(nam, size, dxf)                                      \
801
0
  if (dxf && _obj->nam)                                                       \
802
0
    {                                                                         \
803
0
      for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++)             \
804
0
        {                                                                     \
805
0
          FIELD_2RD (nam[vcount], dxf);                                       \
806
0
        }                                                                     \
807
0
    }
808
809
#define FIELD_2DD_VECTOR(nam, size, dxf)                                      \
810
  FIELD_2RD (nam[0], dxf);                                                    \
811
  if (dxf && _obj->nam)                                                       \
812
    {                                                                         \
813
      for (vcount = 1; vcount < (BITCODE_BL)_obj->size; vcount++)             \
814
        {                                                                     \
815
          FIELD_2DD (nam[vcount], nam[vcount - 1], dxf);                      \
816
        }                                                                     \
817
    }
818
819
#define FIELD_3DPOINT_VECTOR(nam, size, dxf)                                  \
820
0
  if (dxf && _obj->nam)                                                       \
821
0
    {                                                                         \
822
0
      for (vcount = 0; vcount < (BITCODE_BL)_obj->size; vcount++)             \
823
0
        {                                                                     \
824
0
          FIELD_3DPOINT (nam[vcount], dxf);                                   \
825
0
        }                                                                     \
826
0
    }
827
828
#define HANDLE_VECTOR_N(nam, size, code, dxf)                                 \
829
0
  if (dxf && _obj->nam)                                                       \
830
0
    {                                                                         \
831
0
      for (vcount = 0; vcount < (BITCODE_BL)size; vcount++)                   \
832
0
        {                                                                     \
833
0
          FIELD_HANDLE_N (nam[vcount], vcount, code, dxf);                    \
834
0
        }                                                                     \
835
0
    }
836
837
#define HANDLE_VECTOR(nam, sizefield, code, dxf)                              \
838
0
  HANDLE_VECTOR_N (nam, FIELD_VALUE (sizefield), code, dxf)
839
840
#define FIELD_NUM_INSERTS(num_inserts, type, dxf)                             \
841
0
  FIELDG (num_inserts, type, dxf)
842
843
#define FIELD_XDATA(nam, size)                                                \
844
0
  dxfb_write_xdata (dat, obj, _obj->nam, _obj->size)
845
846
#define _XDICOBJHANDLE(code)                                                  \
847
0
  if (dat->version >= R_13b1 && obj->tio.object->xdicobjhandle                \
848
0
      && obj->tio.object->xdicobjhandle->absolute_ref)                        \
849
0
    {                                                                         \
850
0
      VALUE_TV ("{ACAD_XDICTIONARY", 102);                                    \
851
0
      VALUE_HANDLE (obj->tio.object->xdicobjhandle, xdicobjhandle, code,      \
852
0
                    360);                                                     \
853
0
      VALUE_TV ("}", 102);                                                    \
854
0
    }
855
#define _REACTORS(code)                                                       \
856
0
  if (dat->version >= R_13b1 && obj->tio.object->num_reactors                 \
857
0
      && obj->tio.object->reactors)                                           \
858
0
    {                                                                         \
859
0
      VALUE_TV ("{ACAD_REACTORS", 102)                                        \
860
0
      for (vcount = 0; vcount < obj->tio.object->num_reactors; vcount++)      \
861
0
        {                                                                     \
862
0
          VALUE_HANDLE (obj->tio.object->reactors[vcount], reactors, code,    \
863
0
                        330);                                                 \
864
0
        }                                                                     \
865
0
      VALUE_TV ("}", 102)                                                     \
866
0
    }
867
#define ENT_REACTORS(code)                                                    \
868
0
  if (dat->version >= R_13b1 && _obj->num_reactors && _obj->reactors)         \
869
0
    {                                                                         \
870
0
      VALUE_TV ("{ACAD_REACTORS", 102)                                        \
871
0
      for (vcount = 0; vcount < _obj->num_reactors; vcount++)                 \
872
0
        {                                                                     \
873
0
          VALUE_HANDLE (_obj->reactors[vcount], reactors, code, 330);         \
874
0
        }                                                                     \
875
0
      VALUE_TV ("}", 102)                                                     \
876
0
    }
877
878
#define REACTORS(code)
879
#define XDICOBJHANDLE(code)
880
#define ENT_XDICOBJHANDLE(code)                                               \
881
0
  if (dat->version >= R_13b1 && obj->tio.entity->xdicobjhandle                \
882
0
      && obj->tio.entity->xdicobjhandle->absolute_ref)                        \
883
0
    {                                                                         \
884
0
      VALUE_TV ("{ACAD_XDICTIONARY", 102);                                    \
885
0
      VALUE_HANDLE (obj->tio.entity->xdicobjhandle, xdicobjhandle, code,      \
886
0
                    360);                                                     \
887
0
      VALUE_TV ("}", 102);                                                    \
888
0
    }
889
0
#define BLOCK_NAME(nam, dxf) dxfb_cvt_blockname (dat, _obj->nam, dxf)
890
891
#define COMMON_ENTITY_HANDLE_DATA
892
#define SECTION_STRING_STREAM
893
#define START_STRING_STREAM
894
#define END_STRING_STREAM
895
#define START_HANDLE_STREAM
896
897
#ifndef DEBUG_CLASSES
898
static int
899
dwg_dxfb_TABLECONTENT (Bit_Chain *restrict dat, const Dwg_Object *restrict obj)
900
0
{
901
0
  (void)dat;
902
0
  (void)obj;
903
0
  return 0;
904
0
}
905
#else
906
static int dwg_dxfb_TABLECONTENT (Bit_Chain *restrict dat,
907
                                  const Dwg_Object *restrict obj);
908
#endif
909
910
#define DWG_ENTITY(token)                                                     \
911
  static int dwg_dxfb_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat,  \
912
                                         Bit_Chain *str_dat,                  \
913
                                         const Dwg_Object *restrict obj);     \
914
  static int dwg_dxfb_##token (Bit_Chain *restrict dat,                       \
915
                               const Dwg_Object *restrict obj)                \
916
0
  {                                                                           \
917
0
    int error = 0;                                                            \
918
0
    Bit_Chain *hdl_dat = dat;                                                 \
919
0
    Bit_Chain *str_dat = dat;                                                 \
920
0
    if (obj->fixedtype != DWG_TYPE_##token)                                   \
921
0
      {                                                                       \
922
0
        LOG_ERROR ("Invalid type 0x%x, expected 0x%x %s", obj->fixedtype,     \
923
0
                   DWG_TYPE_##token, #token);                                 \
924
0
        return DWG_ERR_INVALIDTYPE;                                           \
925
0
      }                                                                       \
926
0
    if (strEQc (#token, "GEOPOSITIONMARKER"))                                 \
927
0
      RECORD (POSITIONMARKER)                                                 \
928
0
    else if (dat->version < R_13b1 && strlen (#token) == 10                   \
929
0
             && strEQc (#token, "LWPOLYLINE"))                                \
930
0
      RECORD (POLYLINE)                                                       \
931
0
    else if (strlen (#token) > 10 && !memcmp (#token, "DIMENSION_", 10))      \
932
0
      RECORD (DIMENSION)                                                      \
933
0
    else if (strlen (#token) > 9 && !memcmp (#token, "POLYLINE_", 9))         \
934
0
      RECORD (POLYLINE)                                                       \
935
0
    else if (strlen (#token) > 7 && !memcmp (#token, "VERTEX_", 7))           \
936
0
      RECORD (VERTEX)                                                         \
937
0
    else if (strEQc (#token, "MINSERT"))                                      \
938
0
      RECORD (INSERT)                                                         \
939
0
    else if (dat->version >= R_2010 && strEQc (#token, "TABLE"))              \
940
0
      {                                                                       \
941
0
        RECORD (ACAD_TABLE);                                                  \
942
0
        return dwg_dxfb_TABLECONTENT (dat, obj);                              \
943
0
      }                                                                       \
944
0
    else if (strlen (#token) > 3 && !memcmp (#token, "_3D", 3))               \
945
0
      VALUE_TV (obj->dxfname, 0)                                              \
946
0
    else if (obj->type >= 498 && obj->dxfname)                                \
947
0
      VALUE_TV (obj->dxfname, 0)                                              \
948
0
    else                                                                      \
949
0
      RECORD (token)                                                          \
950
0
    LOG_INFO ("Entity " #token ":\n")                                         \
951
0
    SINCE (R_11)                                                              \
952
0
    {                                                                         \
953
0
      LOG_TRACE ("Entity handle: " FORMAT_H "\n", ARGS_H (obj->handle))       \
954
0
      VALUE_H (obj->handle.value, 5);                                         \
955
0
    }                                                                         \
956
0
    SINCE (R_13b1)                                                            \
957
0
    {                                                                         \
958
0
      VALUE_HANDLE_NAME (obj->parent->header_vars.BLOCK_RECORD_MSPACE, 330,   \
959
0
                         BLOCK_HEADER);                                       \
960
0
    }                                                                         \
961
0
    error |= dxfb_common_entity_handle_data (dat, obj);                       \
962
0
    error |= dwg_dxfb_##token##_private (dat, hdl_dat, str_dat, obj);         \
963
0
    error |= dxfb_write_eed (dat, obj->tio.object);                           \
964
0
    return error;                                                             \
965
0
  }                                                                           \
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TEXT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ATTDEF
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCK
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_INSERT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SEQEND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MINSERT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POLYLINE_2D
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POLYLINE_3D
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POLYLINE_PFACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POLYLINE_MESH
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ATTRIB
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VERTEX_2D
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VERTEX_3D
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VERTEX_MESH
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VERTEX_PFACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VERTEX_PFACE_FACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ARC
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_CIRCLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_ORDINATE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_LINEAR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_ALIGNED
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_ANG3PT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_ANG2LN
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_RADIUS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMENSION_DIAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb__3DFACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SOLID
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TRACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SHAPE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VIEWPORT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ELLIPSE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SPLINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_REGION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb__3DSOLID
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RAY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_XLINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MTEXT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LEADER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TOLERANCE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_OLE2FRAME
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LWPOLYLINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_HATCH
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PROXY_ENTITY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_OLEFRAME
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_CAMERA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IMAGE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LIGHT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MESH
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MULTILEADER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SECTIONOBJECT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PDFUNDERLAY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DGNUNDERLAY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DWFUNDERLAY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_REPEAT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ENDREP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb__3DLINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_JUMP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_WIPEOUT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ARC_DIMENSION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PLANESURFACE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_HELIX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LARGE_RADIAL_DIMENSION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYOUTPRINTCONFIG
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUD
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ENDBLK
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MLINE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LOAD
966
  static int dwg_dxfb_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat,  \
967
                                         Bit_Chain *str_dat,                  \
968
                                         const Dwg_Object *restrict obj)      \
969
0
  {                                                                           \
970
0
    int error = 0;                                                            \
971
0
    BITCODE_BL vcount, rcount3, rcount4;                                      \
972
0
    Dwg_Data *dwg = obj->parent;                                              \
973
0
    Dwg_Entity_##token *_obj = obj->tio.entity->tio.token;                    \
974
0
    Dwg_Object_Entity *_ent = obj->tio.entity;
975
976
#define DWG_ENTITY_END                                                        \
977
0
  return error;                                                               \
978
0
  }
979
980
#define DWG_OBJECT(token)                                                     \
981
  static int dwg_dxfb_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat,  \
982
                                         Bit_Chain *str_dat,                  \
983
                                         const Dwg_Object *restrict obj);     \
984
  static int dwg_dxfb_##token (Bit_Chain *restrict dat,                       \
985
                               const Dwg_Object *restrict obj)                \
986
0
  {                                                                           \
987
0
    BITCODE_BL vcount;                                                        \
988
0
    int error = 0;                                                            \
989
0
    Bit_Chain *str_dat = dat;                                                 \
990
0
    Bit_Chain *hdl_dat = dat;                                                 \
991
0
    LOG_INFO ("Object " #token ":\n")                                         \
992
0
    if (obj->fixedtype != DWG_TYPE_##token)                                   \
993
0
      {                                                                       \
994
0
        LOG_ERROR ("Invalid type 0x%x, expected 0x%x %s", obj->fixedtype,     \
995
0
                   DWG_TYPE_##token, #token);                                 \
996
0
        return DWG_ERR_INVALIDTYPE;                                           \
997
0
      }                                                                       \
998
0
    PRE (R_14)                                                                \
999
0
    {                                                                         \
1000
0
      if (obj->fixedtype == DWG_TYPE_PLACEHOLDER)                             \
1001
0
        return 0;                                                             \
1002
0
    }                                                                         \
1003
0
    if (!dwg_obj_is_control (obj))                                            \
1004
0
      {                                                                       \
1005
0
        if (obj->fixedtype == DWG_TYPE_TABLE)                                 \
1006
0
          ;                                                                   \
1007
0
        else if (obj->type >= 500 && obj->dxfname)                            \
1008
0
          VALUE_TV (obj->dxfname, 0)                                          \
1009
0
        else if (obj->type == DWG_TYPE_PLACEHOLDER)                           \
1010
0
          RECORD (ACDBPLACEHOLDER)                                            \
1011
0
        else if (obj->fixedtype == DWG_TYPE_PROXY_OBJECT)                     \
1012
0
          RECORD (ACAD_PROXY_OBJECT)                                          \
1013
0
        else if (obj->type != DWG_TYPE_BLOCK_HEADER)                          \
1014
0
          RECORD (token)                                                      \
1015
0
        SINCE (R_13b1)                                                        \
1016
0
        {                                                                     \
1017
0
          const int dxf = obj->type == DWG_TYPE_DIMSTYLE ? 105 : 5;           \
1018
0
          VALUE_H (obj->handle.value, dxf);                                   \
1019
0
          _XDICOBJHANDLE (3);                                                 \
1020
0
          _REACTORS (4);                                                      \
1021
0
        }                                                                     \
1022
0
        SINCE (R_14)                                                          \
1023
0
        {                                                                     \
1024
0
          VALUE_HANDLE (obj->tio.object->ownerhandle, ownerhandle, 3, 330);   \
1025
0
        }                                                                     \
1026
0
      }                                                                       \
1027
0
    if (DWG_LOGLEVEL >= DWG_LOGLEVEL_TRACE)                                   \
1028
0
      {                                                                       \
1029
0
        if (dwg_obj_is_table (obj))                                           \
1030
0
          {                                                                   \
1031
0
            char *_name = dwg_obj_table_get_name (obj, &error);               \
1032
0
            LOG_TRACE ("Object handle: " FORMAT_H ", name: %s\n",             \
1033
0
                       ARGS_H (obj->handle), _name);                          \
1034
0
            if (IS_FROM_TU (dat))                                             \
1035
0
              free (_name);                                                   \
1036
0
          }                                                                   \
1037
0
        else                                                                  \
1038
0
          LOG_TRACE ("Object handle: " FORMAT_H "\n", ARGS_H (obj->handle))   \
1039
0
      }                                                                       \
1040
0
    error |= dwg_dxfb_##token##_private (dat, hdl_dat, str_dat, obj);         \
1041
0
    error |= dxfb_write_eed (dat, obj->tio.object);                           \
1042
0
    return error;                                                             \
1043
0
  }                                                                           \
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VPORT_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VPORT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LTYPE_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LTYPE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYER_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_STYLE_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_STYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VIEW_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VIEW
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_UCS_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_UCS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_APPID_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_APPID
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMSTYLE_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DIMSTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCK_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCK_HEADER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DICTIONARY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_GROUP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MLINESTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LONG_TRANSACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_XRECORD
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PLACEHOLDER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYOUT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_BOOLEAN_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_BOX_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_CONE_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_CYLINDER_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_FILLET_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_HISTORY_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_SPHERE_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_TORUS_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_WEDGE_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCNETWORK
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCGEOMDEPENDENCY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKGRIPLOCATIONCOMPONENT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKALIGNMENTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKALIGNMENTGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKBASEPOINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKFLIPACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKFLIPPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKFLIPGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLINEARGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLOOKUPGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKROTATIONGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKMOVEACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKROTATEACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKSCALEACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKVISIBILITYGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_CELLSTYLEMAP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DICTIONARYVAR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DICTIONARYWDFLT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DYNAMICBLOCKPURGEPREVENTER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_FIELD
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_FIELDLIST
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_GEODATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IDBUFFER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_INDEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IMAGEDEF
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IMAGEDEF_REACTOR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYER_INDEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LAYERFILTER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PLOTSETTINGS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RASTERVARIABLES
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RENDERENVIRONMENT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SCALE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SECTION_MANAGER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DETAILVIEWSTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SECTIONVIEWSTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SORTENTSTABLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SPATIAL_FILTER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SUN
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TABLEGEOMETRY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PDFDEFINITION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DGNDEFINITION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DWFDEFINITION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VBA_PROJECT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VISUALSTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_WIPEOUTVARIABLES
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MLEADERSTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_BREP_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_CHAMFER_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ACSH_PYRAMID_CLASS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCDEPENDENCY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCVALUEDEPENDENCY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCARRAYACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCBLENDSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCEXTENDSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCEXTRUDEDSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCFILLETSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCLOFTEDSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCNETWORKSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCOFFSETSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCPATCHSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCPLANESURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCREVOLVEDSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCTRIMSURFACEACTIONBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_EVALUATION_GRAPH
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DATALINK
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_DBCOLOR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LIGHTLIST
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MATERIAL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MENTALRAYRENDERSETTINGS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_OBJECT_PTR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PROXY_OBJECT
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RAPIDRTRENDERSETTINGS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RENDERSETTINGS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RENDERENTRY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_RENDERGLOBAL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SPATIAL_INDEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TABLESTYLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SECTION_SETTINGS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SOLID_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_SKYLIGHT_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_GROUND_PLANE_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_GRADIENT_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IMAGE_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_IBL_BACKGROUND
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLINEARPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKROTATIONPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKXYPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKVISIBILITYPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKPOLARPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKPOLARGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKREPRESENTATION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCDIMDEPENDENCYBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKPARAMDEPENDENCYBODY
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ALDIMOBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_MTEXTOBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLKREFOBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_LEADEROBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_TEXTOBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_FCFOBJECTCONTEXTDATA
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCVARIABLE
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOC2DCONSTRAINTGROUP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCOSNAPPOINTREFACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCPOINTREFACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCASMBODYACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCCOMPOUNDACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCFACEACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCOBJECTACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCPATHACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCVERTEXACTIONPARAM
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCARRAYMODIFYPARAMETERS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCARRAYPATHPARAMETERS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCARRAYPOLARPARAMETERS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_ASSOCARRAYRECTANGULARPARAMETERS
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKALIGNEDCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKANGULARCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKARRAYACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKDIAMETRICCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKHORIZONTALCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLINEARCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKRADIALCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKVERTICALCONSTRAINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLOOKUPACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKLOOKUPPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKPOINTPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKPOLARSTRETCHACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKSTRETCHACTION
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKUSERPARAMETER
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_BLOCKXYGRIP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDDEF
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDDEFEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDDEF_REACTOR
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDDEF_REACTOR_EX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_POINTCLOUDCOLORMAP
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_PARTIAL_VIEWING_INDEX
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VX_CONTROL
Unexecuted instantiation: out_dxfb.c:dwg_dxfb_VX_TABLE_RECORD
1044
  static int dwg_dxfb_##token##_private (Bit_Chain *dat, Bit_Chain *hdl_dat,  \
1045
                                         Bit_Chain *str_dat,                  \
1046
                                         const Dwg_Object *restrict obj)      \
1047
0
  {                                                                           \
1048
0
    int error = 0;                                                            \
1049
0
    BITCODE_BL vcount, rcount3, rcount4;                                      \
1050
0
    Dwg_Data *dwg = obj->parent;                                              \
1051
0
    Dwg_Object_##token *_obj = obj->tio.object->tio.token;
1052
1053
// then 330, SUBCLASS
1054
1055
#define DWG_OBJECT_END                                                        \
1056
0
  return error;                                                               \
1057
0
  }
1058
1059
static int
1060
dxfb_write_eed (Bit_Chain *restrict dat, const Dwg_Object_Object *restrict obj)
1061
0
{
1062
0
  int error = 0;
1063
0
  Dwg_Data *dwg = obj->dwg;
1064
0
  for (BITCODE_BL i = 0; i < obj->num_eed; i++)
1065
0
    {
1066
0
      const Dwg_Eed *_obj = &obj->eed[i];
1067
0
      if (_obj->size)
1068
0
        {
1069
          // name of APPID
1070
0
          Dwg_Object *appid = dwg_resolve_handle (dwg, _obj->handle.value);
1071
0
          if (appid && appid->fixedtype == DWG_TYPE_APPID)
1072
0
            VALUE_T (appid->tio.object->tio.APPID->name, 1001)
1073
0
          else
1074
0
            VALUE_TFF ("ACAD", 1001);
1075
0
        }
1076
0
      if (_obj->data)
1077
0
        {
1078
0
          const Dwg_Eed_Data *data = _obj->data;
1079
0
          const int dxf = data->code + 1000;
1080
0
          switch (data->code)
1081
0
            {
1082
0
            case 0:
1083
0
              if (IS_FROM_TU (dat))
1084
0
                VALUE_TU (data->u.eed_0_r2007.string, 1000)
1085
0
              else
1086
0
                VALUE_TV (data->u.eed_0.string, 1000)
1087
0
              break;
1088
0
            case 2:
1089
0
              if (data->u.eed_2.close)
1090
0
                VALUE_TFF ("}", 1002)
1091
0
              else
1092
0
                VALUE_TFF ("{", 1002)
1093
0
              break;
1094
0
            case 3:
1095
0
              GROUP (dxf);
1096
0
              fprintf (dat->fh, "%9lu\r\n",
1097
0
                       (unsigned long)data->u.eed_3.layer);
1098
              // VALUE_RLL (data->u.eed_3.layer, dxf);
1099
0
              break;
1100
0
            case 4:
1101
0
              VALUE_BINARY (data->u.eed_4.data, data->u.eed_4.length, dxf);
1102
0
              break;
1103
0
            case 5:
1104
0
              VALUE_H (data->u.eed_5.entity, dxf);
1105
0
              break; // not in DXF
1106
0
            case 10:
1107
0
            case 11:
1108
0
            case 12:
1109
0
            case 13:
1110
0
            case 14:
1111
0
            case 15:
1112
0
              VALUE_3BD (data->u.eed_10.point, dxf);
1113
0
              break;
1114
0
            case 40:
1115
0
            case 41:
1116
0
            case 42:
1117
0
              VALUE_RD (data->u.eed_40.real, dxf);
1118
0
              break;
1119
0
            case 70:
1120
0
              VALUE_RS (data->u.eed_70.rs, dxf);
1121
0
              break;
1122
0
            case 71:
1123
0
              VALUE_RL (data->u.eed_71.rl, dxf);
1124
0
              break;
1125
0
            default:
1126
0
              VALUE_RC (0, dxf);
1127
0
            }
1128
0
        }
1129
0
    }
1130
0
  return error;
1131
0
}
1132
1133
static void
1134
dxfb_write_xdata (Bit_Chain *restrict dat, const Dwg_Object *restrict obj,
1135
                  Dwg_Resbuf *restrict rbuf, BITCODE_BL size)
1136
0
{
1137
0
  Dwg_Resbuf *tmp;
1138
0
  int i;
1139
1140
0
  while (rbuf)
1141
0
    {
1142
      // const char* fmt = dxf_format(rbuf->type);
1143
0
      short type = dwg_resbuf_value_type (rbuf->type);
1144
0
      int dxftype = (rbuf->type > 1000 || obj->fixedtype == DWG_TYPE_XRECORD)
1145
0
                        ? rbuf->type
1146
0
                        : rbuf->type + 1000;
1147
1148
0
      tmp = rbuf->nextrb;
1149
0
      switch (type)
1150
0
        {
1151
0
        case DWG_VT_STRING:
1152
0
          if (IS_FROM_TU (dat))
1153
0
            {
1154
0
              VALUE_TU (rbuf->value.str.u.wdata, dxftype);
1155
0
            }
1156
0
          else
1157
0
            {
1158
0
              VALUE_TV (rbuf->value.str.u.data, dxftype);
1159
0
            }
1160
0
          break;
1161
0
        case DWG_VT_REAL:
1162
0
          VALUE_RD (rbuf->value.dbl, dxftype);
1163
0
          break;
1164
0
        case DWG_VT_BOOL:
1165
0
        case DWG_VT_INT8:
1166
0
          VALUE_RC (rbuf->value.i8, dxftype);
1167
0
          break;
1168
0
        case DWG_VT_INT16:
1169
0
          VALUE_RS (rbuf->value.i16, dxftype);
1170
0
          break;
1171
0
        case DWG_VT_INT32:
1172
0
          VALUE_RL (rbuf->value.i32, dxftype);
1173
0
          break;
1174
0
        case DWG_VT_INT64:
1175
0
          VALUE_RLL (rbuf->value.i64, dxftype);
1176
0
          break;
1177
0
        case DWG_VT_POINT3D:
1178
0
          VALUE_RD (rbuf->value.pt[0], dxftype);
1179
0
          VALUE_RD (rbuf->value.pt[1], dxftype + 10);
1180
0
          VALUE_RD (rbuf->value.pt[2], dxftype + 20);
1181
0
          break;
1182
0
        case DWG_VT_BINARY:
1183
0
          VALUE_BINARY (rbuf->value.str.u.data, rbuf->value.str.size, dxftype);
1184
0
          break;
1185
0
        case DWG_VT_HANDLE:
1186
0
        case DWG_VT_OBJECTID:
1187
0
          VALUE_H (rbuf->value.absref, dxftype);
1188
0
          break;
1189
0
        case DWG_VT_INVALID:
1190
0
        default:
1191
          // fprintf(dat->fh, "");
1192
0
          break;
1193
0
        }
1194
0
      rbuf = tmp;
1195
0
    }
1196
0
}
1197
1198
#undef DXF_3DSOLID
1199
0
#define DXF_3DSOLID dxfb_3dsolid (dat, obj, (Dwg_Entity_3DSOLID *)_obj);
1200
1201
// r13+ converts STANDARD to Standard, BYLAYER to ByLayer, BYBLOCK to ByBlock
1202
static void
1203
dxfb_cvt_tablerecord (Bit_Chain *restrict dat, const Dwg_Object *restrict obj,
1204
                      char *restrict name, const int dxf)
1205
0
{
1206
0
  if (obj && obj->supertype == DWG_SUPERTYPE_OBJECT && name)
1207
0
    {
1208
0
      if (IS_FROM_TU (dat))
1209
0
        {
1210
0
          name = bit_convert_TU ((BITCODE_TU)name);
1211
0
        }
1212
0
      if (dat->from_version >= R_13b1 && dat->version < R_13b1)
1213
0
        { // convert the other way round, from newer to older
1214
0
          if (strEQc (name, "Standard"))
1215
0
            VALUE_TV ("STANDARD", dxf)
1216
0
          else if (strEQc (name, "ByLayer"))
1217
0
            VALUE_TV ("BYLAYER", dxf)
1218
0
          else if (strEQc (name, "ByBlock"))
1219
0
            VALUE_TV ("BYBLOCK", dxf)
1220
0
          else if (strEQc (name, "*Active"))
1221
0
            VALUE_TV ("*ACTIVE", dxf)
1222
0
          else
1223
0
            VALUE_TV (name, dxf)
1224
0
        }
1225
0
      else
1226
0
        { // convert some standard names
1227
0
          if (dat->version >= R_13b1 && strEQc (name, "STANDARD"))
1228
0
            VALUE_TV ("Standard", dxf)
1229
0
          else if (dat->version >= R_13b1 && strEQc (name, "BYLAYER"))
1230
0
            VALUE_TV ("ByLayer", dxf)
1231
0
          else if (dat->version >= R_13b1 && strEQc (name, "BYBLOCK"))
1232
0
            VALUE_TV ("ByBlock", dxf)
1233
0
          else if (dat->version >= R_13b1 && strEQc (name, "*ACTIVE"))
1234
0
            VALUE_TV ("*Active", dxf)
1235
0
          else
1236
0
            VALUE_TV (name, dxf)
1237
0
        }
1238
0
      if (IS_FROM_TU (dat))
1239
0
        free (name);
1240
0
    }
1241
0
  else
1242
0
    {
1243
0
      VALUE_TV ("", dxf)
1244
0
    }
1245
0
}
1246
1247
/* pre-r13 mspace and pspace blocks have different names:
1248
 *Model_Space => $MODEL_SPACE
1249
 *Paper_Space => $PAPER_SPACE
1250
 */
1251
static void
1252
dxfb_cvt_blockname (Bit_Chain *restrict dat, char *restrict name,
1253
                    const int dxf)
1254
0
{
1255
0
  if (!name)
1256
0
    {
1257
0
      VALUE_TV ("", dxf)
1258
0
      return;
1259
0
    }
1260
0
  if (IS_FROM_TU (dat)) // r2007+ unicode names
1261
0
    {
1262
0
      name = bit_convert_TU ((BITCODE_TU)name);
1263
0
    }
1264
0
  if (dat->version == dat->from_version) // no conversion
1265
0
    {
1266
0
      VALUE_TV (name, dxf)
1267
0
    }
1268
0
  else if (dat->version < R_13b1 && dat->from_version >= R_13b1) // to older
1269
0
    {
1270
0
      if (strlen (name) < 10)
1271
0
        VALUE_TV (name, dxf)
1272
0
      else if (strEQc (name, "*Model_Space"))
1273
0
        VALUE_TV ("$MODEL_SPACE", dxf)
1274
0
      else if (strEQc (name, "*Paper_Space"))
1275
0
        VALUE_TV ("$PAPER_SPACE", dxf)
1276
0
      else if (!memcmp (name, "*Paper_Space", sizeof ("*Paper_Space") - 1))
1277
0
        {
1278
0
          GROUP (dxf);
1279
0
          fprintf (dat->fh, "$PAPER_SPACE%s%c", &name[12], 0);
1280
0
        }
1281
0
      else
1282
0
        VALUE_TV (name, dxf)
1283
0
    }
1284
0
  else if (dat->version >= R_13b1 && dat->from_version < R_13b1) // to newer
1285
0
    {
1286
0
      if (strlen (name) < 10)
1287
0
        VALUE_TV (name, dxf)
1288
0
      else if (strEQc (name, "$MODEL_SPACE"))
1289
0
        VALUE_TV ("*Model_Space", dxf)
1290
0
      else if (strEQc (name, "$PAPER_SPACE"))
1291
0
        VALUE_TV ("*Paper_Space", dxf)
1292
0
      else if (!memcmp (name, "$PAPER_SPACE", sizeof ("$PAPER_SPACE") - 1))
1293
0
        {
1294
0
          GROUP (dxf);
1295
0
          fprintf (dat->fh, "*Paper_Space%s%c", &name[12], 0);
1296
0
        }
1297
0
      else
1298
0
        VALUE_TV (name, dxf)
1299
0
    }
1300
0
  if (IS_FROM_TU (dat))
1301
0
    free (name);
1302
0
}
1303
1304
#define START_OBJECT_HANDLE_STREAM
1305
1306
// Handle 5 written here first
1307
#define COMMON_TABLE_CONTROL_FLAGS                                            \
1308
0
  if (ctrl)                                                                   \
1309
0
    {                                                                         \
1310
0
      SINCE (R_13b1)                                                          \
1311
0
      {                                                                       \
1312
0
        BITCODE_BL vcount;                                                    \
1313
0
        VALUE_H (ctrl->handle.value, 5);                                      \
1314
0
        _XDICOBJHANDLE (3);                                                   \
1315
0
        _REACTORS (4);                                                        \
1316
0
      }                                                                       \
1317
0
      SINCE (R_14)                                                            \
1318
0
      {                                                                       \
1319
0
        VALUE_HANDLE (ctrl->tio.object->ownerhandle, ownerhandle, 3, 330);    \
1320
0
      }                                                                       \
1321
0
    }                                                                         \
1322
0
  SINCE (R_13b1)                                                              \
1323
0
  {                                                                           \
1324
0
    VALUE_TV ("AcDbSymbolTable", 100);                                        \
1325
0
  }
1326
1327
#define COMMON_TABLE_FLAGS(acdbname)                                          \
1328
0
  SINCE (R_13b1)                                                              \
1329
0
  {                                                                           \
1330
0
    VALUE_TV ("AcDbSymbolTableRecord", 100)                                   \
1331
0
    VALUE_TV ("AcDb" #acdbname "TableRecord", 100)                            \
1332
0
  }                                                                           \
1333
0
  if (strEQc (#acdbname, "Block") && dat->version >= R_13b1)                  \
1334
0
    {                                                                         \
1335
0
      Dwg_Object *blk = dwg_ref_object (                                      \
1336
0
          dwg, ((Dwg_Object_BLOCK_HEADER *)_obj)->block_entity);              \
1337
0
      if (blk && blk->type == DWG_TYPE_BLOCK)                                 \
1338
0
        {                                                                     \
1339
0
          Dwg_Entity_BLOCK *_blk = blk->tio.entity->tio.BLOCK;                \
1340
0
          VALUE_T (_blk->name, 2)                                             \
1341
0
        }                                                                     \
1342
0
      else if (_obj->name)                                                    \
1343
0
        {                                                                     \
1344
0
          VALUE_T (_obj->name, 2)                                             \
1345
0
        }                                                                     \
1346
0
      else                                                                    \
1347
0
        VALUE_TV ("*", 2)                                                     \
1348
0
    }                                                                         \
1349
0
  /* Empty name with xref shape names */                                      \
1350
0
  else if (strEQc (#acdbname, "TextStyle") && _obj->flag & 1                  \
1351
0
           && dxf_is_xrefdep_name (dat, _obj->name))                          \
1352
0
    VALUE_TV ("", 2)                                                          \
1353
0
  else if (_obj->name)                                                        \
1354
0
    dxfb_cvt_tablerecord (dat, obj, _obj->name, 2);                           \
1355
0
  else                                                                        \
1356
0
    VALUE_TV ("*", 2)                                                         \
1357
0
  if (strEQc (#acdbname, "Layer") && dat->version >= R_2000)                  \
1358
0
    {                                                                         \
1359
0
      /* Mask off plotflag and linewt. */                                     \
1360
0
      BITCODE_RC _flag = _obj->flag & ~0x3e0;                                 \
1361
0
      /* Don't keep bit 16 when not xrefdep like "XREF|name" */               \
1362
0
      if (_flag & 0x10 && !dxf_has_xrefdep_vertbar (dat, _obj->name))         \
1363
0
        _flag &= ~0x10;                                                       \
1364
0
      VALUE_RC (_flag, 70);                                                   \
1365
0
    }                                                                         \
1366
0
  else if (strEQc (#acdbname, "Block") && dat->version >= R_2000)             \
1367
0
    ; /* skip 70 for AcDbBlockTableRecord here. done in AcDbBlockBegin */     \
1368
0
  else                                                                        \
1369
0
    {                                                                         \
1370
0
      /* mask off 64, the loaded bit 6 */                                     \
1371
0
      VALUE_RS (_obj->flag & ~64, 70);                                        \
1372
0
    }
1373
1374
#define LAYER_TABLE_FLAGS(acdbname)                                           \
1375
  SINCE (R_14)                                                                \
1376
  {                                                                           \
1377
    VALUE_HANDLE (obj->tio.object->ownerhandle, ownerhandle, 3, 330);         \
1378
  }                                                                           \
1379
  SINCE (R_13b1)                                                              \
1380
  {                                                                           \
1381
    VALUE_TV ("AcDbSymbolTableRecord", 100)                                   \
1382
    VALUE_TV ("AcDb" #acdbname "TableRecord", 100)                            \
1383
  }                                                                           \
1384
  if (_obj->name)                                                             \
1385
    dxfb_cvt_tablerecord (dat, obj, _obj->name, 2);                           \
1386
  FIELD_RS (flag, 70)
1387
1388
#include "dwg.spec"
1389
1390
static int
1391
dxfb_3dsolid (Bit_Chain *restrict dat, const Dwg_Object *restrict obj,
1392
              Dwg_Entity_3DSOLID *restrict _obj)
1393
0
{
1394
0
  BITCODE_BL i;
1395
0
  int error = 0;
1396
1397
0
  COMMON_ENTITY_HANDLE_DATA;
1398
0
  SUBCLASS (AcDbModelerGeometry);
1399
1400
0
  FIELD_B (acis_empty, 0);
1401
0
  if (!FIELD_VALUE (acis_empty))
1402
0
    {
1403
0
      FIELD_B (unknown, 0);
1404
0
      FIELD_BS (version, 70);
1405
0
      if (FIELD_VALUE (version) == 1)
1406
0
        {
1407
0
          for (i = 0; i < FIELD_VALUE (num_blocks); i++)
1408
0
            {
1409
0
              char *s = FIELD_VALUE (encr_sat_data[i]);
1410
0
              int len = FIELD_VALUE (block_size[i]);
1411
              // DXF 1 + 3 if >255
1412
0
              while (len > 0)
1413
0
                {
1414
0
                  char *n = strchr (s, '\n');
1415
0
                  int l = len > 255 ? 255 : len & 0xff;
1416
0
                  if (n && ((long)(n - s) < (long)len))
1417
0
                    {
1418
0
                      l = n - s;
1419
0
                    }
1420
0
                  if (l)
1421
0
                    {
1422
0
                      if (len < 255)
1423
0
                        VALUE_BINARY (s, l, 1)
1424
0
                      else
1425
0
                        VALUE_BINARY (s, l, 3)
1426
0
                      l++;
1427
0
                      len -= l;
1428
0
                      s += l;
1429
0
                    }
1430
0
                  else
1431
0
                    {
1432
0
                      len--;
1433
0
                      s++;
1434
0
                    }
1435
0
                }
1436
0
            }
1437
          // LOG_TRACE("acis_data [1]:\n%s\n", FIELD_VALUE (acis_data));
1438
0
        }
1439
0
      else // if (FIELD_VALUE(version)==2)
1440
        // must use ASCII out
1441
0
        {
1442
0
          LOG_ERROR (
1443
0
              "ACIS BinaryFile v2 not yet supported. Use ASCII output.");
1444
0
        }
1445
0
    }
1446
0
  return error;
1447
0
}
1448
1449
/* returns 0 on success
1450
 */
1451
static int
1452
dwg_dxfb_variable_type (const Dwg_Data *restrict dwg, Bit_Chain *restrict dat,
1453
                        Dwg_Object *restrict obj)
1454
0
{
1455
0
  int i;
1456
0
  Dwg_Class *klass;
1457
0
  int is_entity;
1458
1459
0
  i = obj->type - 500;
1460
0
  if (i < 0 || i >= dwg->num_classes)
1461
0
    return DWG_ERR_INVALIDTYPE;
1462
0
  if (obj->fixedtype == DWG_TYPE_UNKNOWN_ENT
1463
0
      || obj->fixedtype == DWG_TYPE_UNKNOWN_OBJ)
1464
0
    return DWG_ERR_UNHANDLEDCLASS;
1465
1466
0
  klass = &dwg->dwg_class[i];
1467
0
  if (!klass || !klass->dxfname)
1468
0
    return DWG_ERR_INTERNALERROR;
1469
  // almost always false
1470
0
  is_entity = dwg_class_is_entity (klass);
1471
0
  if (dat->version < R_2000)
1472
0
    {
1473
      // keep only: IMAGE, LWPOLYLINE, HATCH
1474
0
      if (is_entity && strNE (klass->dxfname, "IMAGE")
1475
0
          && strNEc (klass->dxfname, "LWPOLYLINE")
1476
0
          && strNEc (klass->dxfname, "HATCH"))
1477
0
        {
1478
0
          LOG_WARN ("Skip %s\n", klass->dxfname)
1479
0
          return DWG_ERR_UNHANDLEDCLASS;
1480
0
        }
1481
      // keep only: DICTIONARYVAR, MATERIAL, RASTERVARIABLES, IMAGEDEF_REACTOR,
1482
      // XRECORD
1483
0
      else if (!is_entity && strNEc (klass->dxfname, "DICTIONARYVAR")
1484
0
               && strNEc (klass->dxfname, "MATERIAL")
1485
0
               && strNEc (klass->dxfname, "RASTERVARIABLES")
1486
0
               && strNEc (klass->dxfname, "IDBUFFER")
1487
0
               && strNEc (klass->dxfname, "IMAGEDEF_REACTOR")
1488
0
               && strNEc (klass->dxfname, "XRECORD"))
1489
0
        {
1490
0
          LOG_WARN ("Skip %s\n", klass->dxfname)
1491
0
          return DWG_ERR_UNHANDLEDCLASS;
1492
0
        }
1493
0
    }
1494
1495
    // clang-format off
1496
0
  #include "classes.inc"
1497
  // clang-format on
1498
1499
0
  return DWG_ERR_UNHANDLEDCLASS;
1500
0
}
1501
1502
/* process unsorted vertices */
1503
#define decl_dxfb_process_VERTEX(token)                                       \
1504
  static int dxfb_process_VERTEX_##token (Bit_Chain *restrict dat,            \
1505
                                          const Dwg_Object *restrict obj,     \
1506
                                          int *restrict i)                    \
1507
0
  {                                                                           \
1508
0
    int error = 0;                                                            \
1509
0
    Dwg_Entity_POLYLINE_##token *_obj                                         \
1510
0
        = obj->tio.entity->tio.POLYLINE_##token;                              \
1511
0
                                                                              \
1512
0
    VERSIONS (R_13b1, R_2000)                                                 \
1513
0
    {                                                                         \
1514
0
      Dwg_Object *last_vertex                                                 \
1515
0
          = _obj->last_vertex ? _obj->last_vertex->obj : NULL;                \
1516
0
      Dwg_Object *o = _obj->first_vertex ? _obj->first_vertex->obj : NULL;    \
1517
0
      if (!o || !last_vertex)                                                 \
1518
0
        return DWG_ERR_INVALIDHANDLE;                                         \
1519
0
      if (o->fixedtype == DWG_TYPE_VERTEX_##token)                            \
1520
0
        error |= dwg_dxfb_VERTEX_##token (dat, o);                            \
1521
0
      *i = *i + 1;                                                            \
1522
0
      do                                                                      \
1523
0
        {                                                                     \
1524
0
          o = dwg_next_object (o);                                            \
1525
0
          if (!o)                                                             \
1526
0
            return DWG_ERR_INVALIDHANDLE;                                     \
1527
0
          if (strEQc (#token, "PFACE")                                        \
1528
0
              && o->fixedtype == DWG_TYPE_VERTEX_PFACE_FACE)                  \
1529
0
            {                                                                 \
1530
0
              error |= dwg_dxfb_VERTEX_PFACE_FACE (dat, o);                   \
1531
0
            }                                                                 \
1532
0
          else if (o->fixedtype == DWG_TYPE_VERTEX_##token)                   \
1533
0
            {                                                                 \
1534
0
              error |= dwg_dxfb_VERTEX_##token (dat, o);                      \
1535
0
            }                                                                 \
1536
0
          *i = *i + 1;                                                        \
1537
0
        }                                                                     \
1538
0
      while (o->fixedtype != DWG_TYPE_SEQEND && o != last_vertex);            \
1539
0
      o = _obj->seqend ? _obj->seqend->obj : NULL;                            \
1540
0
      if (o && o->fixedtype == DWG_TYPE_SEQEND)                               \
1541
0
        error |= dwg_dxfb_SEQEND (dat, o);                                    \
1542
0
      *i = *i + 1;                                                            \
1543
0
    }                                                                         \
1544
0
    SINCE (R_2004a)                                                           \
1545
0
    {                                                                         \
1546
0
      Dwg_Object *o;                                                          \
1547
0
      for (BITCODE_BL j = 0; j < _obj->num_owned; j++)                        \
1548
0
        {                                                                     \
1549
0
          o = _obj->vertex && _obj->vertex[j] ? _obj->vertex[j]->obj : NULL;  \
1550
0
          if (strEQc (#token, "PFACE") && o                                   \
1551
0
              && o->fixedtype == DWG_TYPE_VERTEX_PFACE_FACE)                  \
1552
0
            {                                                                 \
1553
0
              error |= dwg_dxfb_VERTEX_PFACE_FACE (dat, o);                   \
1554
0
            }                                                                 \
1555
0
          else if (o && o->fixedtype == DWG_TYPE_VERTEX_##token)              \
1556
0
            {                                                                 \
1557
0
              error |= dwg_dxfb_VERTEX_##token (dat, o);                      \
1558
0
            }                                                                 \
1559
0
        }                                                                     \
1560
0
      o = _obj->seqend ? _obj->seqend->obj : NULL;                            \
1561
0
      if (o && o->fixedtype == DWG_TYPE_SEQEND)                               \
1562
0
        error |= dwg_dxfb_SEQEND (dat, o);                                    \
1563
0
      *i = *i + _obj->num_owned + 1;                                          \
1564
0
    }                                                                         \
1565
0
    return error;                                                             \
1566
0
  }
Unexecuted instantiation: out_dxfb.c:dxfb_process_VERTEX_2D
Unexecuted instantiation: out_dxfb.c:dxfb_process_VERTEX_3D
Unexecuted instantiation: out_dxfb.c:dxfb_process_VERTEX_PFACE
Unexecuted instantiation: out_dxfb.c:dxfb_process_VERTEX_MESH
1567
1568
// clang-format off
1569
decl_dxfb_process_VERTEX (2D)
1570
decl_dxfb_process_VERTEX (3D)
1571
decl_dxfb_process_VERTEX (MESH)
1572
decl_dxfb_process_VERTEX (PFACE)
1573
// clang-format on
1574
1575
/* process seqend before attribs */
1576
#define decl_dxfb_process_INSERT(token)                                       \
1577
  static int dxfb_process_##token (Bit_Chain *restrict dat,                   \
1578
                                   const Dwg_Object *restrict obj,            \
1579
                                   int *restrict i)                           \
1580
0
  {                                                                           \
1581
0
    int error = 0;                                                            \
1582
0
    Dwg_Entity_##token *_obj = obj->tio.entity->tio.token;                    \
1583
0
    if (!_obj->has_attribs)                                                   \
1584
0
      return 0;                                                               \
1585
0
                                                                              \
1586
0
    VERSIONS (R_13b1, R_2000)                                                 \
1587
0
    {                                                                         \
1588
0
      Dwg_Object *last_attrib                                                 \
1589
0
          = _obj->last_attrib ? _obj->last_attrib->obj : NULL;                \
1590
0
      Dwg_Object *o = _obj->first_attrib ? _obj->first_attrib->obj : NULL;    \
1591
0
      if (!o || !last_attrib)                                                 \
1592
0
        return DWG_ERR_INVALIDHANDLE;                                         \
1593
0
      if (o->fixedtype == DWG_TYPE_ATTRIB)                                    \
1594
0
        error |= dwg_dxfb_ATTRIB (dat, o);                                    \
1595
0
      *i = *i + 1;                                                            \
1596
0
      do                                                                      \
1597
0
        {                                                                     \
1598
0
          o = dwg_next_object (o);                                            \
1599
0
          if (!o)                                                             \
1600
0
            return DWG_ERR_INVALIDHANDLE;                                     \
1601
0
          if (o->fixedtype == DWG_TYPE_ATTRIB)                                \
1602
0
            error |= dwg_dxfb_ATTRIB (dat, o);                                \
1603
0
          *i = *i + 1;                                                        \
1604
0
        }                                                                     \
1605
0
      while (o->fixedtype == DWG_TYPE_ATTRIB && o != last_attrib);            \
1606
0
      o = _obj->seqend ? _obj->seqend->obj : NULL;                            \
1607
0
      if (o && o->fixedtype == DWG_TYPE_SEQEND)                               \
1608
0
        error |= dwg_dxfb_SEQEND (dat, o);                                    \
1609
0
      *i = *i + 1;                                                            \
1610
0
    }                                                                         \
1611
0
    SINCE (R_2004a)                                                           \
1612
0
    {                                                                         \
1613
0
      Dwg_Object *o;                                                          \
1614
0
      for (BITCODE_BL j = 0; j < _obj->num_owned; j++)                        \
1615
0
        {                                                                     \
1616
0
          o = _obj->attribs && _obj->attribs[j] ? _obj->attribs[j]->obj       \
1617
0
                                                : NULL;                       \
1618
0
          if (o && o->fixedtype == DWG_TYPE_ATTRIB)                           \
1619
0
            error |= dwg_dxfb_ATTRIB (dat, o);                                \
1620
0
        }                                                                     \
1621
0
      o = _obj->seqend ? _obj->seqend->obj : NULL;                            \
1622
0
      if (o && o->fixedtype == DWG_TYPE_SEQEND)                               \
1623
0
        error |= dwg_dxfb_SEQEND (dat, o);                                    \
1624
0
      *i = *i + _obj->num_owned + 1;                                          \
1625
0
    }                                                                         \
1626
0
    return error;                                                             \
1627
0
  }
Unexecuted instantiation: out_dxfb.c:dxfb_process_INSERT
Unexecuted instantiation: out_dxfb.c:dxfb_process_MINSERT
1628
1629
    // clang-format off
1630
decl_dxfb_process_INSERT (INSERT)
1631
decl_dxfb_process_INSERT (MINSERT)
1632
    // clang-format on
1633
1634
    static int dwg_dxfb_object (Bit_Chain *restrict dat,
1635
                                const Dwg_Object *restrict obj,
1636
                                int *restrict i)
1637
0
{
1638
0
  int error = 0;
1639
0
  int minimal;
1640
0
  unsigned int type;
1641
1642
0
  if (!obj || !obj->parent)
1643
0
    return DWG_ERR_INTERNALERROR;
1644
0
  minimal = obj->parent->opts & DWG_OPTS_MINIMAL;
1645
0
  if (dat->version < R_13b1)
1646
0
    type = (unsigned int)obj->fixedtype;
1647
0
  else
1648
0
    {
1649
0
      type = obj->type;
1650
0
      if (obj->fixedtype == DWG_TYPE_UNKNOWN_ENT)
1651
0
        type = DWG_TYPE_UNKNOWN_ENT;
1652
0
      if (obj->fixedtype == DWG_TYPE_UNKNOWN_OBJ)
1653
0
        type = DWG_TYPE_UNKNOWN_OBJ;
1654
0
    }
1655
1656
0
  switch (type)
1657
0
    {
1658
0
    case DWG_TYPE_TEXT:
1659
0
      return dwg_dxfb_TEXT (dat, obj);
1660
0
    case DWG_TYPE_ATTDEF:
1661
0
      return dwg_dxfb_ATTDEF (dat, obj);
1662
0
    case DWG_TYPE_BLOCK:
1663
0
      return dwg_dxfb_BLOCK (dat, obj);
1664
0
    case DWG_TYPE_ENDBLK:
1665
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1666
0
      return 0; // dwg_dxfb_ENDBLK(dat, obj);
1667
0
    case DWG_TYPE_SEQEND:
1668
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1669
0
      return 0; // dwg_dxfb_SEQEND(dat, obj);
1670
1671
0
    case DWG_TYPE_INSERT:
1672
0
      error = dwg_dxfb_INSERT (dat, obj);
1673
0
      return error | dxfb_process_INSERT (dat, obj, i);
1674
0
    case DWG_TYPE_MINSERT:
1675
0
      error = dwg_dxfb_MINSERT (dat, obj);
1676
0
      return error | dxfb_process_MINSERT (dat, obj, i);
1677
0
    case DWG_TYPE_POLYLINE_2D:
1678
0
      error = dwg_dxfb_POLYLINE_2D (dat, obj);
1679
0
      return error | dxfb_process_VERTEX_2D (dat, obj, i);
1680
0
    case DWG_TYPE_POLYLINE_3D:
1681
0
      error = dwg_dxfb_POLYLINE_3D (dat, obj);
1682
0
      return error | dxfb_process_VERTEX_3D (dat, obj, i);
1683
0
    case DWG_TYPE_POLYLINE_PFACE:
1684
0
      error = dwg_dxfb_POLYLINE_PFACE (dat, obj);
1685
0
      return error | dxfb_process_VERTEX_PFACE (dat, obj, i);
1686
0
    case DWG_TYPE_POLYLINE_MESH:
1687
0
      error = dwg_dxfb_POLYLINE_MESH (dat, obj);
1688
0
      return error | dxfb_process_VERTEX_MESH (dat, obj, i);
1689
1690
0
    case DWG_TYPE_ATTRIB:
1691
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1692
0
      return dwg_dxfb_ATTRIB (dat, obj);
1693
0
    case DWG_TYPE_VERTEX_2D:
1694
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1695
0
      return dwg_dxfb_VERTEX_2D (dat, obj);
1696
0
    case DWG_TYPE_VERTEX_3D:
1697
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1698
0
      return dwg_dxfb_VERTEX_3D (dat, obj);
1699
0
    case DWG_TYPE_VERTEX_MESH:
1700
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1701
0
      return dwg_dxfb_VERTEX_MESH (dat, obj);
1702
0
    case DWG_TYPE_VERTEX_PFACE:
1703
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1704
0
      return dwg_dxfb_VERTEX_PFACE (dat, obj);
1705
0
    case DWG_TYPE_VERTEX_PFACE_FACE:
1706
0
      LOG_WARN ("stale %s subentity", obj->dxfname);
1707
0
      return dwg_dxfb_VERTEX_PFACE_FACE (dat, obj);
1708
1709
0
    case DWG_TYPE_ARC:
1710
0
      return dwg_dxfb_ARC (dat, obj);
1711
0
    case DWG_TYPE_CIRCLE:
1712
0
      return dwg_dxfb_CIRCLE (dat, obj);
1713
0
    case DWG_TYPE_LINE:
1714
0
      return dwg_dxfb_LINE (dat, obj);
1715
0
    case DWG_TYPE_DIMENSION_ORDINATE:
1716
0
      return dwg_dxfb_DIMENSION_ORDINATE (dat, obj);
1717
0
    case DWG_TYPE_DIMENSION_LINEAR:
1718
0
      return dwg_dxfb_DIMENSION_LINEAR (dat, obj);
1719
0
    case DWG_TYPE_DIMENSION_ALIGNED:
1720
0
      return dwg_dxfb_DIMENSION_ALIGNED (dat, obj);
1721
0
    case DWG_TYPE_DIMENSION_ANG3PT:
1722
0
      return dwg_dxfb_DIMENSION_ANG3PT (dat, obj);
1723
0
    case DWG_TYPE_DIMENSION_ANG2LN:
1724
0
      return dwg_dxfb_DIMENSION_ANG2LN (dat, obj);
1725
0
    case DWG_TYPE_DIMENSION_RADIUS:
1726
0
      return dwg_dxfb_DIMENSION_RADIUS (dat, obj);
1727
0
    case DWG_TYPE_DIMENSION_DIAMETER:
1728
0
      return dwg_dxfb_DIMENSION_DIAMETER (dat, obj);
1729
0
    case DWG_TYPE_POINT:
1730
0
      return dwg_dxfb_POINT (dat, obj);
1731
0
    case DWG_TYPE__3DFACE:
1732
0
      return dwg_dxfb__3DFACE (dat, obj);
1733
0
    case DWG_TYPE_SOLID:
1734
0
      return dwg_dxfb_SOLID (dat, obj);
1735
0
    case DWG_TYPE_TRACE:
1736
0
      return dwg_dxfb_TRACE (dat, obj);
1737
0
    case DWG_TYPE_SHAPE:
1738
0
      return dwg_dxfb_SHAPE (dat, obj);
1739
0
    case DWG_TYPE_VIEWPORT:
1740
0
      return minimal ? 0 : dwg_dxfb_VIEWPORT (dat, obj);
1741
0
    case DWG_TYPE_ELLIPSE:
1742
0
      return dwg_dxfb_ELLIPSE (dat, obj);
1743
0
    case DWG_TYPE_SPLINE:
1744
0
      return dwg_dxfb_SPLINE (dat, obj);
1745
0
    case DWG_TYPE_REGION:
1746
0
      return dwg_dxfb_REGION (dat, obj);
1747
0
    case DWG_TYPE__3DSOLID:
1748
0
      return dwg_dxfb__3DSOLID (dat, obj);
1749
0
    case DWG_TYPE_BODY:
1750
0
      return dwg_dxfb_BODY (dat, obj);
1751
0
    case DWG_TYPE_RAY:
1752
0
      return dwg_dxfb_RAY (dat, obj);
1753
0
    case DWG_TYPE_XLINE:
1754
0
      return dwg_dxfb_XLINE (dat, obj);
1755
0
    case DWG_TYPE_DICTIONARY:
1756
0
      return minimal ? 0 : dwg_dxfb_DICTIONARY (dat, obj);
1757
0
    case DWG_TYPE_MTEXT:
1758
0
      return dwg_dxfb_MTEXT (dat, obj);
1759
0
    case DWG_TYPE_LEADER:
1760
0
      return dwg_dxfb_LEADER (dat, obj);
1761
0
    case DWG_TYPE_TOLERANCE:
1762
0
      return dwg_dxfb_TOLERANCE (dat, obj);
1763
0
    case DWG_TYPE_MLINE:
1764
0
      if (0)
1765
0
        {
1766
          // bypass -Wunused-function
1767
0
          dwg_dxfb_JUMP (dat, obj);
1768
0
          dwg_dxfb_LOAD (dat, obj);
1769
0
        }
1770
#ifdef DEBUG_CLASSES
1771
      // TODO: looks good, but acad import crashes
1772
      return dwg_dxfb_MLINE (dat, obj);
1773
#else
1774
0
      LOG_WARN ("Unhandled Entity MLINE in out_dxfb %u/" FMT_H, obj->index,
1775
0
                obj->handle.value)
1776
0
      if (0)
1777
        // bypass -Wunused-function
1778
0
        dwg_dxfb_MLINE (dat, obj);
1779
0
      return DWG_ERR_UNHANDLEDCLASS;
1780
0
#endif
1781
0
    case DWG_TYPE_BLOCK_CONTROL:
1782
0
    case DWG_TYPE_BLOCK_HEADER:
1783
0
    case DWG_TYPE_LAYER_CONTROL:
1784
0
    case DWG_TYPE_LAYER:
1785
0
    case DWG_TYPE_STYLE_CONTROL:
1786
0
    case DWG_TYPE_STYLE:
1787
0
    case DWG_TYPE_LTYPE_CONTROL:
1788
0
    case DWG_TYPE_LTYPE:
1789
0
    case DWG_TYPE_VIEW_CONTROL:
1790
0
    case DWG_TYPE_VIEW:
1791
0
    case DWG_TYPE_UCS_CONTROL:
1792
0
    case DWG_TYPE_UCS:
1793
0
    case DWG_TYPE_VPORT_CONTROL:
1794
0
    case DWG_TYPE_VPORT:
1795
0
    case DWG_TYPE_APPID_CONTROL:
1796
0
    case DWG_TYPE_APPID:
1797
0
    case DWG_TYPE_DIMSTYLE_CONTROL:
1798
0
    case DWG_TYPE_DIMSTYLE:
1799
0
    case DWG_TYPE_VX_CONTROL:
1800
    /* no dxf */
1801
0
    case DWG_TYPE_VX_TABLE_RECORD:
1802
    /* preR13: no dxfb */
1803
0
    case DWG_TYPE_REPEAT:
1804
0
    case DWG_TYPE_ENDREP:
1805
0
    case DWG_TYPE__3DLINE:
1806
0
    case DWG_TYPE_LOAD:
1807
0
    case DWG_TYPE_JUMP:
1808
0
      LOG_INFO ("Skip unsupported object %s\n", obj->name);
1809
0
      break;
1810
1811
0
    case DWG_TYPE_GROUP:
1812
0
      return dwg_dxfb_GROUP (dat, obj);
1813
0
    case DWG_TYPE_MLINESTYLE:
1814
0
      return minimal ? 0 : dwg_dxfb_MLINESTYLE (dat, obj);
1815
0
    case DWG_TYPE_OLE2FRAME:
1816
0
      return minimal ? 0 : dwg_dxfb_OLE2FRAME (dat, obj);
1817
0
    case DWG_TYPE_DUMMY:
1818
0
      return 0;
1819
0
    case DWG_TYPE_LONG_TRANSACTION:
1820
0
      return minimal ? 0 : dwg_dxfb_LONG_TRANSACTION (dat, obj);
1821
0
    case DWG_TYPE_LWPOLYLINE:
1822
0
      return dwg_dxfb_LWPOLYLINE (dat, obj);
1823
0
    case DWG_TYPE_HATCH:
1824
0
      return dwg_dxfb_HATCH (dat, obj);
1825
0
    case DWG_TYPE_XRECORD:
1826
0
      return minimal ? 0 : dwg_dxfb_XRECORD (dat, obj);
1827
0
    case DWG_TYPE_PLACEHOLDER:
1828
0
      return minimal ? 0 : dwg_dxfb_PLACEHOLDER (dat, obj);
1829
0
    case DWG_TYPE_PROXY_ENTITY:
1830
0
      return minimal ? 0 : dwg_dxfb_PROXY_ENTITY (dat, obj);
1831
0
    case DWG_TYPE_OLEFRAME:
1832
0
      return minimal ? 0 : dwg_dxfb_OLEFRAME (dat, obj);
1833
0
    case DWG_TYPE_VBA_PROJECT:
1834
0
      if (!minimal)
1835
0
        {
1836
0
          LOG_ERROR ("Unhandled Object VBA_PROJECT");
1837
          // dwg_dxfb_VBA_PROJECT(dat, obj);
1838
0
          return DWG_ERR_UNHANDLEDCLASS;
1839
0
        }
1840
0
      return 0;
1841
0
    case DWG_TYPE_LAYOUT:
1842
0
      return minimal ? 0 : dwg_dxfb_LAYOUT (dat, obj);
1843
0
    default:
1844
0
      if (obj->type == obj->parent->layout_type)
1845
0
        {
1846
0
          return minimal ? 0 : dwg_dxfb_LAYOUT (dat, obj);
1847
0
        }
1848
      /* > 500 */
1849
0
      else if (DWG_ERR_UNHANDLEDCLASS
1850
0
               & (error = dwg_dxfb_variable_type (obj->parent, dat,
1851
0
                                                  (Dwg_Object *)obj)))
1852
0
        {
1853
0
          Dwg_Data *dwg = obj->parent;
1854
0
          int j = obj->type - 500;
1855
0
          Dwg_Class *klass = NULL;
1856
1857
0
          if (j >= 0 && j < (int)dwg->num_classes
1858
0
              && obj->fixedtype < DWG_TYPE_FREED)
1859
0
            klass = &dwg->dwg_class[j];
1860
0
          if (!klass)
1861
0
            {
1862
0
              LOG_WARN ("Unknown object, skipping eed/reactors/xdic");
1863
0
              return DWG_ERR_INVALIDTYPE;
1864
0
            }
1865
0
          return error;
1866
0
        }
1867
0
    }
1868
0
  return DWG_ERR_UNHANDLEDCLASS;
1869
0
}
1870
1871
static int
1872
dxfb_common_entity_handle_data (Bit_Chain *restrict dat,
1873
                                const Dwg_Object *restrict obj)
1874
0
{
1875
0
  const Dwg_Data *dwg = obj->parent;
1876
0
  const Dwg_Object_Entity *_ent = obj->tio.entity;
1877
0
  const Dwg_Object_Entity *_obj = _ent;
1878
0
  int error = 0;
1879
0
  BITCODE_BL vcount = 0;
1880
1881
  // clang-format off
1882
0
  if (dat->version >= R_13b1)
1883
0
    {
1884
0
      #include "common_entity_handle_data.spec"
1885
0
    }
1886
0
  #include "common_entity_data.spec"
1887
  // clang-format on
1888
1889
0
  return error;
1890
0
}
1891
1892
// see
1893
// https://www.autodesk.com/techpubs/autocad/acad2000/dxf/header_section_group_codes_dxf_02.htm
1894
AFL_GCC_TOOBIG
1895
static int
1896
dxfb_header_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
1897
0
{
1898
0
  Dwg_Header_Variables *_obj = &dwg->header_vars;
1899
0
  Dwg_Object *obj = NULL;
1900
0
  double ms;
1901
0
  const int minimal = dwg->opts & DWG_OPTS_MINIMAL;
1902
0
  const char *codepage = dxf_codepage (dwg->header.codepage, dwg);
1903
1904
0
  if (dwg->header.codepage != 30 && dwg->header.codepage != 29
1905
0
      && dwg->header.codepage != 0 && dwg->header.version < R_2007)
1906
0
    {
1907
      // some asian or eastern-european codepage
1908
      // see
1909
      // https://github.com/mozman/ezdxf/blob/master/docs/source/dxfinternals/fileencoding.rst
1910
0
      LOG_WARN ("Unknown codepage %d, assuming ANSI_1252",
1911
0
                dwg->header.codepage);
1912
0
    }
1913
1914
    // clang-format off
1915
0
  #include "header_variables_dxf.spec"
1916
  // clang-format on
1917
1918
0
  return 0;
1919
0
}
1920
AFL_GCC_POP
1921
1922
static int
1923
dxfb_classes_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
1924
0
{
1925
0
  BITCODE_BS j;
1926
1927
0
  SECTION (CLASSES);
1928
0
  LOG_TRACE ("num_classes: %u\n", dwg->num_classes);
1929
0
  for (j = 0; j < dwg->num_classes; j++)
1930
0
    {
1931
0
      const char *dxfname = dwg->dwg_class[j].dxfname;
1932
0
      if (!dxfname)
1933
0
        continue;
1934
      // some classes are now builtin
1935
0
      if (dat->version >= R_2004
1936
0
          && (strEQc (dxfname, "ACDBPLACEHOLDER")
1937
0
              || strEQc (dxfname, "LAYOUT")))
1938
0
        continue;
1939
0
      if (strEQc (dxfname, "DATATABLE"))
1940
0
        dxfname = "ACDBDATATABLE";
1941
0
      RECORD (CLASS);
1942
0
      VALUE_TV (dxfname, 1);
1943
0
      VALUE_T (dwg->dwg_class[j].cppname, 2);
1944
0
      if (strEQc (dxfname, "SPATIAL_INDEX"))
1945
0
        VALUE_TFF ("AutoCAD 2000", 3)
1946
0
      else
1947
0
        VALUE_T (dwg->dwg_class[j].appname, 3)
1948
0
      VALUE_RL (dwg->dwg_class[j].proxyflag, 90);
1949
0
      SINCE (R_2004a)
1950
0
      {
1951
0
        VALUE_RL (dwg->dwg_class[j].num_instances, 91);
1952
0
      }
1953
0
      VALUE_RS (dwg->dwg_class[j].is_zombie, 280); // acad: was-a-zombie
1954
      // Is-an-entity. 1f2 for entities, 1f3 for objects
1955
0
      VALUE_RS (dwg->dwg_class[j].item_class_id == 0x1F2 ? 1 : 0, 281);
1956
0
    }
1957
0
  ENDSEC ();
1958
0
  return 0;
1959
0
}
1960
1961
static int
1962
dxfb_tables_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
1963
0
{
1964
0
  int error = 0;
1965
0
  unsigned int i;
1966
1967
0
  SECTION (TABLES);
1968
0
  SINCE (R_9c1)
1969
0
  {
1970
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_VPORT_CONTROL);
1971
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.VPORT_CONTROL)
1972
0
      {
1973
0
        Dwg_Object *obj = ctrl;
1974
0
        Dwg_Object_VPORT_CONTROL *_ctrl = ctrl->tio.object->tio.VPORT_CONTROL;
1975
0
        TABLE (VPORT);
1976
        // add handle 5 here at first
1977
0
        COMMON_TABLE_CONTROL_FLAGS;
1978
0
        error |= dwg_dxfb_VPORT_CONTROL (dat, ctrl);
1979
        // TODO how far back can DXF read 1000?
1980
0
        if (dat->version != dat->from_version && dat->from_version >= R_2000)
1981
0
          {
1982
            /* if saved from newer version, eg. AC1032: */
1983
0
            VALUE_TV ("ACAD", 1001);
1984
0
            VALUE_TV ("DbSaveVer", 1000);
1985
0
            VALUE_RS (dwg->header.dwg_version, 1071); // so that 69 is R_2018
1986
0
          }
1987
0
        for (i = 0; i < _ctrl->num_entries; i++)
1988
0
          {
1989
0
            if (!_ctrl->entries)
1990
0
              break;
1991
0
            if (!_ctrl->entries[i])
1992
0
              continue;
1993
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
1994
0
            if (obj && obj->type == DWG_TYPE_VPORT)
1995
0
              {
1996
                // reordered in the DXF: 2,70,10,11,12,13,14,15,16,...
1997
                // special-cased in the spec
1998
0
                error |= dwg_dxfb_VPORT (dat, obj);
1999
0
              }
2000
0
          }
2001
0
        ENDTAB ();
2002
0
      }
2003
0
  }
2004
0
  {
2005
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_LTYPE_CONTROL);
2006
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.LTYPE_CONTROL)
2007
0
      {
2008
0
        Dwg_Object *obj = ctrl;
2009
0
        Dwg_Object_LTYPE_CONTROL *_ctrl = ctrl->tio.object->tio.LTYPE_CONTROL;
2010
0
        TABLE (LTYPE);
2011
0
        COMMON_TABLE_CONTROL_FLAGS;
2012
0
        error |= dwg_dxfb_LTYPE_CONTROL (dat, ctrl);
2013
        // first the 2 builtin ltypes: ByBlock, ByLayer
2014
0
        if ((obj = dwg_ref_object (dwg, dwg->header_vars.LTYPE_BYBLOCK)))
2015
0
          {
2016
0
            dwg_dxfb_LTYPE (dat, obj);
2017
0
          }
2018
0
        if ((obj = dwg_ref_object (dwg, dwg->header_vars.LTYPE_BYLAYER)))
2019
0
          {
2020
0
            error |= dwg_dxfb_LTYPE (dat, obj);
2021
0
          }
2022
        // here LTYPE_CONTINUOUS is already included
2023
0
        for (i = 0; i < _ctrl->num_entries; i++)
2024
0
          {
2025
0
            if (!_ctrl->entries)
2026
0
              break;
2027
0
            if (!_ctrl->entries[i])
2028
0
              continue;
2029
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2030
0
            if (obj && obj->type == DWG_TYPE_LTYPE)
2031
0
              {
2032
0
                error |= dwg_dxfb_LTYPE (dat, obj);
2033
0
              }
2034
0
          }
2035
0
        ENDTAB ();
2036
0
      }
2037
0
  }
2038
0
  {
2039
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_LAYER_CONTROL);
2040
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.LAYER_CONTROL)
2041
0
      {
2042
0
        Dwg_Object *obj = ctrl;
2043
0
        Dwg_Object_LAYER_CONTROL *_ctrl = ctrl->tio.object->tio.LAYER_CONTROL;
2044
0
        TABLE (LAYER);
2045
0
        COMMON_TABLE_CONTROL_FLAGS;
2046
0
        error |= dwg_dxfb_LAYER_CONTROL (dat, ctrl);
2047
0
        for (i = 0; i < _ctrl->num_entries; i++)
2048
0
          {
2049
0
            if (!_ctrl->entries)
2050
0
              break;
2051
0
            if (!_ctrl->entries[i])
2052
0
              continue;
2053
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2054
0
            if (obj && obj->type == DWG_TYPE_LAYER)
2055
0
              {
2056
0
                error |= dwg_dxfb_LAYER (dat, obj);
2057
                // else if (obj && obj->type == DWG_TYPE_DICTIONARY)
2058
                //  error |= dwg_dxfb_DICTIONARY(dat, obj);
2059
0
              }
2060
0
          }
2061
0
        ENDTAB ();
2062
0
      }
2063
0
  }
2064
0
  {
2065
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_STYLE_CONTROL);
2066
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.STYLE_CONTROL)
2067
0
      {
2068
0
        Dwg_Object *obj = ctrl;
2069
0
        Dwg_Object_STYLE_CONTROL *_ctrl = ctrl->tio.object->tio.STYLE_CONTROL;
2070
0
        TABLE (STYLE);
2071
0
        COMMON_TABLE_CONTROL_FLAGS;
2072
0
        error |= dwg_dxfb_STYLE_CONTROL (dat, ctrl);
2073
0
        for (i = 0; i < _ctrl->num_entries; i++)
2074
0
          {
2075
0
            if (!_ctrl->entries)
2076
0
              break;
2077
0
            if (!_ctrl->entries[i])
2078
0
              continue;
2079
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2080
0
            if (obj && obj->type == DWG_TYPE_STYLE)
2081
0
              {
2082
0
                error |= dwg_dxfb_STYLE (dat, obj);
2083
0
              }
2084
0
          }
2085
0
        ENDTAB ();
2086
0
      }
2087
0
  }
2088
0
  {
2089
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_VIEW_CONTROL);
2090
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.VIEW_CONTROL)
2091
0
      {
2092
0
        Dwg_Object *obj = ctrl;
2093
0
        Dwg_Object_VIEW_CONTROL *_ctrl = ctrl->tio.object->tio.VIEW_CONTROL;
2094
0
        TABLE (VIEW);
2095
0
        COMMON_TABLE_CONTROL_FLAGS;
2096
0
        error |= dwg_dxfb_VIEW_CONTROL (dat, ctrl);
2097
0
        for (i = 0; i < _ctrl->num_entries; i++)
2098
0
          {
2099
0
            if (!_ctrl->entries)
2100
0
              break;
2101
0
            if (!_ctrl->entries[i])
2102
0
              continue;
2103
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2104
0
            if (obj && obj->type == DWG_TYPE_VIEW)
2105
0
              error |= dwg_dxfb_VIEW (dat, obj);
2106
0
          }
2107
0
        ENDTAB ();
2108
0
      }
2109
0
  }
2110
0
  SINCE (R_9c1)
2111
0
  {
2112
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_UCS_CONTROL);
2113
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.UCS_CONTROL)
2114
0
      {
2115
0
        Dwg_Object *obj = ctrl;
2116
0
        Dwg_Object_UCS_CONTROL *_ctrl = ctrl->tio.object->tio.UCS_CONTROL;
2117
0
        TABLE (UCS);
2118
0
        COMMON_TABLE_CONTROL_FLAGS;
2119
0
        error |= dwg_dxfb_UCS_CONTROL (dat, ctrl);
2120
0
        for (i = 0; i < _ctrl->num_entries; i++)
2121
0
          {
2122
0
            if (!_ctrl->entries)
2123
0
              break;
2124
0
            if (!_ctrl->entries[i])
2125
0
              continue;
2126
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2127
0
            if (obj && obj->type == DWG_TYPE_UCS)
2128
0
              {
2129
0
                error |= dwg_dxfb_UCS (dat, obj);
2130
0
              }
2131
0
          }
2132
0
        ENDTAB ();
2133
0
      }
2134
0
  }
2135
0
  SINCE (R_11b1)
2136
0
  {
2137
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_APPID_CONTROL);
2138
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.APPID_CONTROL)
2139
0
      {
2140
0
        Dwg_Object *obj = ctrl;
2141
0
        Dwg_Object_APPID_CONTROL *_ctrl = ctrl->tio.object->tio.APPID_CONTROL;
2142
0
        TABLE (APPID);
2143
0
        COMMON_TABLE_CONTROL_FLAGS;
2144
0
        error |= dwg_dxfb_APPID_CONTROL (dat, ctrl);
2145
0
        for (i = 0; i < _ctrl->num_entries; i++)
2146
0
          {
2147
0
            if (!_ctrl->entries)
2148
0
              break;
2149
0
            if (!_ctrl->entries[i])
2150
0
              continue;
2151
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2152
0
            if (obj && obj->type == DWG_TYPE_APPID)
2153
0
              {
2154
0
                error |= dwg_dxfb_APPID (dat, obj);
2155
0
              }
2156
0
          }
2157
0
        ENDTAB ();
2158
0
      }
2159
0
  }
2160
0
  SINCE (R_11b1)
2161
0
  {
2162
0
    Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_DIMSTYLE_CONTROL);
2163
0
    if (ctrl && ctrl->tio.object && ctrl->tio.object->tio.DIMSTYLE_CONTROL)
2164
0
      {
2165
0
        Dwg_Object *obj = ctrl;
2166
0
        Dwg_Object_DIMSTYLE_CONTROL *_ctrl
2167
0
            = ctrl->tio.object->tio.DIMSTYLE_CONTROL;
2168
0
        TABLE (DIMSTYLE);
2169
0
        COMMON_TABLE_CONTROL_FLAGS;
2170
0
        dwg_dxfb_DIMSTYLE_CONTROL (dat, ctrl);
2171
        // ignoring morehandles
2172
0
        for (i = 0; i < _ctrl->num_entries; i++)
2173
0
          {
2174
0
            if (!_ctrl->entries)
2175
0
              break;
2176
0
            if (!_ctrl->entries[i])
2177
0
              continue;
2178
0
            obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2179
0
            if (obj && obj->type == DWG_TYPE_DIMSTYLE)
2180
0
              {
2181
0
                error |= dwg_dxfb_DIMSTYLE (dat, obj);
2182
0
              }
2183
0
          }
2184
0
        ENDTAB ();
2185
0
      }
2186
0
  }
2187
  // fool the warnings. this table is nowhere to be found in the wild. maybe
2188
  // pre-R11
2189
0
  if (0)
2190
0
    {
2191
0
      Dwg_Object *ctrl = dwg_get_first_object (dwg, DWG_TYPE_VX_CONTROL);
2192
0
      Dwg_Object_VX_CONTROL *_ctrl = ctrl->tio.object->tio.VX_CONTROL;
2193
0
      if (ctrl && ctrl->fixedtype == DWG_TYPE_VX_CONTROL)
2194
0
        {
2195
0
          Dwg_Object *obj = ctrl;
2196
0
          TABLE (VX_TABLE_RECORD);
2197
0
          COMMON_TABLE_CONTROL_FLAGS;
2198
0
          error |= dwg_dxfb_VX_CONTROL (dat, ctrl);
2199
0
          for (i = 0; i < _ctrl->num_entries; i++)
2200
0
            {
2201
0
              if (!_ctrl->entries)
2202
0
                break;
2203
0
              if (!_ctrl->entries[i])
2204
0
                continue;
2205
0
              obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2206
0
              if (obj && obj->type == DWG_TYPE_VX_TABLE_RECORD)
2207
0
                {
2208
0
                  RECORD (VX_TABLE_RECORD);
2209
0
                  error |= dwg_dxfb_VX_TABLE_RECORD (dat, obj);
2210
0
                }
2211
0
            }
2212
0
          ENDTAB ();
2213
0
        }
2214
0
    }
2215
0
  SINCE (R_12)
2216
0
  {
2217
0
    Dwg_Object *ctrl, *obj;
2218
0
    Dwg_Object_BLOCK_CONTROL *_ctrl = dwg_block_control (dwg);
2219
0
    Dwg_Object_Ref *ref;
2220
0
    Dwg_Object *mspace = NULL, *pspace = NULL;
2221
0
    if (!_ctrl)
2222
0
      {
2223
0
        LOG_ERROR ("BLOCK_CONTROL missing");
2224
0
        return DWG_ERR_INVALIDDWG;
2225
0
      }
2226
0
    ctrl = dwg_obj_generic_to_object (_ctrl, &error);
2227
0
    if (!ctrl || ctrl->fixedtype != DWG_TYPE_BLOCK_CONTROL)
2228
0
      return DWG_ERR_INVALIDDWG;
2229
2230
0
    obj = ctrl;
2231
0
    TABLE (BLOCK_RECORD);
2232
0
    COMMON_TABLE_CONTROL_FLAGS;
2233
0
    error |= dwg_dxfb_BLOCK_CONTROL (dat, ctrl);
2234
2235
#if 0
2236
    for (i = 0; i < dwg->num_objects; i++)
2237
      {
2238
        Dwg_Object *hdr = &dwg->object[i];
2239
        if (hdr && hdr->supertype == DWG_SUPERTYPE_OBJECT
2240
            && hdr->type == DWG_TYPE_BLOCK_HEADER)
2241
          {
2242
            RECORD (BLOCK_RECORD);
2243
            error |= dwg_dxfb_BLOCK_HEADER (dat, hdr);
2244
          }
2245
      }
2246
#else
2247
0
    mspace = dwg_model_space_object (dwg);
2248
0
    if (!mspace)
2249
0
      return DWG_ERR_INVALIDDWG;
2250
0
    RECORD (BLOCK_RECORD);
2251
0
    error |= dwg_dxfb_BLOCK_HEADER (dat, mspace);
2252
2253
0
    ref = dwg_paper_space_ref (dwg);
2254
0
    pspace = ref ? dwg_ref_object (dwg, ref) : NULL;
2255
0
    if (pspace)
2256
0
      {
2257
0
        RECORD (BLOCK_RECORD);
2258
0
        error |= dwg_dxfb_BLOCK_HEADER (dat, pspace);
2259
0
      }
2260
2261
0
    for (i = 0; i < _ctrl->num_entries; i++)
2262
0
      {
2263
0
        if (!_ctrl->entries)
2264
0
          break;
2265
0
        if (!_ctrl->entries[i])
2266
0
          continue;
2267
0
        obj = dwg_ref_object (dwg, _ctrl->entries[i]);
2268
0
        if (obj && obj->type == DWG_TYPE_BLOCK_HEADER && obj != mspace
2269
0
            && obj != pspace)
2270
0
          {
2271
0
            RECORD (BLOCK_RECORD);
2272
0
            error |= dwg_dxfb_BLOCK_HEADER (dat, obj);
2273
0
          }
2274
0
      }
2275
0
#endif
2276
2277
0
    ENDTAB ();
2278
0
  }
2279
2280
0
  ENDSEC ();
2281
0
  return 0;
2282
0
}
2283
2284
static void
2285
dxfb_ENDBLK_empty (Bit_Chain *restrict dat, const Dwg_Object *restrict hdr)
2286
0
{
2287
0
  Dwg_Object *obj = (Dwg_Object *)calloc (1, sizeof (Dwg_Object));
2288
0
  obj->parent = hdr->parent;
2289
0
  obj->index = obj->parent->num_objects;
2290
0
  dwg_setup_ENDBLK (obj);
2291
0
  obj->tio.entity->ownerhandle
2292
0
      = (Dwg_Object_Ref *)calloc (1, sizeof (Dwg_Object_Ref));
2293
0
  obj->tio.entity->ownerhandle->obj = (Dwg_Object *)hdr;
2294
0
  obj->tio.entity->ownerhandle->handleref = hdr->handle;
2295
0
  obj->tio.entity->ownerhandle->absolute_ref = hdr->handle.value;
2296
0
  dwg_dxfb_ENDBLK (dat, obj);
2297
0
  free (obj->tio.entity->tio.ENDBLK);
2298
0
  free (obj->tio.entity->ownerhandle);
2299
0
  free (obj->tio.entity);
2300
0
  free (obj);
2301
0
}
2302
2303
static int
2304
dxfb_block_write (Bit_Chain *restrict dat, const Dwg_Object *restrict hdr,
2305
                  const Dwg_Object *restrict mspace,
2306
                  const Dwg_Object *restrict pspace, int *restrict i)
2307
0
{
2308
0
  int error = 0;
2309
0
  Dwg_Object *restrict obj = get_first_owned_block (hdr); // BLOCK
2310
0
  const Dwg_Object_BLOCK_HEADER *restrict _hdr
2311
0
      = hdr->tio.object->tio.BLOCK_HEADER;
2312
0
  Dwg_Object *restrict endblk;
2313
0
  Dwg_Data *dwg = hdr->parent;
2314
0
  BITCODE_RLL mspace_ref = mspace ? mspace->handle.value : 0;
2315
0
  BITCODE_RLL pspace_ref = pspace ? pspace->handle.value : 0;
2316
2317
0
  if (obj)
2318
0
    error |= dwg_dxfb_object (dat, obj, i);
2319
0
  else
2320
0
    {
2321
0
      LOG_ERROR ("BLOCK_HEADER.block_entity missing");
2322
0
      return DWG_ERR_INVALIDDWG;
2323
0
    }
2324
  // Skip all *Model_Space and *Paper_Space entities, esp. new ones: UNDERLAY,
2325
  // MULTILEADER, ... They are all under ENTITIES later. Note: the objects may
2326
  // vary (e.g. example_2000), but the index not
2327
0
  if ((hdr == mspace) || (hdr->index == mspace->index))
2328
0
    obj = NULL;
2329
0
  else if ((hdr == pspace) || (pspace && hdr->index == pspace->index))
2330
0
    obj = NULL;
2331
0
  else
2332
0
    obj = get_first_owned_entity (hdr); // first_entity
2333
0
  while (obj)
2334
0
    {
2335
0
      if (obj->supertype == DWG_SUPERTYPE_ENTITY
2336
0
          && obj->fixedtype != DWG_TYPE_ENDBLK && obj->tio.entity != NULL
2337
0
          && (obj->tio.entity->entmode != 2
2338
0
              || (obj->tio.entity->ownerhandle != NULL
2339
0
                  && obj->tio.entity->ownerhandle->absolute_ref != mspace_ref
2340
0
                  && obj->tio.entity->ownerhandle->absolute_ref
2341
0
                         != pspace_ref)))
2342
0
        error |= dwg_dxfb_object (dat, obj, i);
2343
0
      obj = get_next_owned_entity (hdr, obj); // until last_entity
2344
0
    }
2345
0
  endblk = get_last_owned_block (hdr);
2346
0
  if (endblk)
2347
0
    error |= dwg_dxfb_ENDBLK (dat, endblk);
2348
0
  else
2349
0
    {
2350
0
      LOG_WARN ("Empty ENDBLK for \"%s\" " FORMAT_BL, _hdr->name,
2351
0
                hdr ? hdr->tio.object->objid : 0);
2352
0
      dxfb_ENDBLK_empty (dat, hdr);
2353
0
    }
2354
0
  return error;
2355
0
}
2356
2357
static int
2358
dxfb_blocks_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2359
0
{
2360
0
  int error = 0;
2361
0
  int i = 0;
2362
0
  Dwg_Object *restrict mspace = dwg_model_space_object (dwg);
2363
0
  Dwg_Object *restrict pspace = dwg_paper_space_object (dwg);
2364
2365
0
  if (!mspace)
2366
0
    return DWG_ERR_UNHANDLEDCLASS;
2367
2368
0
  SECTION (BLOCKS);
2369
  /* There may be unconnected blocks (not caught by above),
2370
     such as pspace referred by a LAYOUT or DIMENSION, so for simplicity just
2371
     scan all BLOCK_HEADER's and just skip *Model_Space and *Paper_Space.
2372
     pspace might be NULL.
2373
   */
2374
0
  {
2375
0
    for (i = 0; (BITCODE_BL)i < dwg->num_objects; i++)
2376
0
      {
2377
0
        const Dwg_Object *restrict obj = &dwg->object[i];
2378
0
        if (obj->supertype == DWG_SUPERTYPE_OBJECT
2379
0
            && obj->type == DWG_TYPE_BLOCK_HEADER)
2380
0
          {
2381
0
            error |= dxfb_block_write (dat, obj, mspace, pspace, &i);
2382
0
          }
2383
0
      }
2384
0
  }
2385
2386
0
  ENDSEC ();
2387
0
  return error;
2388
0
}
2389
2390
static int
2391
dxfb_entities_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2392
0
{
2393
0
  int error = 0;
2394
0
  Dwg_Object *restrict ms = dwg_model_space_object (dwg);
2395
0
  Dwg_Object *restrict ps = dwg_paper_space_object (dwg);
2396
0
  Dwg_Object *obj;
2397
0
  if (!ms)
2398
0
    return DWG_ERR_INVALIDDWG;
2399
2400
0
  SECTION (ENTITIES);
2401
  // First mspace
2402
0
  obj = get_first_owned_entity (ms); // first_entity or entities[0]
2403
0
  while (obj)
2404
0
    {
2405
0
      int i = obj->index;
2406
0
      error |= dwg_dxfb_object (dat, obj, &i);
2407
0
      obj = get_next_owned_block_entity (ms, obj); // until last_entity
2408
0
    }
2409
  // Then all pspace entities. just filter out other BLOCKS entities
2410
0
  if (ps)
2411
0
    {
2412
0
      obj = get_first_owned_entity (ps);
2413
0
      while (obj)
2414
0
        {
2415
0
          int i = obj->index;
2416
0
          error |= dwg_dxfb_object (dat, obj, &i);
2417
0
          obj = get_next_owned_block_entity (ps, obj);
2418
0
        }
2419
0
    }
2420
0
  ENDSEC ();
2421
0
  return error;
2422
0
}
2423
2424
static int
2425
dxfb_objects_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2426
0
{
2427
0
  int error = 0;
2428
0
  int i = 0;
2429
0
  Dwg_Object *nod;
2430
2431
0
  SECTION (OBJECTS);
2432
  // The NOD (Named Object Dict) must be always the very first OBJECT,
2433
  // not just DICTIONARY.
2434
0
  nod = dwg_get_first_object (dwg, DWG_TYPE_DICTIONARY);
2435
0
  if (nod)
2436
0
    error |= dwg_dxfb_object (dat, nod, &i);
2437
0
  for (i = 0; (BITCODE_BL)i < dwg->num_objects; i++)
2438
0
    {
2439
0
      const Dwg_Object *restrict obj = &dwg->object[i];
2440
0
      if (obj == nod)
2441
0
        continue;
2442
0
      if (obj->supertype == DWG_SUPERTYPE_OBJECT
2443
0
          && obj->type != DWG_TYPE_BLOCK_HEADER && !dwg_obj_is_control (obj))
2444
0
        error |= dwg_dxfb_object (dat, obj, &i);
2445
0
    }
2446
0
  ENDSEC ();
2447
0
  return error;
2448
0
}
2449
2450
static int
2451
dxfb_thumbnail_write (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2452
0
{
2453
0
  Bit_Chain *pic = (Bit_Chain *)&dwg->thumbnail;
2454
0
  if (pic->chain && pic->size && pic->size > 10)
2455
0
    {
2456
0
      SECTION (THUMBNAILIMAGE);
2457
0
      VALUE_RL (pic->size, 90);
2458
0
      VALUE_BINARY (pic->chain, pic->size, 310);
2459
0
      ENDSEC ();
2460
0
    }
2461
0
  return 0;
2462
0
}
2463
2464
int
2465
dwg_write_dxfb (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2466
0
{
2467
0
  int error = 0;
2468
0
  const int minimal = dwg->opts & DWG_OPTS_MINIMAL;
2469
2470
0
  loglevel = dwg->opts & DWG_OPTS_LOGLEVEL;
2471
0
  if (dat->from_version == R_INVALID)
2472
0
    dat->from_version = dat->version;
2473
0
  if (dwg->header.version <= R_2000 && dwg->header.from_version > R_2000)
2474
0
    dwg_fixup_BLOCKS_entities (dwg);
2475
0
  dwg_resolve_objectrefs_silent (dwg);
2476
2477
0
  fprintf (dat->fh, "AutoCAD Binary DXF\r\n%c%c", 0x1a, 0);
2478
  // VALUE_TV (PACKAGE_STRING, 999); // not used in binary DXF
2479
2480
  // a minimal header requires only $ACADVER, $HANDSEED, and then ENTITIES
2481
  // see https://pythonhosted.org/ezdxf/dxfinternals/filestructure.html
2482
0
  dxfb_header_write (dat, dwg);
2483
2484
0
  if (!minimal)
2485
0
    {
2486
      // if downgraded to r13, but we still have classes, keep the
2487
      // classes
2488
0
      if ((dat->from_version >= R_13b1 && dwg->num_classes)
2489
0
          || dat->version >= R_2000)
2490
0
        {
2491
0
          if (dxfb_classes_write (dat, dwg) >= DWG_ERR_CRITICAL)
2492
0
            goto fail;
2493
0
        }
2494
2495
0
      if (dxfb_tables_write (dat, dwg) >= DWG_ERR_CRITICAL)
2496
0
        goto fail;
2497
2498
0
      if (dxfb_blocks_write (dat, dwg) >= DWG_ERR_CRITICAL)
2499
0
        goto fail;
2500
0
    }
2501
2502
0
  if (dxfb_entities_write (dat, dwg) >= DWG_ERR_CRITICAL)
2503
0
    goto fail;
2504
2505
0
  if (!minimal)
2506
0
    {
2507
0
      SINCE (R_13b1)
2508
0
      {
2509
0
        if (dxfb_objects_write (dat, dwg) >= DWG_ERR_CRITICAL)
2510
0
          goto fail;
2511
0
      }
2512
0
      SINCE (R_2000b)
2513
0
      {
2514
0
        if (dxfb_thumbnail_write (dat, dwg) >= DWG_ERR_CRITICAL)
2515
0
          goto fail;
2516
0
      }
2517
0
    }
2518
0
  RECORD (EOF);
2519
2520
0
  return 0;
2521
0
fail:
2522
0
  return 1;
2523
0
}
2524
2525
#undef IS_PRINT
2526
#undef IS_DXF