Bug Summary

File:libraries/libdxfrw/src/drw_header.cpp
Warning:line 2572, column 19
Value stored to 'sz' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name drw_header.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -fcoverage-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -resource-dir /usr/lib/llvm-21/lib/clang/21 -D _REENTRANT -D MUPARSER_STATIC -D QT_NO_DEBUG -I . -I ../../../Qt/6.9.0/gcc_64/mkspecs/linux-g++ -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/x86_64-linux-gnu/c++/15 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu++1z -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/runner/work/LibreCAD/LibreCAD/out/2026-11-06-031751-4837-1 -x c++ src/drw_header.cpp
1/******************************************************************************
2** libDXFrw - Library to read/write DXF files (ascii & binary) **
3** **
4** Copyright (C) 2016-2022 A. Stebich (librecad@mail.lordofbikes.de) **
5** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
6** Copyright (C) 2026 LibreCAD (librecad.org) **
7** **
8** This library is free software, licensed under the terms of the GNU **
9** General Public License as published by the Free Software Foundation, **
10** either version 2 of the License, or (at your option) any later version. **
11** You should have received a copy of the GNU General Public License **
12** along with this program. If not, see <http://www.gnu.org/licenses/>. **
13******************************************************************************/
14
15#include "drw_header.h"
16#include <cmath>
17#include <cstdio>
18#include "intern/dxfreader.h"
19#include "intern/dxfwriter.h"
20#include "intern/drw_dbg.h"
21#include "intern/dwgbuffer.h"
22#include "intern/dwgbufferw.h"
23#include "intern/dwgsafety.h"
24#include "intern/dwg_fixed_handles.h"
25
26DRW_Header::DRW_Header() {
27 linetypeCtrl = layerCtrl = styleCtrl = dimstyleCtrl = appidCtrl = 0;
28 blockCtrl = viewCtrl = ucsCtrl = vportCtrl = vpEntHeaderCtrl = 0;
29 version = DRW::AC1021;
30}
31
32void DRW_Header::addComment(std::string c){
33 if (!comments.empty())
34 comments += '\n';
35 comments += c;
36}
37
38bool DRW_Header::parseCode(int code, const std::unique_ptr<dxfReader>& reader){
39 if (nullptr == curr && 9 != code) {
40 DRW_DBG("invalid header code: ")DRW_dbg::dbg("invalid header code: ");
41 DRW_DBG(code)DRW_dbg::dbg(code);
42 DRW_DBG("\n")DRW_dbg::dbg("\n");
43 return false;
44 }
45
46 switch (code) {
47 case 9:
48 name = reader->getString();
49 if (version < DRW::AC1015 && name == "$DIMUNIT")
50 name="$DIMLUNIT";
51 storeVar(name, new DRW_Variant());
52 break;
53 case 1:
54 curr->addString(code, reader->getUtf8String());
55 if (name =="$ACADVER") {
56 reader->setVersion(*curr->content.s, true);
57 version = reader->getVersion();
58 // An unrecognised $ACADVER is a format error, not an absent
59 // version. Stop before the header callback can publish a
60 // partially interpreted document.
61 if (reader->getSourceVersion() == DRW::UNKNOWNV)
62 return false;
63 }
64 break;
65 case 2:
66 curr->addString(code, reader->getUtf8String());
67 break;
68 case 3:
69 curr->addString(code, reader->getUtf8String());
70 if (name =="$DWGCODEPAGE") {
71 reader->setCodePage(*curr->content.s);
72 curr->addString(code, reader->getCodePage());
73 }
74 break;
75 case 6:
76 curr->addString(code, reader->getUtf8String());
77 break;
78 case 7:
79 curr->addString(code, reader->getUtf8String());
80 break;
81 case 8:
82 curr->addString(code, reader->getUtf8String());
83 break;
84 case 10:
85 curr->addCoord(code, DRW_Coord(reader->getDouble(), 0.0, 0.0));
86 break;
87 case 20:
88 curr->setCoordY(reader->getDouble());
89 break;
90 case 30:
91 curr->setCoordZ(reader->getDouble());
92 break;
93 case 40:
94 curr->addDouble(code, reader->getDouble());
95 break;
96 case 50:
97 curr->addDouble(code, reader->getDouble());
98 break;
99 case 62:
100 curr->addInt(code, reader->getInt32());
101 break;
102 case 70:
103 curr->addInt(code, reader->getInt32());
104 break;
105 case 280:
106 curr->addInt(code, reader->getInt32());
107 break;
108 case 290:
109 curr->addInt(code, reader->getInt32());
110 break;
111 case 370:
112 curr->addInt(code, reader->getInt32());
113 break;
114 case 380:
115 curr->addInt(code, reader->getInt32());
116 break;
117 case 390:
118 curr->addString(code, reader->getUtf8String());
119 break;
120 default:
121 break;
122 }
123
124 return true;
125}
126
127void DRW_Header::write(const std::unique_ptr<dxfWriter>& writer, DRW::Version ver){
128/*RLZ: TODO complete all vars to AC1024*/
129 double varDouble;
130 int varInt;
131 std::string varStr;
132 DRW_Coord varCoord;
133 writer->writeString(2, "HEADER");
134 writer->writeString(9, "$ACADVER");
135 switch (ver) {
136 case DRW::AC1006: //unsupported version acad 10
137 case DRW::AC1009: //acad 11 & 12
138 varStr = "AC1009";
139 break;
140 case DRW::AC1012: //unsupported version acad 13
141 case DRW::AC1014: //acad 14
142 varStr = "AC1014";
143 break;
144 case DRW::AC1015: //acad 2000
145 varStr = "AC1015";
146 break;
147 case DRW::AC1018: //acad 2004
148 varStr = "AC1018";
149 break;
150/* case DRW::AC1021: //acad 2007
151 varStr = "AC1021";
152 break;*/
153 case DRW::AC1024: //acad 2010
154 varStr = "AC1024";
155 break;
156 case DRW::AC1027: //acad 2013
157 varStr = "AC1027";
158 break;
159 case DRW::AC1032: //acad 2018
160 varStr = "AC1032";
161 break;
162 default: //acad 2007 default version
163 varStr = "AC1021";
164 break;
165 }
166 writer->writeString(1, varStr);
167 writer->setVersion(varStr, true);
168
169 getStr("$ACADVER", &varStr);
170 // $ACADMAINTVER (R2000+) was read then discarded. Emit it; the group code
171 // changed from 70 (Int16) to 90 (Int32) in R2018+ (ezdxf headervars.py).
172 if (ver > DRW::AC1014) {
173 writer->writeString(9, "$ACADMAINTVER");
174 int maintVer = 0;
175 getInt("$ACADMAINTVER", &maintVer);
176 if (ver >= DRW::AC1032)
177 writer->writeInt32(90, maintVer);
178 else
179 writer->writeInt16(70, maintVer);
180 }
181
182 if (!getStr("$DWGCODEPAGE", &varStr)) {
183 varStr = "ANSI_1252";
184 }
185 writer->writeString(9, "$DWGCODEPAGE");
186 writer->setCodePage(varStr);
187 writer->writeString(3, writer->getCodePage() );
188 writer->writeString(9, "$INSBASE");
189 if (getCoord("$INSBASE", &varCoord)) {
190 writer->writeDouble(10, varCoord.x);
191 writer->writeDouble(20, varCoord.y);
192 writer->writeDouble(30, varCoord.z);
193 } else {
194 writer->writeDouble(10, 0.0);
195 writer->writeDouble(20, 0.0);
196 writer->writeDouble(30, 0.0);
197 }
198 writer->writeString(9, "$EXTMIN");
199 if (getCoord("$EXTMIN", &varCoord)) {
200 writer->writeDouble(10, varCoord.x);
201 writer->writeDouble(20, varCoord.y);
202 writer->writeDouble(30, varCoord.z);
203 } else {
204 writer->writeDouble(10, 1.0000000000000000E+020);
205 writer->writeDouble(20, 1.0000000000000000E+020);
206 writer->writeDouble(30, 1.0000000000000000E+020);
207 }
208 writer->writeString(9, "$EXTMAX");
209 if (getCoord("$EXTMAX", &varCoord)) {
210 writer->writeDouble(10, varCoord.x);
211 writer->writeDouble(20, varCoord.y);
212 writer->writeDouble(30, varCoord.z);
213 } else {
214 writer->writeDouble(10, -1.0000000000000000E+020);
215 writer->writeDouble(20, -1.0000000000000000E+020);
216 writer->writeDouble(30, -1.0000000000000000E+020);
217 }
218 writer->writeString(9, "$LIMMIN");
219 if (getCoord("$LIMMIN", &varCoord)) {
220 writer->writeDouble(10, varCoord.x);
221 writer->writeDouble(20, varCoord.y);
222 } else {
223 writer->writeDouble(10, 0.0);
224 writer->writeDouble(20, 0.0);
225 }
226 writer->writeString(9, "$LIMMAX");
227 if (getCoord("$LIMMAX", &varCoord)) {
228 writer->writeDouble(10, varCoord.x);
229 writer->writeDouble(20, varCoord.y);
230 } else {
231 writer->writeDouble(10, 420.0);
232 writer->writeDouble(20, 297.0);
233 }
234 writer->writeString(9, "$ORTHOMODE");
235 if (getInt("$ORTHOMODE", &varInt))
236 writer->writeInt16(70, varInt);
237 else
238 writer->writeInt16(70, 0);
239 writer->writeString(9, "$REGENMODE");
240 if (getInt("$REGENMODE", &varInt))
241 writer->writeInt16(70, varInt);
242 else
243 writer->writeInt16(70, 1);
244 writer->writeString(9, "$FILLMODE");
245 if (getInt("$FILLMODE", &varInt))
246 writer->writeInt16(70, varInt);
247 else
248 writer->writeInt16(70, 1);
249 writer->writeString(9, "$QTEXTMODE");
250 if (getInt("$QTEXTMODE", &varInt))
251 writer->writeInt16(70, varInt);
252 else
253 writer->writeInt16(70, 0);
254 writer->writeString(9, "$MIRRTEXT");
255 if (getInt("$MIRRTEXT", &varInt))
256 writer->writeInt16(70, varInt);
257 else
258 writer->writeInt16(70, 0);
259 if (ver == DRW::AC1009){
260 writer->writeString(9, "$DRAGMODE");
261 if (getInt("$DRAGMODE", &varInt))
262 writer->writeInt16(70, varInt);
263 else
264 writer->writeInt16(70, 2);
265 }
266 writer->writeString(9, "$LTSCALE");
267 if (getDouble("$LTSCALE", &varDouble))
268 writer->writeDouble(40, varDouble);
269 else
270 writer->writeDouble(40, 1.0);
271 if (ver == DRW::AC1009){
272 writer->writeString(9, "$OSMODE");
273 if (getInt("$OSMODE", &varInt))
274 writer->writeInt16(70, varInt);
275 else
276 writer->writeInt16(70, 0);
277 }
278 writer->writeString(9, "$ATTMODE");
279 if (getInt("$ATTMODE", &varInt))
280 writer->writeInt16(70, varInt);
281 else
282 writer->writeInt16(70, 0);
283 writer->writeString(9, "$TEXTSIZE");
284 if (getDouble("$TEXTSIZE", &varDouble))
285 writer->writeDouble(40, varDouble);
286 else
287 writer->writeDouble(40, 2.5);
288 writer->writeString(9, "$TRACEWID");
289 if (getDouble("$TRACEWID", &varDouble))
290 writer->writeDouble(40, varDouble);
291 else
292 writer->writeDouble(40, 15.68);
293 writer->writeString(9, "$TEXTSTYLE");
294 if (getStr("$TEXTSTYLE", &varStr))
295 if (ver == DRW::AC1009)
296 writer->writeUtf8Caps(7, varStr);
297 else
298 writer->writeUtf8String(7, varStr);
299 else
300 writer->writeString(7, "STANDARD");
301 writer->writeString(9, "$CLAYER");
302 if (getStr("$CLAYER", &varStr))
303 if (ver == DRW::AC1009)
304 writer->writeUtf8Caps(8, varStr);
305 else
306 writer->writeUtf8String(8, varStr);
307 else
308 writer->writeString(8, "0");
309 writer->writeString(9, "$CELTYPE");
310 if (getStr("$CELTYPE", &varStr))
311 if (ver == DRW::AC1009)
312 writer->writeUtf8Caps(6, varStr);
313 else
314 writer->writeUtf8String(6, varStr);
315 else
316 writer->writeString(6, "BYLAYER");
317 writer->writeString(9, "$CECOLOR");
318 if (getInt("$CECOLOR", &varInt))
319 writer->writeInt16(62, varInt);
320 else
321 writer->writeInt16(62, 256);
322 if (ver > DRW::AC1009){
323 writer->writeString(9, "$CELTSCALE");
324 if (getDouble("$CELTSCALE", &varDouble))
325 writer->writeDouble(40, varDouble);
326 else
327 writer->writeDouble(40, 1.0);
328 writer->writeString(9, "$DISPSILH");
329 if (getInt("$DISPSILH", &varInt))
330 writer->writeInt16(70, varInt);
331 else
332 writer->writeInt16(70, 0);
333 writer->writeString(9, "$PELLIPSE");
334 if (getInt("$PELLIPSE", &varInt))
335 writer->writeInt16(70, varInt);
336 else
337 writer->writeInt16(70, 0);
338 }
339
340 writer->writeString(9, "$DIMSCALE");
341 if (getDouble("$DIMSCALE", &varDouble))
342 writer->writeDouble(40, varDouble);
343 else
344 writer->writeDouble(40, 2.5);
345 writer->writeString(9, "$DIMASZ");
346 if (getDouble("$DIMASZ", &varDouble))
347 writer->writeDouble(40, varDouble);
348 else
349 writer->writeDouble(40, 2.5);
350 writer->writeString(9, "$DIMEXO");
351 if (getDouble("$DIMEXO", &varDouble))
352 writer->writeDouble(40, varDouble);
353 else
354 writer->writeDouble(40, 0.625);
355 writer->writeString(9, "$DIMDLI");
356 if (getDouble("$DIMDLI", &varDouble))
357 writer->writeDouble(40, varDouble);
358 else
359 writer->writeDouble(40, 3.75);
360 writer->writeString(9, "$DIMRND");
361 if (getDouble("$DIMRND", &varDouble))
362 writer->writeDouble(40, varDouble);
363 else
364 writer->writeDouble(40, 0.0);
365 writer->writeString(9, "$DIMDLE");
366 if (getDouble("$DIMDLE", &varDouble))
367 writer->writeDouble(40, varDouble);
368 else
369 writer->writeDouble(40, 0.0);
370 writer->writeString(9, "$DIMEXE");
371 if (getDouble("$DIMEXE", &varDouble))
372 writer->writeDouble(40, varDouble);
373 else
374 writer->writeDouble(40, 1.25);
375 writer->writeString(9, "$DIMTP");
376 if (getDouble("$DIMTP", &varDouble))
377 writer->writeDouble(40, varDouble);
378 else
379 writer->writeDouble(40, 0.0);
380 writer->writeString(9, "$DIMTM");
381 if (getDouble("$DIMTM", &varDouble))
382 writer->writeDouble(40, varDouble);
383 else
384 writer->writeDouble(40, 0.0);
385 writer->writeString(9, "$DIMTXT");
386 if (getDouble("$DIMTXT", &varDouble))
387 writer->writeDouble(40, varDouble);
388 else
389 writer->writeDouble(40, 2.5);
390 writer->writeString(9, "$DIMCEN");
391 if (getDouble("$DIMCEN", &varDouble))
392 writer->writeDouble(40, varDouble);
393 else
394 writer->writeDouble(40, 2.5);
395 writer->writeString(9, "$DIMTSZ");
396 if (getDouble("$DIMTSZ", &varDouble))
397 writer->writeDouble(40, varDouble);
398 else
399 writer->writeDouble(40, 0.0);
400 writer->writeString(9, "$DIMTOL");
401 if (getInt("$DIMTOL", &varInt))
402 writer->writeInt16(70, varInt);
403 else
404 writer->writeInt16(70, 0);
405 writer->writeString(9, "$DIMLIM");
406 if (getInt("$DIMLIM", &varInt))
407 writer->writeInt16(70, varInt);
408 else
409 writer->writeInt16(70, 0);
410 writer->writeString(9, "$DIMTIH");
411 if (getInt("$DIMTIH", &varInt))
412 writer->writeInt16(70, varInt);
413 else
414 writer->writeInt16(70, 0);
415 writer->writeString(9, "$DIMTOH");
416 if (getInt("$DIMTOH", &varInt))
417 writer->writeInt16(70, varInt);
418 else
419 writer->writeInt16(70, 0);
420 writer->writeString(9, "$DIMSE1");
421 if (getInt("$DIMSE1", &varInt))
422 writer->writeInt16(70, varInt);
423 else
424 writer->writeInt16(70, 0);
425 writer->writeString(9, "$DIMSE2");
426 if (getInt("$DIMSE2", &varInt))
427 writer->writeInt16(70, varInt);
428 else
429 writer->writeInt16(70, 0);
430 writer->writeString(9, "$DIMTAD");
431 if (getInt("$DIMTAD", &varInt))
432 writer->writeInt16(70, varInt);
433 else
434 writer->writeInt16(70, 1);
435 writer->writeString(9, "$DIMZIN");
436 if (getInt("$DIMZIN", &varInt))
437 writer->writeInt16(70, varInt);
438 else
439 writer->writeInt16(70, 8);
440 writer->writeString(9, "$DIMBLK");
441 if (getStr("$DIMBLK", &varStr))
442 if (ver == DRW::AC1009)
443 writer->writeUtf8Caps(1, varStr);
444 else
445 writer->writeUtf8String(1, varStr);
446 else
447 writer->writeString(1, "");
448 writer->writeString(9, "$DIMASO");
449 if (getInt("$DIMASO", &varInt))
450 writer->writeInt16(70, varInt);
451 else
452 writer->writeInt16(70, 1);
453 writer->writeString(9, "$DIMSHO");
454 if (getInt("$DIMSHO", &varInt))
455 writer->writeInt16(70, varInt);
456 else
457 writer->writeInt16(70, 1);
458 writer->writeString(9, "$DIMPOST");
459 if (getStr("$DIMPOST", &varStr))
460 if (ver == DRW::AC1009)
461 writer->writeUtf8Caps(1, varStr);
462 else
463 writer->writeUtf8String(1, varStr);
464 else
465 writer->writeString(1, "");
466 writer->writeString(9, "$DIMAPOST");
467 if (getStr("$DIMAPOST", &varStr))
468 if (ver == DRW::AC1009)
469 writer->writeUtf8Caps(1, varStr);
470 else
471 writer->writeUtf8String(1, varStr);
472 else
473 writer->writeString(1, "");
474 writer->writeString(9, "$DIMALT");
475 if (getInt("$DIMALT", &varInt))
476 writer->writeInt16(70, varInt);
477 else
478 writer->writeInt16(70, 0);
479 writer->writeString(9, "$DIMALTD");
480 if (getInt("$DIMALTD", &varInt))
481 writer->writeInt16(70, varInt);
482 else
483 writer->writeInt16(70, 3);
484 writer->writeString(9, "$DIMALTF");
485 if (getDouble("$DIMALTF", &varDouble))
486 writer->writeDouble(40, varDouble);
487 else
488 writer->writeDouble(40, 0.03937);
489 writer->writeString(9, "$DIMLFAC");
490 if (getDouble("$DIMLFAC", &varDouble))
491 writer->writeDouble(40, varDouble);
492 else
493 writer->writeDouble(40, 1.0);
494 writer->writeString(9, "$DIMTOFL");
495 if (getInt("$DIMTOFL", &varInt))
496 writer->writeInt16(70, varInt);
497 else
498 writer->writeInt16(70, 1);
499 writer->writeString(9, "$DIMTVP");
500 if (getDouble("$DIMTVP", &varDouble))
501 writer->writeDouble(40, varDouble);
502 else
503 writer->writeDouble(40, 0.0);
504 writer->writeString(9, "$DIMTIX");
505 if (getInt("$DIMTIX", &varInt))
506 writer->writeInt16(70, varInt);
507 else
508 writer->writeInt16(70, 0);
509 writer->writeString(9, "$DIMSOXD");
510 if (getInt("$DIMSOXD", &varInt))
511 writer->writeInt16(70, varInt);
512 else
513 writer->writeInt16(70, 0);
514 writer->writeString(9, "$DIMSAH");
515 if (getInt("$DIMSAH", &varInt))
516 writer->writeInt16(70, varInt);
517 else
518 writer->writeInt16(70, 0);
519 writer->writeString(9, "$DIMBLK1");
520 if (getStr("$DIMBLK1", &varStr))
521 if (ver == DRW::AC1009)
522 writer->writeUtf8Caps(1, varStr);
523 else
524 writer->writeUtf8String(1, varStr);
525 else
526 writer->writeString(1, "");
527 writer->writeString(9, "$DIMBLK2");
528 if (getStr("$DIMBLK2", &varStr))
529 if (ver == DRW::AC1009)
530 writer->writeUtf8Caps(1, varStr);
531 else
532 writer->writeUtf8String(1, varStr);
533 else
534 writer->writeString(1, "");
535 writer->writeString(9, "$DIMSTYLE");
536 if (getStr("$DIMSTYLE", &varStr))
537 if (ver == DRW::AC1009)
538 writer->writeUtf8Caps(2, varStr);
539 else
540 writer->writeUtf8String(2, varStr);
541 else
542 writer->writeString(2, "STANDARD");
543 writer->writeString(9, "$DIMCLRD");
544 if (getInt("$DIMCLRD", &varInt))
545 writer->writeInt16(70, varInt);
546 else
547 writer->writeInt16(70, 0);
548 writer->writeString(9, "$DIMCLRE");
549 if (getInt("$DIMCLRE", &varInt))
550 writer->writeInt16(70, varInt);
551 else
552 writer->writeInt16(70, 0);
553 writer->writeString(9, "$DIMCLRT");
554 if (getInt("$DIMCLRT", &varInt))
555 writer->writeInt16(70, varInt);
556 else
557 writer->writeInt16(70, 0);
558 writer->writeString(9, "$DIMTFAC");
559 if (getDouble("$DIMTFAC", &varDouble))
560 writer->writeDouble(40, varDouble);
561 else
562 writer->writeDouble(40, 1.0);
563 writer->writeString(9, "$DIMGAP");
564 if (getDouble("$DIMGAP", &varDouble))
565 writer->writeDouble(40, varDouble);
566 else
567 writer->writeDouble(40, 0.625);
568 //post r12 dim vars
569 if (ver > DRW::AC1009) {
570 writer->writeString(9, "$DIMJUST");
571 if (getInt("$DIMJUST", &varInt))
572 writer->writeInt16(70, varInt);
573 else
574 writer->writeInt16(70, 0);
575 writer->writeString(9, "$DIMSD1");
576 if (getInt("$DIMSD1", &varInt))
577 writer->writeInt16(70, varInt);
578 else
579 writer->writeInt16(70, 0);
580 writer->writeString(9, "$DIMSD2");
581 if (getInt("$DIMSD2", &varInt))
582 writer->writeInt16(70, varInt);
583 else
584 writer->writeInt16(70, 0);
585 writer->writeString(9, "$DIMTOLJ");
586 if (getInt("$DIMTOLJ", &varInt))
587 writer->writeInt16(70, varInt);
588 else
589 writer->writeInt16(70, 0);
590 writer->writeString(9, "$DIMTZIN");
591 if (getInt("$DIMTZIN", &varInt))
592 writer->writeInt16(70, varInt);
593 else
594 writer->writeInt16(70, 8);
595 writer->writeString(9, "$DIMALTZ");
596 if (getInt("$DIMALTZ", &varInt))
597 writer->writeInt16(70, varInt);
598 else
599 writer->writeInt16(70, 0);
600 writer->writeString(9, "$DIMALTTZ");
601 if (getInt("$DIMALTTZ", &varInt))
602 writer->writeInt16(70, varInt);
603 else
604 writer->writeInt16(70, 0);
605 writer->writeString(9, "$DIMUPT");
606 if (getInt("$DIMUPT", &varInt))
607 writer->writeInt16(70, varInt);
608 else
609 writer->writeInt16(70, 0);
610 writer->writeString(9, "$DIMDEC");
611 if (getInt("$DIMDEC", &varInt))
612 writer->writeInt16(70, varInt);
613 else
614 writer->writeInt16(70, 2);
615 writer->writeString(9, "$DIMTDEC");
616 if (getInt("$DIMTDEC", &varInt))
617 writer->writeInt16(70, varInt);
618 else
619 writer->writeInt16(70, 2);
620 writer->writeString(9, "$DIMALTU");
621 if (getInt("$DIMALTU", &varInt))
622 writer->writeInt16(70, varInt);
623 else
624 writer->writeInt16(70, 2);
625 writer->writeString(9, "$DIMALTTD");
626 if (getInt("$DIMALTTD", &varInt))
627 writer->writeInt16(70, varInt);
628 else
629 writer->writeInt16(70, 3);
630 writer->writeString(9, "$DIMTXSTY");
631 if (getStr("$DIMTXSTY", &varStr))
632 if (ver == DRW::AC1009)
633 writer->writeUtf8Caps(7, varStr);
634 else
635 writer->writeUtf8String(7, varStr);
636 else
637 writer->writeString(7, "STANDARD");
638 writer->writeString(9, "$DIMAUNIT");
639 if (getInt("$DIMAUNIT", &varInt))
640 writer->writeInt16(70, varInt);
641 else
642 writer->writeInt16(70, 0);
643 writer->writeString(9, "$DIMADEC");
644 if (getInt("$DIMADEC", &varInt))
645 writer->writeInt16(70, varInt);
646 else
647 writer->writeInt16(70, 0);
648 writer->writeString(9, "$DIMALTRND");
649 if (getDouble("$DIMALTRND", &varDouble))
650 writer->writeDouble(40, varDouble);
651 else
652 writer->writeDouble(40, 0.0);
653 writer->writeString(9, "$DIMAZIN");
654 if (getInt("$DIMAZIN", &varInt))
655 writer->writeInt16(70, varInt);
656 else
657 writer->writeInt16(70, 0);
658 writer->writeString(9, "$DIMDSEP");
659 if (getInt("$DIMDSEP", &varInt))
660 writer->writeInt16(70, varInt);
661 else
662 writer->writeInt16(70, 44);
663 writer->writeString(9, "$DIMATFIT");
664 if (getInt("$DIMATFIT", &varInt))
665 writer->writeInt16(70, varInt);
666 else
667 writer->writeInt16(70, 3);
668 writer->writeString(9, "$DIMFRAC");
669 if (getInt("$DIMFRAC", &varInt))
670 writer->writeInt16(70, varInt);
671 else
672 writer->writeInt16(70, 0);
673 writer->writeString(9, "$DIMLDRBLK");
674 if (getStr("$DIMLDRBLK", &varStr))
675 if (ver == DRW::AC1009)
676 writer->writeUtf8Caps(1, varStr);
677 else
678 writer->writeUtf8String(1, varStr);
679 else
680 writer->writeString(1, "STANDARD");
681 //verify if exist "$DIMLUNIT" or obsolete "$DIMUNIT" (pre v2000)
682 if ( !getInt("$DIMLUNIT", &varInt) ){
683 if (!getInt("$DIMUNIT", &varInt))
684 varInt = 2;
685 }
686 //verify valid values from 1 to 6
687 if (varInt<1 || varInt>6)
688 varInt = 2;
689 if (ver > DRW::AC1014) {
690 writer->writeString(9, "$DIMLUNIT");
691 writer->writeInt16(70, varInt);
692 } else {
693 writer->writeString(9, "$DIMUNIT");
694 writer->writeInt16(70, varInt);
695 }
696 writer->writeString(9, "$DIMLWD");
697 if (getInt("$DIMLWD", &varInt))
698 writer->writeInt16(70, varInt);
699 else
700 writer->writeInt16(70, -2);
701 writer->writeString(9, "$DIMLWE");
702 if (getInt("$DIMLWE", &varInt))
703 writer->writeInt16(70, varInt);
704 else
705 writer->writeInt16(70, -2);
706 writer->writeString(9, "$DIMTMOVE");
707 if (getInt("$DIMTMOVE", &varInt))
708 writer->writeInt16(70, varInt);
709 else
710 writer->writeInt16(70, 0);
711
712 if (ver > DRW::AC1018) {// and post v2004 dim vars
713 writer->writeString(9, "$DIMFXL");
714 if (getDouble("$DIMFXL", &varDouble))
715 writer->writeDouble(40, varDouble);
716 else
717 writer->writeDouble(40, 1.0);
718 writer->writeString(9, "$DIMFXLON");
719 if (getInt("$DIMFXLON", &varInt))
720 writer->writeInt16(70, varInt);
721 else
722 writer->writeInt16(70, 0);
723 writer->writeString(9, "$DIMJOGANG");
724 if (getDouble("$DIMJOGANG", &varDouble))
725 writer->writeDouble(40, varDouble);
726 else
727 writer->writeDouble(40, 0.7854);
728 writer->writeString(9, "$DIMTFILL");
729 if (getInt("$DIMTFILL", &varInt))
730 writer->writeInt16(70, varInt);
731 else
732 writer->writeInt16(70, 0);
733 writer->writeString(9, "$DIMTFILLCLR");
734 if (getInt("$DIMTFILLCLR", &varInt))
735 writer->writeInt16(70, varInt);
736 else
737 writer->writeInt16(70, 0);
738 writer->writeString(9, "$DIMARCSYM");
739 if (getInt("$DIMARCSYM", &varInt))
740 writer->writeInt16(70, varInt);
741 else
742 writer->writeInt16(70, 0);
743 writer->writeString(9, "$DIMLTYPE");
744 if (getStr("$DIMLTYPE", &varStr))
745 if (ver == DRW::AC1009)
746 writer->writeUtf8Caps(6, varStr);
747 else
748 writer->writeUtf8String(6, varStr);
749 else
750 writer->writeString(6, "");
751 writer->writeString(9, "$DIMLTEX1");
752 if (getStr("$DIMLTEX1", &varStr))
753 if (ver == DRW::AC1009)
754 writer->writeUtf8Caps(6, varStr);
755 else
756 writer->writeUtf8String(6, varStr);
757 else
758 writer->writeString(6, "");
759 writer->writeString(9, "$DIMLTEX2");
760 if (getStr("$DIMLTEX2", &varStr))
761 if (ver == DRW::AC1009)
762 writer->writeUtf8Caps(6, varStr);
763 else
764 writer->writeUtf8String(6, varStr);
765 else
766 writer->writeString(6, "");
767 if (ver > DRW::AC1021) {// and post v2007 dim vars
768 writer->writeString(9, "$DIMTXTDIRECTION");
769 if (getInt("$DIMTXTDIRECTION", &varInt))
770 writer->writeInt16(70, varInt);
771 else
772 writer->writeInt16(70, 0);
773 writer->writeString(9, "$DIMALTMZF");
774 if (getDouble("$DIMALTMZF", &varDouble))
775 writer->writeDouble(40, varDouble);
776 else
777 writer->writeDouble(40, 1.0);
778 writer->writeString(9, "$DIMALTMZS");
779 if (getStr("$DIMALTMZS", &varStr))
780 writer->writeUtf8String(1, varStr);
781 else
782 writer->writeString(1, "");
783 writer->writeString(9, "$DIMMZF");
784 if (getDouble("$DIMMZF", &varDouble))
785 writer->writeDouble(40, varDouble);
786 else
787 writer->writeDouble(40, 1.0);
788 writer->writeString(9, "$DIMMZS");
789 if (getStr("$DIMMZS", &varStr))
790 writer->writeUtf8String(1, varStr);
791 else
792 writer->writeString(1, "");
793 }
794 }// end post v2004 dim vars
795 }//end post r12 dim vars
796
797 writer->writeString(9, "$LUNITS");
798 if (getInt("$LUNITS", &varInt))
799 writer->writeInt16(70, varInt);
800 else
801 writer->writeInt16(70, 2);
802 writer->writeString(9, "$LUPREC");
803 if (getInt("$LUPREC", &varInt))
804 writer->writeInt16(70, varInt);
805 else
806 writer->writeInt16(70, 4);
807 writer->writeString(9, "$SKETCHINC");
808 if (getDouble("$SKETCHINC", &varDouble))
809 writer->writeDouble(40, varDouble);
810 else
811 writer->writeDouble(40, 1.0);
812 writer->writeString(9, "$FILLETRAD");
813 if (getDouble("$FILLETRAD", &varDouble))
814 writer->writeDouble(40, varDouble);
815 else
816 writer->writeDouble(40, 0.0);
817 writer->writeString(9, "$AUNITS");
818 if (getInt("$AUNITS", &varInt))
819 writer->writeInt16(70, varInt);
820 else
821 writer->writeInt16(70, 0);
822 writer->writeString(9, "$AUPREC");
823 if (getInt("$AUPREC", &varInt))
824 writer->writeInt16(70, varInt);
825 else
826 writer->writeInt16(70, 2);
827 writer->writeString(9, "$MENU");
828 if (getStr("$MENU", &varStr))
829 if (ver == DRW::AC1009)
830 writer->writeUtf8Caps(1, varStr);
831 else
832 writer->writeUtf8String(1, varStr);
833 else
834 writer->writeString(1, ".");
835 writer->writeString(9, "$TDCREATE");
836 if (getDouble("$TDCREATE", &varDouble))
837 writer->writeDouble(40, varDouble);
838 else
839 writer->writeDouble(40, 0.0);
840 writer->writeString(9, "$TDUPDATE");
841 if (getDouble("$TDUPDATE", &varDouble))
842 writer->writeDouble(40, varDouble);
843 else
844 writer->writeDouble(40, 0.0);
845 writer->writeString(9, "$TDINDWG");
846 if (getDouble("$TDINDWG", &varDouble))
847 writer->writeDouble(40, varDouble);
848 else
849 writer->writeDouble(40, 0.0);
850 writer->writeString(9, "$TDUSRTIMER");
851 if (getDouble("$TDUSRTIMER", &varDouble))
852 writer->writeDouble(40, varDouble);
853 else
854 writer->writeDouble(40, 0.0);
855 writer->writeString(9, "$ELEVATION");
856 if (getDouble("$ELEVATION", &varDouble))
857 writer->writeDouble(40, varDouble);
858 else
859 writer->writeDouble(40, 0.0);
860 writer->writeString(9, "$PELEVATION");
861 if (getDouble("$PELEVATION", &varDouble))
862 writer->writeDouble(40, varDouble);
863 else
864 writer->writeDouble(40, 0.0);
865 writer->writeString(9, "$THICKNESS");
866 if (getDouble("$THICKNESS", &varDouble))
867 writer->writeDouble(40, varDouble);
868 else
869 writer->writeDouble(40, 0.0);
870 writer->writeString(9, "$LIMCHECK");
871 if (getInt("$LIMCHECK", &varInt))
872 writer->writeInt16(70, varInt);
873 else
874 writer->writeInt16(70, 0);
875 if (ver < DRW::AC1015) {
876 writer->writeString(9, "$BLIPMODE");
877 if (getInt("$BLIPMODE", &varInt))
878 writer->writeInt16(70, varInt);
879 else
880 writer->writeInt16(70, 0);
881 }
882 writer->writeString(9, "$CHAMFERA");
883 if (getDouble("$CHAMFERA", &varDouble))
884 writer->writeDouble(40, varDouble);
885 else
886 writer->writeDouble(40, 0.0);
887 writer->writeString(9, "$CHAMFERB");
888 if (getDouble("$CHAMFERB", &varDouble))
889 writer->writeDouble(40, varDouble);
890 else
891 writer->writeDouble(40, 0.0);
892 if (ver > DRW::AC1009) {
893 writer->writeString(9, "$CHAMFERC");
894 if (getDouble("$CHAMFERC", &varDouble))
895 writer->writeDouble(40, varDouble);
896 else
897 writer->writeDouble(40, 0.0);
898 writer->writeString(9, "$CHAMFERD");
899 if (getDouble("$CHAMFERD", &varDouble))
900 writer->writeDouble(40, varDouble);
901 else
902 writer->writeDouble(40, 0.0);
903 }
904 writer->writeString(9, "$SKPOLY");
905 if (getInt("$SKPOLY", &varInt)) {
906 writer->writeInt16(70, varInt);
907 } else
908 writer->writeInt16(70, 0);
909 //rlz: todo, times
910 writer->writeString(9, "$USRTIMER");
911 if (getInt("$USRTIMER", &varInt)) {
912 writer->writeInt16(70, varInt);
913 } else
914 writer->writeInt16(70, 1);
915 writer->writeString(9, "$ANGBASE");
916 if (getDouble("$ANGBASE", &varDouble))
917 writer->writeDouble(50, varDouble);
918 else
919 writer->writeDouble(50, 0.0);
920 writer->writeString(9, "$ANGDIR");
921 if (getInt("$ANGDIR", &varInt)) {
922 writer->writeInt16(70, varInt);
923 } else
924 writer->writeInt16(70, 0);
925 writer->writeString(9, "$PDMODE");
926 if (getInt("$PDMODE", &varInt)) {
927 writer->writeInt16(70, varInt);
928 } else
929 writer->writeInt16(70, 34);
930 writer->writeString(9, "$PDSIZE");
931 if (getDouble("$PDSIZE", &varDouble))
932 writer->writeDouble(40, varDouble);
933 else
934 writer->writeDouble(40, 0.0);
935 writer->writeString(9, "$PLINEWID");
936 if (getDouble("$PLINEWID", &varDouble))
937 writer->writeDouble(40, varDouble);
938 else
939 writer->writeDouble(40, 0.0);
940 if (ver < DRW::AC1012) {
941 writer->writeString(9, "$COORDS");
942 if (getInt("$COORDS", &varInt)) {
943 writer->writeInt16(70, varInt);
944 } else
945 writer->writeInt16(70, 2);
946 }
947 writer->writeString(9, "$SPLFRAME");
948 if (getInt("$SPLFRAME", &varInt)) {
949 writer->writeInt16(70, varInt);
950 } else
951 writer->writeInt16(70, 0);
952 writer->writeString(9, "$SPLINETYPE");
953 if (getInt("$SPLINETYPE", &varInt)) {
954 writer->writeInt16(70, varInt);
955 } else
956 writer->writeInt16(70, 2);
957 writer->writeString(9, "$SPLINESEGS");
958 if (getInt("$SPLINESEGS", &varInt)) {
959 writer->writeInt16(70, varInt);
960 } else
961 writer->writeInt16(70, 8);
962 if (ver < DRW::AC1012) {
963 writer->writeString(9, "$ATTDIA");
964 if (getInt("$ATTDIA", &varInt)) {
965 writer->writeInt16(70, varInt);
966 } else
967 writer->writeInt16(70, 1);
968 writer->writeString(9, "$ATTREQ");
969 if (getInt("$ATTREQ", &varInt)) {
970 writer->writeInt16(70, varInt);
971 } else
972 writer->writeInt16(70, 1);
973 writer->writeString(9, "$HANDLING");
974 if (getInt("$HANDLING", &varInt)) {
975 writer->writeInt16(70, varInt);
976 } else
977 writer->writeInt16(70, 1);
978 }
979 writer->writeString(9, "$HANDSEED");
980 //RLZ dxfHex(5, 0xFFFF);
981 // Emit $HANDSEED as a fixed-width zero-padded hex placeholder and record the
982 // value-field offset so dxfRW can back-patch it with the final handle
983 // high-water mark after the OBJECTS section (the header streams first, so the
984 // true high-water is not yet known here). handSeed (if pre-set by a DWG-side
985 // round-trip) seeds the placeholder; otherwise the legacy 0x20000 ceiling is
986 // used and back-patched up if minted/raw handles exceed it.
987 {
988 std::uint32_t seed = (handSeed != 0) ? handSeed : 0x20000u;
989 char buf[kHandseedFieldWidth + 1];
990 snprintf(buf, sizeof(buf), "%0*X", kHandseedFieldWidth, seed);
991 std::ostream *os = writer->stream();
992 std::streampos before = os ? os->tellp() : std::streampos(-1);
993 writer->writeString(5, std::string(buf));
994 if (os && before != std::streampos(-1)) {
995 std::streampos after = os->tellp();
996 // ASCII: " 5\n"+value+"\n"; binary: code(2)+value+'\0'. In both the
997 // value field is the kHandseedFieldWidth bytes ending one byte before
998 // `after`, so the field starts at after-(width+1).
999 m_handseedValueOffset =
1000 after - static_cast<std::streamoff>(kHandseedFieldWidth + 1);
1001 }
1002 }
1003 writer->writeString(9, "$SURFTAB1");
1004 if (getInt("$SURFTAB1", &varInt)) {
1005 writer->writeInt16(70, varInt);
1006 } else
1007 writer->writeInt16(70, 6);
1008 writer->writeString(9, "$SURFTAB2");
1009 if (getInt("$SURFTAB2", &varInt)) {
1010 writer->writeInt16(70, varInt);
1011 } else
1012 writer->writeInt16(70, 6);
1013 writer->writeString(9, "$SURFTYPE");
1014 if (getInt("$SURFTYPE", &varInt)) {
1015 writer->writeInt16(70, varInt);
1016 } else
1017 writer->writeInt16(70, 6);
1018 writer->writeString(9, "$SURFU");
1019 if (getInt("$SURFU", &varInt)) {
1020 writer->writeInt16(70, varInt);
1021 } else
1022 writer->writeInt16(70, 6);
1023 writer->writeString(9, "$SURFV");
1024 if (getInt("$SURFV", &varInt)) {
1025 writer->writeInt16(70, varInt);
1026 } else
1027 writer->writeInt16(70, 6);
1028 if (ver > DRW::AC1009) {
1029 writer->writeString(9, "$UCSBASE");
1030 if (getStr("$UCSBASE", &varStr))
1031 if (ver == DRW::AC1009)
1032 writer->writeUtf8Caps(2, varStr);
1033 else
1034 writer->writeUtf8String(2, varStr);
1035 else
1036 writer->writeString(2, "");
1037}
1038 writer->writeString(9, "$UCSNAME");
1039 if (getStr("$UCSNAME", &varStr))
1040 if (ver == DRW::AC1009)
1041 writer->writeUtf8Caps(2, varStr);
1042 else
1043 writer->writeUtf8String(2, varStr);
1044 else
1045 writer->writeString(2, "");
1046 writer->writeString(9, "$UCSORG");
1047 if (getCoord("$UCSORG", &varCoord)) {
1048 writer->writeDouble(10, varCoord.x);
1049 writer->writeDouble(20, varCoord.y);
1050 writer->writeDouble(30, varCoord.z);
1051 } else {
1052 writer->writeDouble(10, 0.0);
1053 writer->writeDouble(20, 0.0);
1054 writer->writeDouble(30, 0.0);
1055 }
1056 writer->writeString(9, "$UCSXDIR");
1057 if (getCoord("$UCSXDIR", &varCoord)) {
1058 writer->writeDouble(10, varCoord.x);
1059 writer->writeDouble(20, varCoord.y);
1060 writer->writeDouble(30, varCoord.z);
1061 } else {
1062 writer->writeDouble(10, 1.0);
1063 writer->writeDouble(20, 0.0);
1064 writer->writeDouble(30, 0.0);
1065 }
1066 writer->writeString(9, "$UCSYDIR");
1067 if (getCoord("$UCSYDIR", &varCoord)) {
1068 writer->writeDouble(10, varCoord.x);
1069 writer->writeDouble(20, varCoord.y);
1070 writer->writeDouble(30, varCoord.z);
1071 } else {
1072 writer->writeDouble(10, 0.0);
1073 writer->writeDouble(20, 1.0);
1074 writer->writeDouble(30, 0.0);
1075 }
1076 if (ver > DRW::AC1009) { //begin post r12 UCS vars
1077 writer->writeString(9, "$UCSORTHOREF");
1078 if (getStr("$UCSORTHOREF", &varStr))
1079 if (ver == DRW::AC1009)
1080 writer->writeUtf8Caps(2, varStr);
1081 else
1082 writer->writeUtf8String(2, varStr);
1083 else
1084 writer->writeString(2, "");
1085 writer->writeString(9, "$UCSORTHOVIEW");
1086 if (getInt("$UCSORTHOVIEW", &varInt))
1087 writer->writeInt16(70, varInt);
1088 else
1089 writer->writeInt16(70, 0);
1090 writer->writeString(9, "$UCSORGTOP");
1091 if (getCoord("$UCSORGTOP", &varCoord)) {
1092 writer->writeDouble(10, varCoord.x);
1093 writer->writeDouble(20, varCoord.y);
1094 writer->writeDouble(30, varCoord.z);
1095 } else {
1096 writer->writeDouble(10, 0.0);
1097 writer->writeDouble(20, 0.0);
1098 writer->writeDouble(30, 0.0);
1099 }
1100 writer->writeString(9, "$UCSORGBOTTOM");
1101 if (getCoord("$UCSORGBOTTOM", &varCoord)) {
1102 writer->writeDouble(10, varCoord.x);
1103 writer->writeDouble(20, varCoord.y);
1104 writer->writeDouble(30, varCoord.z);
1105 } else {
1106 writer->writeDouble(10, 0.0);
1107 writer->writeDouble(20, 0.0);
1108 writer->writeDouble(30, 0.0);
1109 }
1110 writer->writeString(9, "$UCSORGLEFT");
1111 if (getCoord("$UCSORGLEFT", &varCoord)) {
1112 writer->writeDouble(10, varCoord.x);
1113 writer->writeDouble(20, varCoord.y);
1114 writer->writeDouble(30, varCoord.z);
1115 } else {
1116 writer->writeDouble(10, 0.0);
1117 writer->writeDouble(20, 0.0);
1118 writer->writeDouble(30, 0.0);
1119 }
1120 writer->writeString(9, "$UCSORGRIGHT");
1121 if (getCoord("$UCSORGRIGHT", &varCoord)) {
1122 writer->writeDouble(10, varCoord.x);
1123 writer->writeDouble(20, varCoord.y);
1124 writer->writeDouble(30, varCoord.z);
1125 } else {
1126 writer->writeDouble(10, 0.0);
1127 writer->writeDouble(20, 0.0);
1128 writer->writeDouble(30, 0.0);
1129 }
1130 writer->writeString(9, "$UCSORGFRONT");
1131 if (getCoord("$UCSORGFRONT", &varCoord)) {
1132 writer->writeDouble(10, varCoord.x);
1133 writer->writeDouble(20, varCoord.y);
1134 writer->writeDouble(30, varCoord.z);
1135 } else {
1136 writer->writeDouble(10, 0.0);
1137 writer->writeDouble(20, 0.0);
1138 writer->writeDouble(30, 0.0);
1139 }
1140 writer->writeString(9, "$UCSORGBACK");
1141 if (getCoord("$UCSORGBACK", &varCoord)) {
1142 writer->writeDouble(10, varCoord.x);
1143 writer->writeDouble(20, varCoord.y);
1144 writer->writeDouble(30, varCoord.z);
1145 } else {
1146 writer->writeDouble(10, 0.0);
1147 writer->writeDouble(20, 0.0);
1148 writer->writeDouble(30, 0.0);
1149 }
1150 writer->writeString(9, "$PUCSBASE");
1151 if (getStr("$PUCSBASE", &varStr))
1152 if (ver == DRW::AC1009)
1153 writer->writeUtf8Caps(2, varStr);
1154 else
1155 writer->writeUtf8String(2, varStr);
1156 else
1157 writer->writeString(2, "");
1158 } //end post r12 UCS vars
1159 writer->writeString(9, "$PUCSNAME");
1160 if (getStr("$PUCSNAME", &varStr))
1161 if (ver == DRW::AC1009)
1162 writer->writeUtf8Caps(2, varStr);
1163 else
1164 writer->writeUtf8String(2, varStr);
1165 else
1166 writer->writeString(2, "");
1167 writer->writeString(9, "$PUCSORG");
1168 if (getCoord("$PUCSORG", &varCoord)) {
1169 writer->writeDouble(10, varCoord.x);
1170 writer->writeDouble(20, varCoord.y);
1171 writer->writeDouble(30, varCoord.z);
1172 } else {
1173 writer->writeDouble(10, 0.0);
1174 writer->writeDouble(20, 0.0);
1175 writer->writeDouble(30, 0.0);
1176 }
1177 writer->writeString(9, "$PUCSXDIR");
1178 if (getCoord("$PUCSXDIR", &varCoord)) {
1179 writer->writeDouble(10, varCoord.x);
1180 writer->writeDouble(20, varCoord.y);
1181 writer->writeDouble(30, varCoord.z);
1182 } else {
1183 writer->writeDouble(10, 1.0);
1184 writer->writeDouble(20, 0.0);
1185 writer->writeDouble(30, 0.0);
1186 }
1187 writer->writeString(9, "$PUCSYDIR");
1188 if (getCoord("$PUCSYDIR", &varCoord)) {
1189 writer->writeDouble(10, varCoord.x);
1190 writer->writeDouble(20, varCoord.y);
1191 writer->writeDouble(30, varCoord.z);
1192 } else {
1193 writer->writeDouble(10, 0.0);
1194 writer->writeDouble(20, 1.0);
1195 writer->writeDouble(30, 0.0);
1196 }
1197 if (ver > DRW::AC1009) { //begin post r12 PUCS vars
1198 writer->writeString(9, "$PUCSORTHOREF");
1199 if (getStr("$PUCSORTHOREF", &varStr))
1200 if (ver == DRW::AC1009)
1201 writer->writeUtf8Caps(2, varStr);
1202 else
1203 writer->writeUtf8String(2, varStr);
1204 else
1205 writer->writeString(2, "");
1206 writer->writeString(9, "$PUCSORTHOVIEW");
1207 if (getInt("$PUCSORTHOVIEW", &varInt))
1208 writer->writeInt16(70, varInt);
1209 else
1210 writer->writeInt16(70, 0);
1211 writer->writeString(9, "$PUCSORGTOP");
1212 if (getCoord("$PUCSORGTOP", &varCoord)) {
1213 writer->writeDouble(10, varCoord.x);
1214 writer->writeDouble(20, varCoord.y);
1215 writer->writeDouble(30, varCoord.z);
1216 } else {
1217 writer->writeDouble(10, 0.0);
1218 writer->writeDouble(20, 0.0);
1219 writer->writeDouble(30, 0.0);
1220 }
1221 writer->writeString(9, "$PUCSORGBOTTOM");
1222 if (getCoord("$PUCSORGBOTTOM", &varCoord)) {
1223 writer->writeDouble(10, varCoord.x);
1224 writer->writeDouble(20, varCoord.y);
1225 writer->writeDouble(30, varCoord.z);
1226 } else {
1227 writer->writeDouble(10, 0.0);
1228 writer->writeDouble(20, 0.0);
1229 writer->writeDouble(30, 0.0);
1230 }
1231 writer->writeString(9, "$PUCSORGLEFT");
1232 if (getCoord("$PUCSORGLEFT", &varCoord)) {
1233 writer->writeDouble(10, varCoord.x);
1234 writer->writeDouble(20, varCoord.y);
1235 writer->writeDouble(30, varCoord.z);
1236 } else {
1237 writer->writeDouble(10, 0.0);
1238 writer->writeDouble(20, 0.0);
1239 writer->writeDouble(30, 0.0);
1240 }
1241 writer->writeString(9, "$PUCSORGRIGHT");
1242 if (getCoord("$PUCSORGRIGHT", &varCoord)) {
1243 writer->writeDouble(10, varCoord.x);
1244 writer->writeDouble(20, varCoord.y);
1245 writer->writeDouble(30, varCoord.z);
1246 } else {
1247 writer->writeDouble(10, 0.0);
1248 writer->writeDouble(20, 0.0);
1249 writer->writeDouble(30, 0.0);
1250 }
1251 writer->writeString(9, "$PUCSORGFRONT");
1252 if (getCoord("$PUCSORGFRONT", &varCoord)) {
1253 writer->writeDouble(10, varCoord.x);
1254 writer->writeDouble(20, varCoord.y);
1255 writer->writeDouble(30, varCoord.z);
1256 } else {
1257 writer->writeDouble(10, 0.0);
1258 writer->writeDouble(20, 0.0);
1259 writer->writeDouble(30, 0.0);
1260 }
1261 writer->writeString(9, "$PUCSORGBACK");
1262 if (getCoord("$PUCSORGBACK", &varCoord)) {
1263 writer->writeDouble(10, varCoord.x);
1264 writer->writeDouble(20, varCoord.y);
1265 writer->writeDouble(30, varCoord.z);
1266 } else {
1267 writer->writeDouble(10, 0.0);
1268 writer->writeDouble(20, 0.0);
1269 writer->writeDouble(30, 0.0);
1270 }
1271 } //end post r12 PUCS vars
1272
1273 writer->writeString(9, "$USERI1");
1274 if (getInt("$USERI1", &varInt))
1275 writer->writeInt16(70, varInt);
1276 else
1277 writer->writeInt16(70, 0);
1278 writer->writeString(9, "$USERI2");
1279 if (getInt("$USERI2", &varInt))
1280 writer->writeInt16(70, varInt);
1281 else
1282 writer->writeInt16(70, 0);
1283 writer->writeString(9, "$USERI3");
1284 if (getInt("$USERI3", &varInt))
1285 writer->writeInt16(70, varInt);
1286 else
1287 writer->writeInt16(70, 0);
1288 writer->writeString(9, "$USERI4");
1289 if (getInt("$USERI4", &varInt))
1290 writer->writeInt16(70, varInt);
1291 else
1292 writer->writeInt16(70, 0);
1293 writer->writeString(9, "$USERI5");
1294 if (getInt("$USERI5", &varInt))
1295 writer->writeInt16(70, varInt);
1296 else
1297 writer->writeInt16(70, 0);
1298 writer->writeString(9, "$USERR1");
1299 if (getDouble("$USERR1", &varDouble))
1300 writer->writeDouble(40, varDouble);
1301 else
1302 writer->writeDouble(40, 0.0);
1303 writer->writeString(9, "$USERR2");
1304 if (getDouble("$USERR2", &varDouble))
1305 writer->writeDouble(40, varDouble);
1306 else
1307 writer->writeDouble(40, 0.0);
1308 writer->writeString(9, "$USERR3");
1309 if (getDouble("$USERR3", &varDouble))
1310 writer->writeDouble(40, varDouble);
1311 else
1312 writer->writeDouble(40, 0.0);
1313 writer->writeString(9, "$USERR4");
1314 if (getDouble("$USERR4", &varDouble))
1315 writer->writeDouble(40, varDouble);
1316 else
1317 writer->writeDouble(40, 0.0);
1318 writer->writeString(9, "$USERR5");
1319 if (getDouble("$USERR5", &varDouble))
1320 writer->writeDouble(40, varDouble);
1321 else
1322 writer->writeDouble(40, 0.0);
1323 writer->writeString(9, "$WORLDVIEW");
1324 if (getInt("$WORLDVIEW", &varInt))
1325 writer->writeInt16(70, varInt);
1326 else
1327 writer->writeInt16(70, 1);
1328 writer->writeString(9, "$SHADEDGE");
1329 if (getInt("$SHADEDGE", &varInt))
1330 writer->writeInt16(70, varInt);
1331 else
1332 writer->writeInt16(70, 3);
1333 writer->writeString(9, "$SHADEDIF");
1334 if (getInt("$SHADEDIF", &varInt))
1335 writer->writeInt16(70, varInt);
1336 else
1337 writer->writeInt16(70, 70);
1338 writer->writeString(9, "$ISOLINES");
1339 if (getInt("$ISOLINES", &varInt))
1340 writer->writeInt16(70, varInt);
1341 else
1342 writer->writeInt16(70, 4);
1343 writer->writeString(9, "$FACETRES");
1344 if (getDouble("$FACETRES", &varDouble))
1345 writer->writeDouble(40, varDouble);
1346 else
1347 writer->writeDouble(40, 0.5);
1348 writer->writeString(9, "$TEXTQLTY");
1349 if (getInt("$TEXTQLTY", &varInt))
1350 writer->writeInt16(70, varInt);
1351 else
1352 writer->writeInt16(70, 50);
1353 writer->writeString(9, "$TILEMODE");
1354 if (getInt("$TILEMODE", &varInt))
1355 writer->writeInt16(70, varInt);
1356 else
1357 writer->writeInt16(70, 1);
1358 writer->writeString(9, "$MAXACTVP");
1359 if (getInt("$MAXACTVP", &varInt))
1360 writer->writeInt16(70, varInt);
1361 else
1362 writer->writeInt16(70, 64);
1363 if (ver > DRW::AC1009) { //begin post r12 PUCS vars
1364 writer->writeString(9, "$PINSBASE");
1365 if (getCoord("$PINSBASE", &varCoord)) {
1366 writer->writeDouble(10, varCoord.x);
1367 writer->writeDouble(20, varCoord.y);
1368 writer->writeDouble(30, varCoord.z);
1369 } else {
1370 writer->writeDouble(10, 0.0);
1371 writer->writeDouble(20, 0.0);
1372 writer->writeDouble(30, 0.0);
1373 }
1374 }
1375 writer->writeString(9, "$PLIMCHECK");
1376 if (getInt("$PLIMCHECK", &varInt))
1377 writer->writeInt16(70, varInt);
1378 else
1379 writer->writeInt16(70, 0);
1380 writer->writeString(9, "$PEXTMIN");
1381 if (getCoord("$PEXTMIN", &varCoord)) {
1382 writer->writeDouble(10, varCoord.x);
1383 writer->writeDouble(20, varCoord.y);
1384 writer->writeDouble(30, varCoord.z);
1385 } else {
1386 writer->writeDouble(10, 0.0);
1387 writer->writeDouble(20, 0.0);
1388 writer->writeDouble(30, 0.0);
1389 }
1390 writer->writeString(9, "$PEXTMAX");
1391 if (getCoord("$PEXTMAX", &varCoord)) {
1392 writer->writeDouble(10, varCoord.x);
1393 writer->writeDouble(20, varCoord.y);
1394 writer->writeDouble(30, varCoord.z);
1395 } else {
1396 writer->writeDouble(10, 0.0);
1397 writer->writeDouble(20, 0.0);
1398 writer->writeDouble(30, 0.0);
1399 }
1400
1401/* RLZ: moved to active VPORT, but can write in header if present*/
1402 if (getInt("$GRIDMODE", &varInt)) {
1403 writer->writeString(9, "$GRIDMODE");
1404 writer->writeInt16(70, varInt);
1405 }
1406 if (getInt("$SNAPSTYLE", &varInt)) {
1407 writer->writeString(9, "$SNAPSTYLE");
1408 writer->writeInt16(70, varInt);
1409 }
1410 if (getCoord("$GRIDUNIT", &varCoord)) {
1411 writer->writeString(9, "$GRIDUNIT");
1412 writer->writeDouble(10, varCoord.x);
1413 writer->writeDouble(20, varCoord.y);
1414 }
1415 if (getCoord("$VIEWCTR", &varCoord)) {
1416 writer->writeString(9, "$VIEWCTR");
1417 writer->writeDouble(10, varCoord.x);
1418 writer->writeDouble(20, varCoord.y);
1419 }
1420/* RLZ: moved to active VPORT, but can write in header if present*/
1421
1422 writer->writeString(9, "$PLIMMIN");
1423 if (getCoord("$PLIMMIN", &varCoord)) {
1424 writer->writeDouble(10, varCoord.x);
1425 writer->writeDouble(20, varCoord.y);
1426 } else {
1427 writer->writeDouble(10, 0.0);
1428 writer->writeDouble(20, 0.0);
1429 }
1430 writer->writeString(9, "$PLIMMAX");
1431 if (getCoord("$PLIMMAX", &varCoord)) {
1432 writer->writeDouble(10, varCoord.x);
1433 writer->writeDouble(20, varCoord.y);
1434 } else {
1435 writer->writeDouble(10, 297.0);
1436 writer->writeDouble(20, 210.0);
1437 }
1438 writer->writeString(9, "$UNITMODE");
1439 if (getInt("$UNITMODE", &varInt))
1440 writer->writeInt16(70, varInt);
1441 else
1442 writer->writeInt16(70, 0);
1443 writer->writeString(9, "$VISRETAIN");
1444 if (getInt("$VISRETAIN", &varInt))
1445 writer->writeInt16(70, varInt);
1446 else
1447 writer->writeInt16(70, 1);
1448 writer->writeString(9, "$PLINEGEN");
1449 if (getInt("$PLINEGEN", &varInt))
1450 writer->writeInt16(70, varInt);
1451 else
1452 writer->writeInt16(70, 0);
1453 writer->writeString(9, "$PSLTSCALE");
1454 if (getInt("$PSLTSCALE", &varInt))
1455 writer->writeInt16(70, varInt);
1456 else
1457 writer->writeInt16(70, 1);
1458 if (ver > DRW::AC1009){//start port r12 vars
1459 writer->writeString(9, "$TREEDEPTH");
1460 if (getInt("$TREEDEPTH", &varInt))
1461 writer->writeInt16(70, varInt);
1462 else
1463 writer->writeInt16(70, 3020);
1464 writer->writeString(9, "$CMLSTYLE");
1465 if (getStr("$CMLSTYLE", &varStr))
1466 if (ver == DRW::AC1009)
1467 writer->writeUtf8Caps(2, varStr);
1468 else
1469 writer->writeUtf8String(2, varStr);
1470 else
1471 writer->writeString(2, "Standard");
1472 writer->writeString(9, "$CMLJUST");
1473 if (getInt("$CMLJUST", &varInt))
1474 writer->writeInt16(70, varInt);
1475 else
1476 writer->writeInt16(70, 0);
1477 writer->writeString(9, "$CMLSCALE");
1478 if (getDouble("$CMLSCALE", &varDouble))
1479 writer->writeDouble(40, varDouble);
1480 else
1481 writer->writeDouble(40, 20.0);
1482 writer->writeString(9, "$PROXYGRAPHICS");
1483 if (getInt("$PROXYGRAPHICS", &varInt) || getInt("$PROXIGRAPHICS", &varInt))
1484 writer->writeInt16(70, varInt);
1485 else
1486 writer->writeInt16(70, 1);
1487 int insunits {Units::None};
1488 getInt("$INSUNITS", &insunits); // get $INSUNITS now to evaluate $MEASUREMENT
1489 int measurementValue = measurement(insunits);
1490 if (getInt("$MEASUREMENT", &varInt))
1491 measurementValue = varInt;
1492 writer->writeString(9, "$MEASUREMENT");
1493 writer->writeInt16(70, measurementValue);
1494 writer->writeString(9, "$CELWEIGHT");
1495 if (getInt("$CELWEIGHT", &varInt))
1496 writer->writeInt16(370, varInt);
1497 else
1498 writer->writeInt16(370, -1);
1499 writer->writeString(9, "$ENDCAPS");
1500 if (getInt("$ENDCAPS", &varInt))
1501 writer->writeInt16(280, varInt);
1502 else
1503 writer->writeInt16(280, 0);
1504 writer->writeString(9, "$JOINSTYLE");
1505 if (getInt("$JOINSTYLE", &varInt))
1506 writer->writeInt16(280, varInt);
1507 else
1508 writer->writeInt16(280, 0);
1509 writer->writeString(9, "$LWDISPLAY"); //RLZ bool flag, verify in bin version
1510 if (getInt("$LWDISPLAY", &varInt))
1511 writer->writeBool(290, varInt != 0);
1512 else
1513 writer->writeBool(290, false);
1514 if (ver > DRW::AC1014) {
1515 writer->writeString(9, "$INSUNITS");
1516 writer->writeInt16(70, insunits); // already fetched above for $MEASUREMENT
1517 }
1518 writer->writeString(9, "$HYPERLINKBASE");
1519 if (getStr("$HYPERLINKBASE", &varStr))
1520 if (ver == DRW::AC1009)
1521 writer->writeUtf8Caps(1, varStr);
1522 else
1523 writer->writeUtf8String(1, varStr);
1524 else
1525 writer->writeString(1, "");
1526 writer->writeString(9, "$STYLESHEET");
1527 if (getStr("$STYLESHEET", &varStr))
1528 if (ver == DRW::AC1009)
1529 writer->writeUtf8Caps(1, varStr);
1530 else
1531 writer->writeUtf8String(1, varStr);
1532 else
1533 writer->writeString(1, "");
1534 writer->writeString(9, "$XEDIT"); //RLZ bool flag, verify in bin version
1535 if (getInt("$XEDIT", &varInt))
1536 writer->writeBool(290, varInt != 0);
1537 else
1538 writer->writeBool(290, true);
1539 writer->writeString(9, "$CEPSNTYPE");
1540 if (getInt("$CEPSNTYPE", &varInt))
1541 writer->writeInt16(380, varInt);
1542 else
1543 writer->writeInt16(380, 0);
1544 writer->writeString(9, "$PSTYLEMODE"); //RLZ bool flag, verify in bin version
1545 if (getInt("$PSTYLEMODE", &varInt))
1546 writer->writeBool(290, varInt != 0);
1547 else
1548 writer->writeBool(290, true);
1549 if (ver > DRW::AC1014) {
1550 static const std::string nullGuid = "{00000000-0000-0000-0000-000000000000}";
1551 writer->writeString(9, "$FINGERPRINTGUID");
1552 if (getStr("$FINGERPRINTGUID", &varStr))
1553 writer->writeUtf8String(2, varStr);
1554 else
1555 writer->writeString(2, nullGuid);
1556 writer->writeString(9, "$VERSIONGUID");
1557 if (getStr("$VERSIONGUID", &varStr))
1558 writer->writeUtf8String(2, varStr);
1559 else
1560 writer->writeString(2, nullGuid);
1561 }
1562 writer->writeString(9, "$EXTNAMES"); //RLZ bool flag, verify in bin version
1563 if (getInt("$EXTNAMES", &varInt))
1564 writer->writeBool(290, varInt != 0);
1565 else
1566 writer->writeBool(290, true);
1567 writer->writeString(9, "$PSVPSCALE");
1568 if (getDouble("$PSVPSCALE", &varDouble))
1569 writer->writeDouble(40, varDouble);
1570 else
1571 writer->writeDouble(40, 0.0);
1572 writer->writeString(9, "$TSTACKALIGN");
1573 if (getInt("$TSTACKALIGN", &varInt))
1574 writer->writeInt16(70, varInt);
1575 else
1576 writer->writeInt16(70, 1);
1577 writer->writeString(9, "$TSTACKSIZE");
1578 if (getInt("$TSTACKSIZE", &varInt))
1579 writer->writeInt16(70, varInt);
1580 else
1581 writer->writeInt16(70, 70);
1582 writer->writeString(9, "$OLESTARTUP"); //RLZ bool flag, verify in bin version
1583 if (getInt("$OLESTARTUP", &varInt))
1584 writer->writeBool(290, varInt != 0);
1585 else
1586 writer->writeBool(290, false);
1587 }
1588 if (ver > DRW::AC1015) {// and post v2004 vars
1589 writer->writeString(9, "$SORTENTS");
1590 if (getInt("$SORTENTS", &varInt))
1591 writer->writeInt16(280, varInt);
1592 else
1593 writer->writeInt16(280, 127);
1594 writer->writeString(9, "$INDEXCTL");
1595 if (getInt("$INDEXCTL", &varInt))
1596 writer->writeInt16(280, varInt);
1597 else
1598 writer->writeInt16(280, 0);
1599 writer->writeString(9, "$HIDETEXT");
1600 if (getInt("$HIDETEXT", &varInt))
1601 writer->writeInt16(280, varInt);
1602 else
1603 writer->writeInt16(280, 1);
1604 writer->writeString(9, "$XCLIPFRAME"); //RLZ bool flag, verify in bin version
1605 if (ver > DRW::AC1021) {
1606 if (getInt("$XCLIPFRAME", &varInt))
1607 writer->writeInt16(280, varInt);
1608 else
1609 writer->writeInt16(280, 0);
1610 } else {
1611 if (getInt("$XCLIPFRAME", &varInt))
1612 writer->writeBool(290, varInt != 0);
1613 else
1614 writer->writeBool(290, false);
1615 }
1616 writer->writeString(9, "$HALOGAP");
1617 if (getInt("$HALOGAP", &varInt))
1618 writer->writeInt16(280, varInt);
1619 else
1620 writer->writeInt16(280, 0);
1621 writer->writeString(9, "$OBSCOLOR");
1622 if (getInt("$OBSCOLOR", &varInt) || getInt("$OBSCUREDCOLOR", &varInt))
1623 writer->writeInt16(70, varInt);
1624 else
1625 writer->writeInt16(70, 257);
1626 writer->writeString(9, "$OBSLTYPE");
1627 if (getInt("$OBSLTYPE", &varInt) || getInt("$OBSCUREDLTYPE", &varInt))
1628 writer->writeInt16(280, varInt);
1629 else
1630 writer->writeInt16(280, 0);
1631 writer->writeString(9, "$INTERSECTIONDISPLAY");
1632 if (getInt("$INTERSECTIONDISPLAY", &varInt))
1633 writer->writeInt16(280, varInt);
1634 else
1635 writer->writeInt16(280, 0);
1636 writer->writeString(9, "$INTERSECTIONCOLOR");
1637 if (getInt("$INTERSECTIONCOLOR", &varInt))
1638 writer->writeInt16(70, varInt);
1639 else
1640 writer->writeInt16(70, 257);
1641 writer->writeString(9, "$DIMASSOC");
1642 if (getInt("$DIMASSOC", &varInt))
1643 writer->writeInt16(280, varInt);
1644 else
1645 writer->writeInt16(280, 1);
1646 writer->writeString(9, "$PROJECTNAME");
1647 if (getStr("$PROJECTNAME", &varStr))
1648 writer->writeUtf8String(1, varStr);
1649 else
1650 writer->writeString(1, "");
1651 }
1652 if (ver > DRW::AC1018) {// and post v2007 vars
1653 writer->writeString(9, "$CAMERADISPLAY"); //RLZ bool flag, verify in bin version
1654 if (getInt("$CAMERADISPLAY", &varInt))
1655 writer->writeBool(290, varInt != 0);
1656 else
1657 writer->writeBool(290, false);
1658 writer->writeString(9, "$LENSLENGTH");
1659 if (getDouble("$LENSLENGTH", &varDouble))
1660 writer->writeDouble(40, varDouble);
1661 else
1662 writer->writeDouble(40, 50.0);
1663 writer->writeString(9, "$CAMERAHEIGHT");
1664 if (getDouble("$CAMERAHEIGHT", &varDouble))
1665 writer->writeDouble(40, varDouble);
1666 else
1667 writer->writeDouble(40, 0.0);
1668 writer->writeString(9, "$STEPSPERSEC");
1669 if (getDouble("$STEPSPERSEC", &varDouble))
1670 writer->writeDouble(40, varDouble);
1671 else
1672 writer->writeDouble(40, 2.0);
1673 writer->writeString(9, "$STEPSIZE");
1674 if (getDouble("$STEPSIZE", &varDouble))
1675 writer->writeDouble(40, varDouble);
1676 else
1677 writer->writeDouble(40, 50.0);
1678 writer->writeString(9, "$3DDWFPREC");
1679 if (getDouble("$3DDWFPREC", &varDouble))
1680 writer->writeDouble(40, varDouble);
1681 else
1682 writer->writeDouble(40, 2.0);
1683 writer->writeString(9, "$PSOLWIDTH");
1684 if (getDouble("$PSOLWIDTH", &varDouble))
1685 writer->writeDouble(40, varDouble);
1686 else
1687 writer->writeDouble(40, 5.0);
1688 writer->writeString(9, "$PSOLHEIGHT");
1689 if (getDouble("$PSOLHEIGHT", &varDouble))
1690 writer->writeDouble(40, varDouble);
1691 else
1692 writer->writeDouble(40, 80.0);
1693 writer->writeString(9, "$LOFTANG1");
1694 if (getDouble("$LOFTANG1", &varDouble))
1695 writer->writeDouble(40, varDouble);
1696 else
1697 writer->writeDouble(40, M_PI_21.57079632679489661923);
1698 writer->writeString(9, "$LOFTANG2");
1699 if (getDouble("$LOFTANG2", &varDouble))
1700 writer->writeDouble(40, varDouble);
1701 else
1702 writer->writeDouble(40, M_PI_21.57079632679489661923);
1703 writer->writeString(9, "$LOFTMAG1");
1704 if (getDouble("$LOFTMAG1", &varDouble))
1705 writer->writeDouble(40, varDouble);
1706 else
1707 writer->writeDouble(40, 0.0);
1708 writer->writeString(9, "$LOFTMAG2");
1709 if (getDouble("$LOFTMAG2", &varDouble))
1710 writer->writeDouble(40, varDouble);
1711 else
1712 writer->writeDouble(40, 0.0);
1713 writer->writeString(9, "$LOFTPARAM");
1714 if (getInt("$LOFTPARAM", &varInt))
1715 writer->writeInt16(70, varInt);
1716 else
1717 writer->writeInt16(70, 7);
1718 writer->writeString(9, "$LOFTNORMALS");
1719 if (getInt("$LOFTNORMALS", &varInt))
1720 writer->writeInt16(280, varInt);
1721 else
1722 writer->writeInt16(280, 1);
1723 writer->writeString(9, "$LATITUDE");
1724 if (getDouble("$LATITUDE", &varDouble))
1725 writer->writeDouble(40, varDouble);
1726 else
1727 writer->writeDouble(40, 1.0);
1728 writer->writeString(9, "$LONGITUDE");
1729 if (getDouble("$LONGITUDE", &varDouble))
1730 writer->writeDouble(40, varDouble);
1731 else
1732 writer->writeDouble(40, 1.0);
1733 writer->writeString(9, "$NORTHDIRECTION");
1734 if (getDouble("$NORTHDIRECTION", &varDouble))
1735 writer->writeDouble(40, varDouble);
1736 else
1737 writer->writeDouble(40, 0.0);
1738 writer->writeString(9, "$TIMEZONE");
1739 if (getInt("$TIMEZONE", &varInt))
1740 writer->writeInt16(70, varInt);
1741 else
1742 writer->writeInt16(70, -8000);
1743 writer->writeString(9, "$LIGHTGLYPHDISPLAY");
1744 if (getInt("$LIGHTGLYPHDISPLAY", &varInt))
1745 writer->writeInt16(280, varInt);
1746 else
1747 writer->writeInt16(280, 1);
1748 writer->writeString(9, "$TILEMODELIGHTSYNCH");
1749 if (getInt("$TILEMODELIGHTSYNCH", &varInt))
1750 writer->writeInt16(280, varInt);
1751 else
1752 writer->writeInt16(280, 1);
1753 //$CMATERIAL is a handle
1754 writer->writeString(9, "$SOLIDHIST");
1755 if (getInt("$SOLIDHIST", &varInt))
1756 writer->writeInt16(280, varInt);
1757 else
1758 writer->writeInt16(280, 1);
1759 writer->writeString(9, "$SHOWHIST");
1760 if (getInt("$SHOWHIST", &varInt))
1761 writer->writeInt16(280, varInt);
1762 else
1763 writer->writeInt16(280, 1);
1764 writer->writeString(9, "$DWFFRAME");
1765 if (getInt("$DWFFRAME", &varInt))
1766 writer->writeInt16(280, varInt);
1767 else
1768 writer->writeInt16(280, 2);
1769 writer->writeString(9, "$DGNFRAME");
1770 if (getInt("$DGNFRAME", &varInt))
1771 writer->writeInt16(280, varInt);
1772 else
1773 writer->writeInt16(280, 0);
1774 writer->writeString(9, "$REALWORLDSCALE"); //RLZ bool flag, verify in bin version
1775 if (getInt("$REALWORLDSCALE", &varInt))
1776 writer->writeBool(290, varInt != 0);
1777 else
1778 writer->writeBool(290, true);
1779 writer->writeString(9, "$INTERFERECOLOR");
1780 if (getInt("$INTERFERECOLOR", &varInt))
1781 writer->writeInt16(62, varInt);
1782 else
1783 writer->writeInt16(62, 1);
1784 //$INTERFEREOBJVS is a handle
1785 //$INTERFEREVPVS is a handle
1786 writer->writeString(9, "$CSHADOW");
1787 if (getInt("$CSHADOW", &varInt))
1788 writer->writeInt16(280, varInt);
1789 else
1790 writer->writeInt16(280, 0);
1791 writer->writeString(9, "$SHADOWPLANELOCATION");
1792 if (getDouble("$SHADOWPLANELOCATION", &varDouble))
1793 writer->writeDouble(40, varDouble);
1794 else
1795 writer->writeDouble(40, 0.0);
1796 }
1797
1798#ifdef DRW_DBG
1799 for ( auto it=vars.begin() ; it != vars.end(); ++it ){
1800 DRW_DBG((*it).first)DRW_dbg::dbg((*it).first); DRW_DBG("\n")DRW_dbg::dbg("\n");
1801 }
1802#endif
1803}
1804
1805void DRW_Header::addDouble(std::string key, double value, int code){
1806 storeVar(key, new DRW_Variant(code, value));
1807}
1808
1809void DRW_Header::addInt(std::string key, int value, int code){
1810 storeVar(key, new DRW_Variant(code, value));
1811}
1812
1813void DRW_Header::addStr(std::string key, std::string value, int code){
1814 storeVar(key, new DRW_Variant(code, value));
1815}
1816
1817void DRW_Header::addCoord(std::string key, DRW_Coord value, int code){
1818 storeVar(key, new DRW_Variant(code, value));
1819}
1820
1821// Mirror the DWG-encoder findVar() convention: DXF reader stores "$NAME" keys,
1822// DWG parser stores bare "NAME" keys. Try the queried form first; if not
1823// found, try the alternate ($-stripped or $-added) form so both read paths
1824// can feed the DXF writer without key-convention mismatches.
1825static auto varFindAlternate(std::unordered_map<std::string, DRW_Variant*>& vars,
1826 const std::string& key)
1827 -> std::unordered_map<std::string, DRW_Variant*>::iterator
1828{
1829 auto it = vars.find(key);
1830 if (it != vars.end())
1831 return it;
1832 std::string alt = (!key.empty() && key[0] == '$') ? key.substr(1) : ("$" + key);
1833 return vars.find(alt);
1834}
1835
1836bool DRW_Header::getDouble(std::string key, double *varDouble){
1837 bool result = false;
1838 auto it = varFindAlternate(vars, key);
1839 if (it != vars.end()) {
1840 DRW_Variant *var = (*it).second;
1841 if (var != nullptr && var->type() == DRW_Variant::DOUBLE) {
1842 *varDouble = var->content.d;
1843 result = true;
1844 }
1845 delete var;
1846 vars.erase(it);
1847 }
1848 return result;
1849}
1850
1851bool DRW_Header::getInt(std::string key, int *varInt){
1852 bool result = false;
1853 auto it = varFindAlternate(vars, key);
1854 if (it != vars.end()) {
1855 DRW_Variant *var = (*it).second;
1856 if (var != nullptr && var->type() == DRW_Variant::INTEGER) {
1857 *varInt = var->content.i;
1858 result = true;
1859 }
1860 delete var;
1861 vars.erase(it);
1862 }
1863 return result;
1864}
1865
1866bool DRW_Header::getStr(std::string key, std::string *varStr){
1867 bool result = false;
1868 auto it = varFindAlternate(vars, key);
1869 if (it != vars.end()) {
1870 DRW_Variant *var = (*it).second;
1871 if (var != nullptr && var->type() == DRW_Variant::STRING) {
1872 *varStr = *var->content.s;
1873 result = true;
1874 }
1875 delete var;
1876 vars.erase(it);
1877 }
1878 return result;
1879}
1880
1881bool DRW_Header::getCoord(std::string key, DRW_Coord *varCoord){
1882 bool result = false;
1883 auto it = varFindAlternate(vars, key);
1884 if (it != vars.end()) {
1885 DRW_Variant *var = (*it).second;
1886 if (var != nullptr && var->type() == DRW_Variant::COORD) {
1887 *varCoord = *var->content.v;
1888 result = true;
1889 }
1890 delete var;
1891 vars.erase(it);
1892 }
1893 return result;
1894}
1895
1896bool DRW_Header::parseDwg(DRW::Version version, dwgBuffer *buf,
1897 dwgBuffer *hBbuf,
1898 std::uint8_t maintenanceVersion) {
1899 if (buf == nullptr || hBbuf == nullptr)
1900 return false;
1901
1902 // Header parsing fills owning raw-pointer maps through a legacy layout.
1903 // Publish none of that state when a malformed input or allocation
1904 // exception interrupts the implementation below.
1905 clearVars();
1906 curr = nullptr;
1907 name.clear();
1908 try {
1909 const bool parsed = parseDwgImpl(version, buf, hBbuf,
1910 maintenanceVersion);
1911 const bool valid = parsed && buf->isGood() && hBbuf->isGood();
1912 if (!valid) {
1913 clearVars();
1914 curr = nullptr;
1915 name.clear();
1916 }
1917 return valid;
1918 } catch (...) {
1919 clearVars();
1920 curr = nullptr;
1921 name.clear();
1922 buf->invalidate();
1923 if (hBbuf != buf)
1924 hBbuf->invalidate();
1925 return false;
1926 }
1927}
1928
1929bool DRW_Header::parseDwgImpl(DRW::Version version, dwgBuffer *buf,
1930 dwgBuffer *hBbuf,
1931 std::uint8_t maintenanceVersion) {
1932 bool result = true;
1933 const std::uint64_t headerStart = buf->getPosition();
1934 std::uint32_t size = buf->getRawLong32();
1935 std::uint32_t bitSize = 0;
1936 std::uint64_t endBitPos = 160; //start bit: 16 sentinel + 4 size
1937 DRW_DBG("\nbyte size of data: ")DRW_dbg::dbg("\nbyte size of data: "); DRW_DBG(size)DRW_dbg::dbg(size);
1938 if ((DRW::AC1024 <= version && 3 < maintenanceVersion)
1939 || DRW::AC1032 <= version) { //2010+ MV>3
1940 std::uint32_t hSize = buf->getRawLong32();
1941 endBitPos += 32; //start bit: + 4 height size
1942 DRW_DBG("\n2010+ & MV> 3, height 32b: ")DRW_dbg::dbg("\n2010+ & MV> 3, height 32b: "); DRW_DBG(hSize)DRW_dbg::dbg(hSize);
1943 }
1944//RLZ TODO add $ACADVER var & $DWGCODEPAGE & $MEASUREMENT
1945//RLZ TODO EN 2000 falta $CELWEIGHT, $ENDCAPS, $EXTNAMES $JOINSTYLE $LWDISPLAY $PSTYLEMODE $TDUCREATE $TDUUPDATE $XEDIT
1946
1947 //bit size of data needed to locate start of string stream in 2007+
1948 //and mark the start of handle stream
1949 //header is one object reads data and continue read strings ???
1950 if (version > DRW::AC1018) {//2007+
1951 bitSize = buf->getRawLong32();
1952 DRW_DBG("\nsize in bits: ")DRW_dbg::dbg("\nsize in bits: "); DRW_DBG(bitSize)DRW_dbg::dbg(bitSize);
1953 endBitPos += bitSize;
1954 hBbuf->setPosition(endBitPos >>3);
1955 hBbuf->setBitPos(endBitPos&7);
1956 }
1957
1958 if (version > DRW::AC1024) {//2013+
1959 std::uint64_t requiredVersions = buf->getBitLongLong();
1960 DRW_DBG("\nREQUIREDVERSIONS var: ")DRW_dbg::dbg("\nREQUIREDVERSIONS var: "); DRW_DBG(requiredVersions)DRW_dbg::dbg(requiredVersions);
1961 }
1962 DRW_DBG("\nUnknown1: ")DRW_dbg::dbg("\nUnknown1: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
1963 DRW_DBG("\nUnknown2: ")DRW_dbg::dbg("\nUnknown2: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
1964 DRW_DBG("\nUnknown3: ")DRW_dbg::dbg("\nUnknown3: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
1965 DRW_DBG("\nUnknown4: ")DRW_dbg::dbg("\nUnknown4: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
1966 if (version < DRW::AC1021) {//2007-
1967 DRW_DBG("\nUnknown text1: ")DRW_dbg::dbg("\nUnknown text1: "); DRW_DBG(buf->getCP8Text())DRW_dbg::dbg(buf->getCP8Text());
1968 DRW_DBG("\nUnknown text2: ")DRW_dbg::dbg("\nUnknown text2: "); DRW_DBG(buf->getCP8Text())DRW_dbg::dbg(buf->getCP8Text());
1969 DRW_DBG("\nUnknown text3: ")DRW_dbg::dbg("\nUnknown text3: "); DRW_DBG(buf->getCP8Text())DRW_dbg::dbg(buf->getCP8Text());
1970 DRW_DBG("\nUnknown text4: ")DRW_dbg::dbg("\nUnknown text4: "); DRW_DBG(buf->getCP8Text())DRW_dbg::dbg(buf->getCP8Text());
1971 }
1972 DRW_DBG("\nUnknown long1 (24L): ")DRW_dbg::dbg("\nUnknown long1 (24L): "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
1973 DRW_DBG("\nUnknown long2 (0L): ")DRW_dbg::dbg("\nUnknown long2 (0L): "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
1974 if (version < DRW::AC1015) {//pre 2000
1975 DRW_DBG("\nUnknown short (0): ")DRW_dbg::dbg("\nUnknown short (0): "); DRW_DBG(buf->getBitShort())DRW_dbg::dbg(buf->getBitShort());
1976 }
1977 if (version < DRW::AC1018) {//pre 2004
1978 dwgHandle hcv = hBbuf->getHandle();
1979 DRW_DBG("\nhandle of current view: ")DRW_dbg::dbg("\nhandle of current view: "); DRW_DBGHL(hcv.code, hcv.size, hcv.ref)DRW_dbg::dbgHL(hcv.code, hcv.size, hcv.ref);
1980 }
1981 storeVar("DIMASO", new DRW_Variant(70, buf->getBit()));
1982 storeVar("DIMSHO", new DRW_Variant(70, buf->getBit()));
1983 if (version < DRW::AC1015) {//pre 2000
1984 storeVar("DIMSAV", new DRW_Variant(70, buf->getBit()));
1985 }
1986 storeVar("PLINEGEN", new DRW_Variant(70, buf->getBit()));
1987 storeVar("ORTHOMODE", new DRW_Variant(70, buf->getBit()));
1988 storeVar("REGENMODE", new DRW_Variant(70, buf->getBit()));
1989 storeVar("FILLMODE", new DRW_Variant(70, buf->getBit()));
1990 storeVar("QTEXTMODE", new DRW_Variant(70, buf->getBit()));
1991 storeVar("PSLTSCALE", new DRW_Variant(70, buf->getBit()));
1992 storeVar("LIMCHECK", new DRW_Variant(70, buf->getBit()));
1993 if (version < DRW::AC1015) {//pre 2000
1994 storeVar("BLIPMODE", new DRW_Variant(70, buf->getBit()));
1995 }
1996 if (version > DRW::AC1015) {//2004+
1997 DRW_DBG("\nUndocumented: ")DRW_dbg::dbg("\nUndocumented: "); DRW_DBG(buf->getBit())DRW_dbg::dbg(buf->getBit());
1998 }
1999 storeVar("USRTIMER", new DRW_Variant(70, buf->getBit()));
2000 storeVar("SKPOLY", new DRW_Variant(70, buf->getBit()));
2001 storeVar("ANGDIR", new DRW_Variant(70, buf->getBit()));
2002 storeVar("SPLFRAME", new DRW_Variant(70, buf->getBit()));
2003 if (version < DRW::AC1015) {//pre 2000
2004 storeVar("ATTREQ", new DRW_Variant(70, buf->getBit()));
2005 storeVar("ATTDIA", new DRW_Variant(70, buf->getBit()));
2006 }
2007 storeVar("MIRRTEXT", new DRW_Variant(70, buf->getBit()));
2008 storeVar("WORLDVIEW", new DRW_Variant(70, buf->getBit()));
2009 if (version < DRW::AC1015) {//pre 2000
2010 storeVar("WIREFRAME", new DRW_Variant(70, buf->getBit()));
2011 }
2012 storeVar("TILEMODE", new DRW_Variant(70, buf->getBit()));
2013 storeVar("PLIMCHECK", new DRW_Variant(70, buf->getBit()));
2014 storeVar("VISRETAIN", new DRW_Variant(70, buf->getBit()));
2015 if (version < DRW::AC1015) {//pre 2000
2016 storeVar("DELOBJ", new DRW_Variant(70, buf->getBit()));
2017 }
2018 storeVar("DISPSILH", new DRW_Variant(70, buf->getBit()));
2019 storeVar("PELLIPSE", new DRW_Variant(70, buf->getBit()));
2020 storeVar("PROXIGRAPHICS", new DRW_Variant(70, buf->getBitShort()));//RLZ short or bit??
2021 if (version < DRW::AC1015) {//pre 2000
2022 storeVar("DRAGMODE", new DRW_Variant(70, buf->getBitShort()));//RLZ short or bit??
2023 }
2024 storeVar("TREEDEPTH", new DRW_Variant(70, buf->getBitShort()));//RLZ short or bit??
2025 storeVar("LUNITS", new DRW_Variant(70, buf->getBitShort()));
2026 storeVar("LUPREC", new DRW_Variant(70, buf->getBitShort()));
2027 storeVar("AUNITS", new DRW_Variant(70, buf->getBitShort()));
2028 storeVar("AUPREC", new DRW_Variant(70, buf->getBitShort()));
2029 if (version < DRW::AC1015) {//pre 2000
2030 storeVar("OSMODE", new DRW_Variant(70, buf->getBitShort()));
2031 }
2032 storeVar("ATTMODE", new DRW_Variant(70, buf->getBitShort()));
2033 if (version < DRW::AC1015) {//pre 2000
2034 storeVar("COORDS", new DRW_Variant(70, buf->getBitShort()));
2035 }
2036 storeVar("PDMODE", new DRW_Variant(70, buf->getBitShort()));
2037 if (version < DRW::AC1015) {//pre 2000
2038 storeVar("PICKSTYLE", new DRW_Variant(70, buf->getBitShort()));
2039 }
2040 if (version > DRW::AC1015) {//2004+
2041 DRW_DBG("\nUnknown long 1: ")DRW_dbg::dbg("\nUnknown long 1: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2042 DRW_DBG("\nUnknown long 2: ")DRW_dbg::dbg("\nUnknown long 2: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2043 DRW_DBG("\nUnknown long 3: ")DRW_dbg::dbg("\nUnknown long 3: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2044 }
2045 storeVar("USERI1", new DRW_Variant(70, buf->getBitShort()));
2046 storeVar("USERI2", new DRW_Variant(70, buf->getBitShort()));
2047 storeVar("USERI3", new DRW_Variant(70, buf->getBitShort()));
2048 storeVar("USERI4", new DRW_Variant(70, buf->getBitShort()));
2049 storeVar("USERI5", new DRW_Variant(70, buf->getBitShort()));
2050 storeVar("SPLINESEGS", new DRW_Variant(70, buf->getBitShort()));
2051 storeVar("SURFU", new DRW_Variant(70, buf->getBitShort()));
2052 storeVar("SURFV", new DRW_Variant(70, buf->getBitShort()));
2053 storeVar("SURFTYPE", new DRW_Variant(70, buf->getBitShort()));
2054 storeVar("SURFTAB1", new DRW_Variant(70, buf->getBitShort()));
2055 storeVar("SURFTAB2", new DRW_Variant(70, buf->getBitShort()));
2056 storeVar("SPLINETYPE", new DRW_Variant(70, buf->getBitShort()));
2057 storeVar("SHADEDGE", new DRW_Variant(70, buf->getBitShort()));
2058 storeVar("SHADEDIF", new DRW_Variant(70, buf->getBitShort()));
2059 storeVar("UNITMODE", new DRW_Variant(70, buf->getBitShort()));
2060 storeVar("MAXACTVP", new DRW_Variant(70, buf->getBitShort()));
2061 storeVar("ISOLINES", new DRW_Variant(70, buf->getBitShort()));//////////////////
2062 storeVar("CMLJUST", new DRW_Variant(70, buf->getBitShort()));
2063 storeVar("TEXTQLTY", new DRW_Variant(70, buf->getBitShort()));/////////////////////
2064 storeVar("LTSCALE", new DRW_Variant(40, buf->getBitDouble()));
2065 storeVar("TEXTSIZE", new DRW_Variant(40, buf->getBitDouble()));
2066 storeVar("TRACEWID", new DRW_Variant(40, buf->getBitDouble()));
2067 storeVar("SKETCHINC", new DRW_Variant(40, buf->getBitDouble()));
2068 storeVar("FILLETRAD", new DRW_Variant(40, buf->getBitDouble()));
2069 storeVar("THICKNESS", new DRW_Variant(40, buf->getBitDouble()));
2070 storeVar("ANGBASE", new DRW_Variant(50, buf->getBitDouble()));
2071 storeVar("PDSIZE", new DRW_Variant(40, buf->getBitDouble()));
2072 storeVar("PLINEWID", new DRW_Variant(40, buf->getBitDouble()));
2073 storeVar("USERR1", new DRW_Variant(40, buf->getBitDouble()));
2074 storeVar("USERR2", new DRW_Variant(40, buf->getBitDouble()));
2075 storeVar("USERR3", new DRW_Variant(40, buf->getBitDouble()));
2076 storeVar("USERR4", new DRW_Variant(40, buf->getBitDouble()));
2077 storeVar("USERR5", new DRW_Variant(40, buf->getBitDouble()));
2078 storeVar("CHAMFERA", new DRW_Variant(40, buf->getBitDouble()));
2079 storeVar("CHAMFERB", new DRW_Variant(40, buf->getBitDouble()));
2080 storeVar("CHAMFERC", new DRW_Variant(40, buf->getBitDouble()));
2081 storeVar("CHAMFERD", new DRW_Variant(40, buf->getBitDouble()));
2082 storeVar("FACETRES", new DRW_Variant(40, buf->getBitDouble()));/////////////////////////
2083 storeVar("CMLSCALE", new DRW_Variant(40, buf->getBitDouble()));
2084 storeVar("CELTSCALE", new DRW_Variant(40, buf->getBitDouble()));
2085 if (version < DRW::AC1021) {//2004-
2086 storeVar("MENU", new DRW_Variant(1, buf->getCP8Text()));
2087 }
2088 // DWG header time variables are stored as two 32-bit ints: julian day +
2089 // milliseconds since midnight UTC. DXF/DXF-API convention is the canonical
2090 // double `julianDay + msec/86_400_000.0`, so combine them with that ratio
2091 // (NOT the historic "divide by 10 until <1" loop, which produced lossy
2092 // and non-deterministic noise for any wall-clock time).
2093 // Keep kMsecPerDay inside the lambda: MSVC rejects uncaptured constexpr
2094 // locals in C++17 lambdas (error C3493).
2095 auto readJulianDate = [buf]() {
2096 constexpr double kMsecPerDay = 86400000.0;
2097 const std::int32_t day = buf->getBitLong();
2098 const std::int32_t msec = buf->getBitLong();
2099 return static_cast<double>(day) + static_cast<double>(msec) / kMsecPerDay;
2100 };
2101 storeVar("TDCREATE", new DRW_Variant(40, readJulianDate()));
2102 storeVar("TDUPDATE", new DRW_Variant(40, readJulianDate()));
2103 if (version > DRW::AC1015) {//2004+
2104 DRW_DBG("\nUnknown long 4: ")DRW_dbg::dbg("\nUnknown long 4: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2105 DRW_DBG("\nUnknown long 5: ")DRW_dbg::dbg("\nUnknown long 5: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2106 DRW_DBG("\nUnknown long 6: ")DRW_dbg::dbg("\nUnknown long 6: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2107 }
2108 storeVar("TDINDWG", new DRW_Variant(40, readJulianDate()));
2109 storeVar("TDUSRTIMER", new DRW_Variant(40, readJulianDate()));
2110 storeVar("CECOLOR", new DRW_Variant(62, buf->getCmColor(version)));//RLZ: TODO read CMC or EMC color
2111 dwgHandle HANDSEED = buf->getHandle();//always present in data stream
2112 DRW_DBG("\nHANDSEED: ")DRW_dbg::dbg("\nHANDSEED: "); DRW_DBGHL(HANDSEED.code, HANDSEED.size, HANDSEED.ref)DRW_dbg::dbgHL(HANDSEED.code, HANDSEED.size, HANDSEED.ref);
2113 handSeed = HANDSEED.ref;
2114 dwgHandle CLAYER = hBbuf->getHandle();
2115 DRW_DBG("\nCLAYER: ")DRW_dbg::dbg("\nCLAYER: "); DRW_DBGHL(CLAYER.code, CLAYER.size, CLAYER.ref)DRW_dbg::dbgHL(CLAYER.code, CLAYER.size, CLAYER.ref);
2116 clayerHandle = CLAYER.ref;
2117 dwgHandle TEXTSTYLE = hBbuf->getHandle();
2118 DRW_DBG("\nTEXTSTYLE: ")DRW_dbg::dbg("\nTEXTSTYLE: "); DRW_DBGHL(TEXTSTYLE.code, TEXTSTYLE.size, TEXTSTYLE.ref)DRW_dbg::dbgHL(TEXTSTYLE.code, TEXTSTYLE.size, TEXTSTYLE.ref);
2119 dwgHandle CELTYPE = hBbuf->getHandle();
2120 DRW_DBG("\nCELTYPE: ")DRW_dbg::dbg("\nCELTYPE: "); DRW_DBGHL(CELTYPE.code, CELTYPE.size, CELTYPE.ref)DRW_dbg::dbgHL(CELTYPE.code, CELTYPE.size, CELTYPE.ref);
2121 if (version > DRW::AC1018) {//2007+
2122 dwgHandle CMATERIAL = hBbuf->getHandle();
2123 DRW_DBG("\nCMATERIAL: ")DRW_dbg::dbg("\nCMATERIAL: "); DRW_DBGHL(CMATERIAL.code, CMATERIAL.size, CMATERIAL.ref)DRW_dbg::dbgHL(CMATERIAL.code, CMATERIAL.size, CMATERIAL.ref);
2124 }
2125 dwgHandle DIMSTYLE = hBbuf->getHandle();
2126 DRW_DBG("\nDIMSTYLE: ")DRW_dbg::dbg("\nDIMSTYLE: "); DRW_DBGHL(DIMSTYLE.code, DIMSTYLE.size, DIMSTYLE.ref)DRW_dbg::dbgHL(DIMSTYLE.code, DIMSTYLE.size, DIMSTYLE.ref);
2127 dwgHandle CMLSTYLE = hBbuf->getHandle();
2128 DRW_DBG("\nCMLSTYLE: ")DRW_dbg::dbg("\nCMLSTYLE: "); DRW_DBGHL(CMLSTYLE.code, CMLSTYLE.size, CMLSTYLE.ref)DRW_dbg::dbgHL(CMLSTYLE.code, CMLSTYLE.size, CMLSTYLE.ref);
2129 if (version > DRW::AC1014) {//2000+
2130 storeVar("PSVPSCALE", new DRW_Variant(40, buf->getBitDouble()));
2131 }
2132 storeVar("PINSBASE", new DRW_Variant(10, buf->get3BitDouble()));
2133 storeVar("PEXTMIN", new DRW_Variant(10, buf->get3BitDouble()));
2134 storeVar("PEXTMAX", new DRW_Variant(10, buf->get3BitDouble()));
2135 storeVar("PLIMMIN", new DRW_Variant(10, buf->get2RawDouble()));
2136 storeVar("PLIMMAX", new DRW_Variant(10, buf->get2RawDouble()));
2137 storeVar("PELEVATION", new DRW_Variant(40, buf->getBitDouble()));
2138 storeVar("PUCSORG", new DRW_Variant(10, buf->get3BitDouble()));
2139 storeVar("PUCSXDIR", new DRW_Variant(10, buf->get3BitDouble()));
2140 storeVar("PUCSYDIR", new DRW_Variant(10, buf->get3BitDouble()));
2141 dwgHandle PUCSNAME = hBbuf->getHandle();
2142 DRW_DBG("\nPUCSNAME: ")DRW_dbg::dbg("\nPUCSNAME: "); DRW_DBGHL(PUCSNAME.code, PUCSNAME.size, PUCSNAME.ref)DRW_dbg::dbgHL(PUCSNAME.code, PUCSNAME.size, PUCSNAME.ref);
2143 if (version > DRW::AC1014) {//2000+
2144 dwgHandle PUCSORTHOREF = hBbuf->getHandle();
2145 DRW_DBG("\nPUCSORTHOREF: ")DRW_dbg::dbg("\nPUCSORTHOREF: "); DRW_DBGHL(PUCSORTHOREF.code, PUCSORTHOREF.size, PUCSORTHOREF.ref)DRW_dbg::dbgHL(PUCSORTHOREF.code, PUCSORTHOREF.size, PUCSORTHOREF
.ref)
;
2146 storeVar("PUCSORTHOVIEW", new DRW_Variant(70, buf->getBitShort()));
2147 dwgHandle PUCSBASE = hBbuf->getHandle();
2148 DRW_DBG("\nPUCSBASE: ")DRW_dbg::dbg("\nPUCSBASE: "); DRW_DBGHL(PUCSBASE.code, PUCSBASE.size, PUCSBASE.ref)DRW_dbg::dbgHL(PUCSBASE.code, PUCSBASE.size, PUCSBASE.ref);
2149 storeVar("PUCSORGTOP", new DRW_Variant(10, buf->get3BitDouble()));
2150 storeVar("PUCSORGBOTTOM", new DRW_Variant(10, buf->get3BitDouble()));
2151 storeVar("PUCSORGLEFT", new DRW_Variant(10, buf->get3BitDouble()));
2152 storeVar("PUCSORGRIGHT", new DRW_Variant(10, buf->get3BitDouble()));
2153 storeVar("PUCSORGFRONT", new DRW_Variant(10, buf->get3BitDouble()));
2154 storeVar("PUCSORGBACK", new DRW_Variant(10, buf->get3BitDouble()));
2155 }
2156 storeVar("INSBASE", new DRW_Variant(10, buf->get3BitDouble()));
2157 storeVar("EXTMIN", new DRW_Variant(10, buf->get3BitDouble()));
2158 storeVar("EXTMAX", new DRW_Variant(10, buf->get3BitDouble()));
2159
2160 storeVar("LIMMIN", new DRW_Variant(10, buf->get2RawDouble()));
2161 storeVar("LIMMAX", new DRW_Variant(10, buf->get2RawDouble()));
2162 storeVar("ELEVATION", new DRW_Variant(40, buf->getBitDouble()));
2163 storeVar("UCSORG", new DRW_Variant(10, buf->get3BitDouble()));
2164 storeVar("UCSXDIR", new DRW_Variant(10, buf->get3BitDouble()));
2165 storeVar("UCSYDIR", new DRW_Variant(10, buf->get3BitDouble()));
2166 dwgHandle UCSNAME = hBbuf->getHandle();
2167 DRW_DBG("\nUCSNAME: ")DRW_dbg::dbg("\nUCSNAME: "); DRW_DBGHL(UCSNAME.code, UCSNAME.size, UCSNAME.ref)DRW_dbg::dbgHL(UCSNAME.code, UCSNAME.size, UCSNAME.ref);
2168 if (version > DRW::AC1014) {//2000+
2169 dwgHandle UCSORTHOREF = hBbuf->getHandle();
2170 DRW_DBG("\nUCSORTHOREF: ")DRW_dbg::dbg("\nUCSORTHOREF: "); DRW_DBGHL(UCSORTHOREF.code, UCSORTHOREF.size, UCSORTHOREF.ref)DRW_dbg::dbgHL(UCSORTHOREF.code, UCSORTHOREF.size, UCSORTHOREF
.ref)
;
2171 storeVar("UCSORTHOVIEW", new DRW_Variant(70, buf->getBitShort()));
2172 dwgHandle UCSBASE = hBbuf->getHandle();
2173 DRW_DBG("\nUCSBASE: ")DRW_dbg::dbg("\nUCSBASE: "); DRW_DBGHL(UCSBASE.code, UCSBASE.size, UCSBASE.ref)DRW_dbg::dbgHL(UCSBASE.code, UCSBASE.size, UCSBASE.ref);
2174 storeVar("UCSORGTOP", new DRW_Variant(10, buf->get3BitDouble()));
2175 storeVar("UCSORGBOTTOM", new DRW_Variant(10, buf->get3BitDouble()));
2176 storeVar("UCSORGLEFT", new DRW_Variant(10, buf->get3BitDouble()));
2177 storeVar("UCSORGRIGHT", new DRW_Variant(10, buf->get3BitDouble()));
2178 storeVar("UCSORGFRONT", new DRW_Variant(10, buf->get3BitDouble()));
2179 storeVar("UCSORGBACK", new DRW_Variant(10, buf->get3BitDouble()));
2180 if (version < DRW::AC1021) {//2004-
2181 storeVar("DIMPOST", new DRW_Variant(1, buf->getCP8Text()));
2182 storeVar("DIMAPOST", new DRW_Variant(1, buf->getCP8Text()));
2183 }
2184 }
2185 if (version < DRW::AC1015) {//r14-
2186 storeVar("DIMTOL", new DRW_Variant(70, buf->getBit()));
2187 storeVar("DIMLIM", new DRW_Variant(70, buf->getBit()));
2188 storeVar("DIMTIH", new DRW_Variant(70, buf->getBit()));
2189 storeVar("DIMTOH", new DRW_Variant(70, buf->getBit()));
2190 storeVar("DIMSE1", new DRW_Variant(70, buf->getBit()));
2191 storeVar("DIMSE2", new DRW_Variant(70, buf->getBit()));
2192 storeVar("DIMALT", new DRW_Variant(70, buf->getBit()));
2193 storeVar("DIMTOFL", new DRW_Variant(70, buf->getBit()));
2194 storeVar("DIMSAH", new DRW_Variant(70, buf->getBit()));
2195 storeVar("DIMTIX", new DRW_Variant(70, buf->getBit()));
2196 storeVar("DIMSOXD", new DRW_Variant(70, buf->getBit()));
2197 storeVar("DIMALTD", new DRW_Variant(70, buf->getRawChar8()));
2198 storeVar("DIMZIN", new DRW_Variant(70, buf->getRawChar8()));
2199 storeVar("DIMSD1", new DRW_Variant(70, buf->getBit()));
2200 storeVar("DIMSD2", new DRW_Variant(70, buf->getBit()));
2201 storeVar("DIMTOLJ", new DRW_Variant(70, buf->getRawChar8()));
2202 storeVar("DIMJUST", new DRW_Variant(70, buf->getRawChar8()));
2203 storeVar("DIMFIT", new DRW_Variant(70, buf->getRawChar8()));///////////
2204 storeVar("DIMUPT", new DRW_Variant(70, buf->getBit()));
2205 storeVar("DIMTZIN", new DRW_Variant(70, buf->getRawChar8()));
2206 storeVar("DIMALTZ", new DRW_Variant(70, buf->getRawChar8()));
2207 storeVar("DIMALTTZ", new DRW_Variant(70, buf->getRawChar8()));
2208 storeVar("DIMTAD", new DRW_Variant(70, buf->getRawChar8()));
2209 storeVar("DIMUNIT", new DRW_Variant(70, buf->getBitShort()));///////////
2210 storeVar("DIMAUNIT", new DRW_Variant(70, buf->getBitShort()));
2211 storeVar("DIMDEC", new DRW_Variant(70, buf->getBitShort()));
2212 storeVar("DIMTDEC", new DRW_Variant(70, buf->getBitShort()));
2213 storeVar("DIMALTU", new DRW_Variant(70, buf->getBitShort()));
2214 storeVar("DIMALTTD", new DRW_Variant(70, buf->getBitShort()));
2215 dwgHandle DIMTXSTY = hBbuf->getHandle();
2216 DRW_DBG("\nDIMTXSTY: ")DRW_dbg::dbg("\nDIMTXSTY: "); DRW_DBGHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref)DRW_dbg::dbgHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref);
2217 }
2218 storeVar("DIMSCALE", new DRW_Variant(40, buf->getBitDouble()));
2219 storeVar("DIMASZ", new DRW_Variant(40, buf->getBitDouble()));
2220 storeVar("DIMEXO", new DRW_Variant(40, buf->getBitDouble()));
2221 storeVar("DIMDLI", new DRW_Variant(40, buf->getBitDouble()));
2222 storeVar("DIMEXE", new DRW_Variant(40, buf->getBitDouble()));
2223 storeVar("DIMRND", new DRW_Variant(40, buf->getBitDouble()));
2224 storeVar("DIMDLE", new DRW_Variant(40, buf->getBitDouble()));
2225 storeVar("DIMTP", new DRW_Variant(40, buf->getBitDouble()));
2226 storeVar("DIMTM", new DRW_Variant(40, buf->getBitDouble()));
2227 if (version > DRW::AC1018) {//2007+
2228 storeVar("DIMFXL", new DRW_Variant(40, buf->getBitDouble()));//////////////////
2229 storeVar("DIMJOGANG", new DRW_Variant(40, buf->getBitDouble()));///////////////
2230 storeVar("DIMTFILL", new DRW_Variant(70, buf->getBitShort()));
2231 storeVar("DIMTFILLCLR", new DRW_Variant(62, buf->getCmColor(version)));
2232 }
2233 if (version > DRW::AC1014) {//2000+
2234 storeVar("DIMTOL", new DRW_Variant(70, buf->getBit()));
2235 storeVar("DIMLIM", new DRW_Variant(70, buf->getBit()));
2236 storeVar("DIMTIH", new DRW_Variant(70, buf->getBit()));
2237 storeVar("DIMTOH", new DRW_Variant(70, buf->getBit()));
2238 storeVar("DIMSE1", new DRW_Variant(70, buf->getBit()));
2239 storeVar("DIMSE2", new DRW_Variant(70, buf->getBit()));
2240 storeVar("DIMTAD", new DRW_Variant(70, buf->getBitShort()));
2241 storeVar("DIMZIN", new DRW_Variant(70, buf->getBitShort()));
2242 storeVar("DIMAZIN", new DRW_Variant(70, buf->getBitShort()));
2243 }
2244 if (version > DRW::AC1018) {//2007+
2245 storeVar("DIMARCSYM", new DRW_Variant(70, buf->getBitShort()));
2246 }
2247 storeVar("DIMTXT", new DRW_Variant(40, buf->getBitDouble()));
2248 storeVar("DIMCEN", new DRW_Variant(40, buf->getBitDouble()));
2249 storeVar("DIMTSZ", new DRW_Variant(40, buf->getBitDouble()));
2250 storeVar("DIMALTF", new DRW_Variant(40, buf->getBitDouble()));
2251 storeVar("DIMLFAC", new DRW_Variant(40, buf->getBitDouble()));
2252 storeVar("DIMTVP", new DRW_Variant(40, buf->getBitDouble()));
2253 storeVar("DIMTFAC", new DRW_Variant(40, buf->getBitDouble()));
2254 storeVar("DIMGAP", new DRW_Variant(40, buf->getBitDouble()));
2255 if (version < DRW::AC1015) {//r14-
2256 storeVar("DIMPOST", new DRW_Variant(1, buf->getCP8Text()));
2257 storeVar("DIMAPOST", new DRW_Variant(1, buf->getCP8Text()));
2258 storeVar("DIMBLK", new DRW_Variant(1, buf->getCP8Text()));
2259 storeVar("DIMBLK1", new DRW_Variant(1, buf->getCP8Text()));
2260 storeVar("DIMBLK2", new DRW_Variant(1, buf->getCP8Text()));
2261 }
2262 if (version > DRW::AC1014) {//2000+
2263 storeVar("DIMALTRND", new DRW_Variant(40, buf->getBitDouble()));
2264 storeVar("DIMALT", new DRW_Variant(70, buf->getBit()));
2265 storeVar("DIMALTD", new DRW_Variant(70, buf->getBitShort()));
2266 storeVar("DIMTOFL", new DRW_Variant(70, buf->getBit()));
2267 storeVar("DIMSAH", new DRW_Variant(70, buf->getBit()));
2268 storeVar("DIMTIX", new DRW_Variant(70, buf->getBit()));
2269 storeVar("DIMSOXD", new DRW_Variant(70, buf->getBit()));
2270 }
2271 storeVar("DIMCLRD", new DRW_Variant(70, buf->getCmColor(version)));//RLZ: TODO read CMC or EMC color
2272 storeVar("DIMCLRE", new DRW_Variant(70, buf->getCmColor(version)));//RLZ: TODO read CMC or EMC color
2273 storeVar("DIMCLRT", new DRW_Variant(70, buf->getCmColor(version)));//RLZ: TODO read CMC or EMC color
2274 if (version > DRW::AC1014) {//2000+
2275 storeVar("DIMADEC", new DRW_Variant(70, buf->getBitShort()));
2276 storeVar("DIMDEC", new DRW_Variant(70, buf->getBitShort()));
2277 storeVar("DIMTDEC", new DRW_Variant(70, buf->getBitShort()));
2278 storeVar("DIMALTU", new DRW_Variant(70, buf->getBitShort()));
2279 storeVar("DIMALTTD", new DRW_Variant(70, buf->getBitShort()));
2280 storeVar("DIMAUNIT", new DRW_Variant(70, buf->getBitShort()));
2281 storeVar("DIMFRAC", new DRW_Variant(70, buf->getBitShort()));// DIMFRAC (fraction format)
2282 storeVar("DIMLUNIT", new DRW_Variant(70, buf->getBitShort()));
2283 storeVar("DIMDSEP", new DRW_Variant(70, buf->getBitShort()));
2284 storeVar("DIMTMOVE", new DRW_Variant(70, buf->getBitShort()));
2285 storeVar("DIMJUST", new DRW_Variant(70, buf->getBitShort()));
2286 storeVar("DIMSD1", new DRW_Variant(70, buf->getBit()));
2287 storeVar("DIMSD2", new DRW_Variant(70, buf->getBit()));
2288 storeVar("DIMTOLJ", new DRW_Variant(70, buf->getBitShort()));
2289 storeVar("DIMTZIN", new DRW_Variant(70, buf->getBitShort()));
2290 storeVar("DIMALTZ", new DRW_Variant(70, buf->getBitShort()));
2291 storeVar("DIMALTTZ", new DRW_Variant(70, buf->getBitShort()));
2292 storeVar("DIMUPT", new DRW_Variant(70, buf->getBit()));
2293 storeVar("DIMATFIT", new DRW_Variant(70, buf->getBitShort()));
2294 }
2295 if (version > DRW::AC1018) {//2007+
2296 storeVar("DIMFXLON", new DRW_Variant(70, buf->getBit()));////////////////
2297 }
2298 if (version > DRW::AC1021) {//2010+
2299 storeVar("DIMTXTDIRECTION", new DRW_Variant(70, buf->getBit()));////////////////
2300 storeVar("DIMALTMZF", new DRW_Variant(40, buf->getBitDouble()));////////////////
2301 storeVar("DIMMZF", new DRW_Variant(40, buf->getBitDouble()));////////////////
2302 }
2303 if (version > DRW::AC1014) {//2000+
2304 dwgHandle DIMTXSTY = hBbuf->getHandle();
2305 DRW_DBG("\nDIMTXSTY: ")DRW_dbg::dbg("\nDIMTXSTY: "); DRW_DBGHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref)DRW_dbg::dbgHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref);
2306 dwgHandle DIMLDRBLK = hBbuf->getHandle();
2307 DRW_DBG("\nDIMLDRBLK: ")DRW_dbg::dbg("\nDIMLDRBLK: "); DRW_DBGHL(DIMLDRBLK.code, DIMLDRBLK.size, DIMLDRBLK.ref)DRW_dbg::dbgHL(DIMLDRBLK.code, DIMLDRBLK.size, DIMLDRBLK.ref);
2308 dwgHandle DIMBLK = hBbuf->getHandle();
2309 DRW_DBG("\nDIMBLK: ")DRW_dbg::dbg("\nDIMBLK: "); DRW_DBGHL(DIMBLK.code, DIMBLK.size, DIMBLK.ref)DRW_dbg::dbgHL(DIMBLK.code, DIMBLK.size, DIMBLK.ref);
2310 dwgHandle DIMBLK1 = hBbuf->getHandle();
2311 DRW_DBG("\nDIMBLK1: ")DRW_dbg::dbg("\nDIMBLK1: "); DRW_DBGHL(DIMBLK1.code, DIMBLK1.size, DIMBLK1.ref)DRW_dbg::dbgHL(DIMBLK1.code, DIMBLK1.size, DIMBLK1.ref);
2312 dwgHandle DIMBLK2 = hBbuf->getHandle();
2313 DRW_DBG("\nDIMBLK2: ")DRW_dbg::dbg("\nDIMBLK2: "); DRW_DBGHL(DIMBLK2.code, DIMBLK2.size, DIMBLK2.ref)DRW_dbg::dbgHL(DIMBLK2.code, DIMBLK2.size, DIMBLK2.ref);
2314 }
2315 if (version > DRW::AC1018) {//2007+
2316 dwgHandle DIMLTYPE = hBbuf->getHandle();
2317 DRW_DBG("\nDIMLTYPE: ")DRW_dbg::dbg("\nDIMLTYPE: "); DRW_DBGHL(DIMLTYPE.code, DIMLTYPE.size, DIMLTYPE.ref)DRW_dbg::dbgHL(DIMLTYPE.code, DIMLTYPE.size, DIMLTYPE.ref);
2318 dwgHandle DIMLTEX1 = hBbuf->getHandle();
2319 DRW_DBG("\nDIMLTEX1: ")DRW_dbg::dbg("\nDIMLTEX1: "); DRW_DBGHL(DIMLTEX1.code, DIMLTEX1.size, DIMLTEX1.ref)DRW_dbg::dbgHL(DIMLTEX1.code, DIMLTEX1.size, DIMLTEX1.ref);
2320 dwgHandle DIMLTEX2 = hBbuf->getHandle();
2321 DRW_DBG("\nDIMLTEX2: ")DRW_dbg::dbg("\nDIMLTEX2: "); DRW_DBGHL(DIMLTEX2.code, DIMLTEX2.size, DIMLTEX2.ref)DRW_dbg::dbgHL(DIMLTEX2.code, DIMLTEX2.size, DIMLTEX2.ref);
2322 }
2323 if (version > DRW::AC1014) {//2000+
2324 storeVar("DIMLWD", new DRW_Variant(70, buf->getBitShort()));
2325 storeVar("DIMLWE", new DRW_Variant(70, buf->getBitShort()));
2326 }
2327 dwgHandle CONTROL = hBbuf->getHandle();
2328 DRW_DBG("\nBLOCK CONTROL: ")DRW_dbg::dbg("\nBLOCK CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2329 blockCtrl = CONTROL.ref;
2330 CONTROL = hBbuf->getHandle();
2331 DRW_DBG("\nLAYER CONTROL: ")DRW_dbg::dbg("\nLAYER CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2332 layerCtrl = CONTROL.ref;
2333 CONTROL = hBbuf->getHandle();
2334 DRW_DBG("\nSTYLE CONTROL: ")DRW_dbg::dbg("\nSTYLE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2335 styleCtrl = CONTROL.ref;
2336 CONTROL = hBbuf->getHandle();
2337 DRW_DBG("\nLINETYPE CONTROL: ")DRW_dbg::dbg("\nLINETYPE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2338 linetypeCtrl = CONTROL.ref;
2339 CONTROL = hBbuf->getHandle();
2340 DRW_DBG("\nVIEW CONTROL: ")DRW_dbg::dbg("\nVIEW CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2341 viewCtrl = CONTROL.ref;
2342 CONTROL = hBbuf->getHandle();
2343 DRW_DBG("\nUCS CONTROL: ")DRW_dbg::dbg("\nUCS CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2344 ucsCtrl = CONTROL.ref;
2345 CONTROL = hBbuf->getHandle();
2346 DRW_DBG("\nVPORT CONTROL: ")DRW_dbg::dbg("\nVPORT CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2347 vportCtrl = CONTROL.ref;
2348 CONTROL = hBbuf->getHandle();
2349 DRW_DBG("\nAPPID CONTROL: ")DRW_dbg::dbg("\nAPPID CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2350 appidCtrl = CONTROL.ref;
2351 CONTROL = hBbuf->getHandle();
2352 DRW_DBG("\nDIMSTYLE CONTROL: ")DRW_dbg::dbg("\nDIMSTYLE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2353 dimstyleCtrl = CONTROL.ref;
2354 if (version < DRW::AC1018) {//r2000-
2355 CONTROL = hBbuf->getHandle();
2356 DRW_DBG("\nVIEWPORT ENTITY HEADER CONTROL: ")DRW_dbg::dbg("\nVIEWPORT ENTITY HEADER CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2357 vpEntHeaderCtrl = CONTROL.ref; //RLZ: only in R13-R15 ????
2358 }
2359 CONTROL = hBbuf->getHandle();
2360 DRW_DBG("\nDICT ACAD_GROUP: ")DRW_dbg::dbg("\nDICT ACAD_GROUP: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2361 CONTROL = hBbuf->getHandle();
2362 DRW_DBG("\nDICT ACAD_MLINESTYLE: ")DRW_dbg::dbg("\nDICT ACAD_MLINESTYLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2363 CONTROL = hBbuf->getHandle();
2364 DRW_DBG("\nDICT NAMED OBJS: ")DRW_dbg::dbg("\nDICT NAMED OBJS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2365
2366 if (version > DRW::AC1014) {//2000+
2367 storeVar("TSTACKALIGN", new DRW_Variant(70, buf->getBitShort()));
2368 storeVar("TSTACKSIZE", new DRW_Variant(70, buf->getBitShort()));
2369 if (version < DRW::AC1021) {//2004-
2370 storeVar("HYPERLINKBASE", new DRW_Variant(1, buf->getCP8Text()));
2371 storeVar("STYLESHEET", new DRW_Variant(1, buf->getCP8Text()));
2372 }
2373 CONTROL = hBbuf->getHandle();
2374 DRW_DBG("\nDICT LAYOUTS: ")DRW_dbg::dbg("\nDICT LAYOUTS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2375 CONTROL = hBbuf->getHandle();
2376 DRW_DBG("\nDICT PLOTSETTINGS: ")DRW_dbg::dbg("\nDICT PLOTSETTINGS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2377 CONTROL = hBbuf->getHandle();
2378 DRW_DBG("\nDICT PLOTSTYLES: ")DRW_dbg::dbg("\nDICT PLOTSTYLES: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2379 }
2380 if (version > DRW::AC1015) {//2004+
2381 CONTROL = hBbuf->getHandle();
2382 DRW_DBG("\nDICT MATERIALS: ")DRW_dbg::dbg("\nDICT MATERIALS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2383 CONTROL = hBbuf->getHandle();
2384 DRW_DBG("\nDICT COLORS: ")DRW_dbg::dbg("\nDICT COLORS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2385 }
2386 if (version > DRW::AC1018) {//2007+
2387 CONTROL = hBbuf->getHandle();
2388 DRW_DBG("\nDICT VISUALSTYLE: ")DRW_dbg::dbg("\nDICT VISUALSTYLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2389 }
2390 if (version > DRW::AC1024) {//2013+
2391 CONTROL = hBbuf->getHandle();
2392 DRW_DBG("\nUNKNOWN HANDLE: ")DRW_dbg::dbg("\nUNKNOWN HANDLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2393 }
2394 if (version > DRW::AC1014) {//2000+
2395 DRW_DBG("\nFlags: ")DRW_dbg::dbg("\nFlags: "); DRW_DBGH(buf->getBitLong())DRW_dbg::dbgH(buf->getBitLong());//RLZ TODO change to 8 vars
2396 storeVar("INSUNITS", new DRW_Variant(70, buf->getBitShort()));
2397 std::uint16_t cepsntype = buf->getBitShort();
2398 storeVar("CEPSNTYPE", new DRW_Variant(70, cepsntype));
2399 if (cepsntype == 3){
2400 CONTROL = hBbuf->getHandle();
2401 DRW_DBG("\nCPSNID HANDLE: ")DRW_dbg::dbg("\nCPSNID HANDLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2402 }
2403 if (version < DRW::AC1021) {//2004-
2404 storeVar("FINGERPRINTGUID", new DRW_Variant(1, buf->getCP8Text()));
2405 storeVar("VERSIONGUID", new DRW_Variant(1, buf->getCP8Text()));
2406 }
2407 }
2408 if (version > DRW::AC1015) {//2004+
2409 storeVar("SORTENTS", new DRW_Variant(70, buf->getRawChar8()));
2410 storeVar("INDEXCTL", new DRW_Variant(70, buf->getRawChar8()));
2411 storeVar("HIDETEXT", new DRW_Variant(70, buf->getRawChar8()));
2412 storeVar("XCLIPFRAME", new DRW_Variant(70, buf->getRawChar8()));
2413 storeVar("DIMASSOC", new DRW_Variant(70, buf->getRawChar8()));
2414 storeVar("HALOGAP", new DRW_Variant(70, buf->getRawChar8()));
2415 storeVar("OBSCUREDCOLOR", new DRW_Variant(70, buf->getBitShort()));
2416 storeVar("INTERSECTIONCOLOR", new DRW_Variant(70, buf->getBitShort()));
2417 storeVar("OBSCUREDLTYPE", new DRW_Variant(70, buf->getRawChar8()));
2418 storeVar("INTERSECTIONDISPLAY", new DRW_Variant(70, buf->getRawChar8()));
2419 if (version < DRW::AC1021) {//2004-
2420 storeVar("PROJECTNAME", new DRW_Variant(1, buf->getCP8Text()));
2421 }
2422 }
2423 CONTROL = hBbuf->getHandle();
2424 DRW_DBG("\nBLOCK PAPER_SPACE: ")DRW_dbg::dbg("\nBLOCK PAPER_SPACE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2425 CONTROL = hBbuf->getHandle();
2426 DRW_DBG("\nBLOCK MODEL_SPACE: ")DRW_dbg::dbg("\nBLOCK MODEL_SPACE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2427 CONTROL = hBbuf->getHandle();
2428 DRW_DBG("\nLTYPE BYLAYER: ")DRW_dbg::dbg("\nLTYPE BYLAYER: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2429 CONTROL = hBbuf->getHandle();
2430 DRW_DBG("\nLTYPE BYBLOCK: ")DRW_dbg::dbg("\nLTYPE BYBLOCK: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2431 CONTROL = hBbuf->getHandle();
2432 DRW_DBG("\nLTYPE CONTINUOUS: ")DRW_dbg::dbg("\nLTYPE CONTINUOUS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2433 if (version > DRW::AC1018) {//2007+
2434 storeVar("CAMERADISPLAY", new DRW_Variant(70, buf->getBit()));
2435 DRW_DBG("\nUnknown 2007+ long1: ")DRW_dbg::dbg("\nUnknown 2007+ long1: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2436 DRW_DBG("\nUnknown 2007+ long2: ")DRW_dbg::dbg("\nUnknown 2007+ long2: "); DRW_DBG(buf->getBitLong())DRW_dbg::dbg(buf->getBitLong());
2437 DRW_DBG("\nUnknown 2007+ double2: ")DRW_dbg::dbg("\nUnknown 2007+ double2: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
2438 storeVar("STEPSPERSEC", new DRW_Variant(40, buf->getBitDouble()));
2439 storeVar("STEPSIZE", new DRW_Variant(40, buf->getBitDouble()));
2440 storeVar("3DDWFPREC", new DRW_Variant(40, buf->getBitDouble()));
2441 storeVar("LENSLENGTH", new DRW_Variant(40, buf->getBitDouble()));
2442 storeVar("CAMERAHEIGHT", new DRW_Variant(40, buf->getBitDouble()));
2443 storeVar("SOLIDHIST", new DRW_Variant(70, buf->getRawChar8()));
2444 storeVar("SHOWHIST", new DRW_Variant(70, buf->getRawChar8()));
2445 storeVar("PSOLWIDTH", new DRW_Variant(40, buf->getBitDouble()));
2446 storeVar("PSOLHEIGHT", new DRW_Variant(40, buf->getBitDouble()));
2447 storeVar("LOFTANG1", new DRW_Variant(40, buf->getBitDouble()));
2448 storeVar("LOFTANG2", new DRW_Variant(40, buf->getBitDouble()));
2449 storeVar("LOFTMAG1", new DRW_Variant(40, buf->getBitDouble()));
2450 storeVar("LOFTMAG2", new DRW_Variant(40, buf->getBitDouble()));
2451 storeVar("LOFTPARAM", new DRW_Variant(70, buf->getBitShort()));
2452 storeVar("LOFTNORMALS", new DRW_Variant(40, buf->getRawChar8()));
2453 storeVar("LATITUDE", new DRW_Variant(40, buf->getBitDouble()));
2454 storeVar("LONGITUDE", new DRW_Variant(40, buf->getBitDouble()));
2455 storeVar("NORTHDIRECTION", new DRW_Variant(40, buf->getBitDouble()));
2456 storeVar("TIMEZONE", new DRW_Variant(70, buf->getBitLong()));
2457 storeVar("LIGHTGLYPHDISPLAY", new DRW_Variant(70, buf->getRawChar8()));
2458 storeVar("TILEMODELIGHTSYNCH", new DRW_Variant(70, buf->getRawChar8()));
2459 storeVar("DWFFRAME", new DRW_Variant(70, buf->getRawChar8()));
2460 storeVar("DGNFRAME", new DRW_Variant(70, buf->getRawChar8()));
2461 DRW_DBG("\nUnknown 2007+ BIT: ")DRW_dbg::dbg("\nUnknown 2007+ BIT: "); DRW_DBG(buf->getBit())DRW_dbg::dbg(buf->getBit());
2462 storeVar("INTERFERECOLOR", new DRW_Variant(70, buf->getCmColor(version)));
2463 CONTROL = hBbuf->getHandle();
2464 DRW_DBG("\nINTERFEREOBJVS: ")DRW_dbg::dbg("\nINTERFEREOBJVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2465 CONTROL = hBbuf->getHandle();
2466 DRW_DBG("\nINTERFEREVPVS: ")DRW_dbg::dbg("\nINTERFEREVPVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2467 CONTROL = hBbuf->getHandle();
2468 DRW_DBG("\nDRAGVS: ")DRW_dbg::dbg("\nDRAGVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref)DRW_dbg::dbgHL(CONTROL.code, CONTROL.size, CONTROL.ref);
2469 storeVar("CSHADOW", new DRW_Variant(70, buf->getRawChar8()));
2470 DRW_DBG("\nUnknown 2007+ double2: ")DRW_dbg::dbg("\nUnknown 2007+ double2: "); DRW_DBG(buf->getBitDouble())DRW_dbg::dbg(buf->getBitDouble());
2471 }
2472 if (version > DRW::AC1012) {//R14+
2473 DRW_DBG("\nUnknown R14+ short1: ")DRW_dbg::dbg("\nUnknown R14+ short1: "); DRW_DBG(buf->getBitShort())DRW_dbg::dbg(buf->getBitShort());
2474 DRW_DBG("\nUnknown R14+ short2: ")DRW_dbg::dbg("\nUnknown R14+ short2: "); DRW_DBG(buf->getBitShort())DRW_dbg::dbg(buf->getBitShort());
2475 DRW_DBG("\nUnknown R14+ short3: ")DRW_dbg::dbg("\nUnknown R14+ short3: "); DRW_DBG(buf->getBitShort())DRW_dbg::dbg(buf->getBitShort());
2476 DRW_DBG("\nUnknown R14+ short4: ")DRW_dbg::dbg("\nUnknown R14+ short4: "); DRW_DBG(buf->getBitShort())DRW_dbg::dbg(buf->getBitShort());
2477 }
2478
2479 DRW_DBG("\nbuf position: ")DRW_dbg::dbg("\nbuf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2480 DRW_DBG(" buf bit position: ")DRW_dbg::dbg(" buf bit position: "); DRW_DBG(buf->getBitPos())DRW_dbg::dbg(buf->getBitPos());
2481
2482
2483 /**** RLZ: disabled, pending to read all data ***/
2484 //Start reading string stream for 2007 and further
2485 if (version > DRW::AC1018) {//2007+
2486 if (!buf->seekR2007StringStream(endBitPos))
2487 return false;
2488 DRW_DBG("\nstring buf position: ")DRW_dbg::dbg("\nstring buf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2489 DRW_DBG("\nstring buf bit position: ")DRW_dbg::dbg("\nstring buf bit position: "); DRW_DBG(buf->getBitPos())DRW_dbg::dbg(buf->getBitPos());
2490 DRW_DBG("\nUnknown text1: ")DRW_dbg::dbg("\nUnknown text1: "); DRW_DBG(buf->getUCSText(false))DRW_dbg::dbg(buf->getUCSText(false));
2491 DRW_DBG("\nUnknown text2: ")DRW_dbg::dbg("\nUnknown text2: "); DRW_DBG(buf->getUCSText(false))DRW_dbg::dbg(buf->getUCSText(false));
2492 DRW_DBG("\nUnknown text3: ")DRW_dbg::dbg("\nUnknown text3: "); DRW_DBG(buf->getUCSText(false))DRW_dbg::dbg(buf->getUCSText(false));
2493 DRW_DBG("\nUnknown text4: ")DRW_dbg::dbg("\nUnknown text4: "); DRW_DBG(buf->getUCSText(false))DRW_dbg::dbg(buf->getUCSText(false));
2494 storeVar("MENU", new DRW_Variant(1, buf->getUCSText(false)));
2495 storeVar("DIMPOST", new DRW_Variant(1, buf->getUCSText(false)));
2496 storeVar("DIMAPOST", new DRW_Variant(1, buf->getUCSText(false)));
2497 if (version > DRW::AC1021) {//2010+
2498 storeVar("DIMALTMZS", new DRW_Variant(70, buf->getUCSText(false)));//RLZ: pending to verify//////////////
2499 storeVar("DIMMZS", new DRW_Variant(70, buf->getUCSText(false)));//RLZ: pending to verify//////////////
2500 }
2501 storeVar("HYPERLINKBASE", new DRW_Variant(1, buf->getUCSText(false)));
2502 storeVar("STYLESHEET", new DRW_Variant(1, buf->getUCSText(false)));
2503 storeVar("FINGERPRINTGUID", new DRW_Variant(1, buf->getUCSText(false)));
2504 DRW_DBG("\nstring buf position: ")DRW_dbg::dbg("\nstring buf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2505 DRW_DBG(" string buf bit position: ")DRW_dbg::dbg(" string buf bit position: "); DRW_DBG(buf->getBitPos())DRW_dbg::dbg(buf->getBitPos());
2506 storeVar("VERSIONGUID", new DRW_Variant(1, buf->getUCSText(false)));
2507 DRW_DBG("\nstring buf position: ")DRW_dbg::dbg("\nstring buf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2508 DRW_DBG(" string buf bit position: ")DRW_dbg::dbg(" string buf bit position: "); DRW_DBG(buf->getBitPos())DRW_dbg::dbg(buf->getBitPos());
2509 storeVar("PROJECTNAME", new DRW_Variant(1, buf->getUCSText(false)));
2510 }
2511/*** ****/
2512 DRW_DBG("\nstring buf position: ")DRW_dbg::dbg("\nstring buf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2513 DRW_DBG(" string buf bit position: ")DRW_dbg::dbg(" string buf bit position: "); DRW_DBG(buf->getBitPos())DRW_dbg::dbg(buf->getBitPos());
2514
2515 // Header encode/decode unit tests and a few embedders pass the compact
2516 // standalone form: an RL size followed by exactly that many body bytes,
2517 // without the section's begin/end sentinels and CRC. Keep that form
2518 // bounded and skip only the trailer reads; real DWG section buffers start
2519 // after the 16-byte begin sentinel and still require the complete trailer.
2520 const bool standaloneBody = headerStart == 0
2521 && buf->size() >= sizeof(std::uint32_t)
2522 && size == buf->size() - sizeof(std::uint32_t);
2523 if (standaloneBody) {
2524 std::uint64_t cursorBit = 0;
2525 std::uint64_t bufferBits = 0;
2526 if (!dwgSafety::multiply(buf->getPosition(), 8, cursorBit)
2527 || !dwgSafety::add(cursorBit, buf->getBitPos(), cursorBit)
2528 || !dwgSafety::multiply(buf->size(), 8, bufferBits)
2529 || cursorBit > bufferBits)
2530 return false;
2531 return result;
2532 }
2533
2534 if (DRW_DBGGLDRW_dbg::getInstance()->getLevel() == DRW_dbg::Level::Debug){
2535 for (auto it=vars.begin(); it!=vars.end(); ++it){
2536 DRW_DBG("\n")DRW_dbg::dbg("\n"); DRW_DBG(it->first)DRW_dbg::dbg(it->first); DRW_DBG(": ")DRW_dbg::dbg(": ");
2537 switch (it->second->type()){
2538 case DRW_Variant::INTEGER:
2539 DRW_DBG(it->second->content.i)DRW_dbg::dbg(it->second->content.i);
2540 break;
2541 case DRW_Variant::DOUBLE:
2542 DRW_DBG(it->second->content.d)DRW_dbg::dbg(it->second->content.d);
2543 break;
2544 case DRW_Variant::STRING:
2545 DRW_DBG(it->second->content.s->c_str())DRW_dbg::dbg(it->second->content.s->c_str());
2546 break;
2547 case DRW_Variant::COORD:
2548 DRW_DBG("x= ")DRW_dbg::dbg("x= "); DRW_DBG(it->second->content.v->x)DRW_dbg::dbg(it->second->content.v->x);
2549 DRW_DBG(", y= ")DRW_dbg::dbg(", y= "); DRW_DBG(it->second->content.v->y)DRW_dbg::dbg(it->second->content.v->y);
2550 DRW_DBG(", z= ")DRW_dbg::dbg(", z= "); DRW_DBG(it->second->content.v->z)DRW_dbg::dbg(it->second->content.v->z);
2551 break;
2552 default:
2553 break;
2554 }
2555 DRW_DBG(" code: ")DRW_dbg::dbg(" code: ");DRW_DBG(it->second->code())DRW_dbg::dbg(it->second->code());
2556 }
2557 }
2558
2559 // The section RL includes every field after the RL itself, including the
2560 // optional R2010+/R2018 high-size field. Therefore its CRC is always at
2561 // the end of the declared payload; do not skip hSize a second time.
2562 buf->setPosition(size + 16 + 4);
2563 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2564 DRW_DBG("\nHeader CRC: ")DRW_dbg::dbg("\nHeader CRC: "); DRW_DBGH(buf->getRawShort16())DRW_dbg::dbgH(buf->getRawShort16());
2565 DRW_DBG("\nbuf position: ")DRW_dbg::dbg("\nbuf position: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2566 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2567 for (int i=0; i<16;i++) {
2568 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2569 }
2570
2571 //temporary code to show header end sentinel
2572 std::uint64_t sz= buf->size()-1;
Value stored to 'sz' during its initialization is never read
2573 if (version < DRW::AC1018) {//pre 2004
2574 sz= buf->size()-16;
2575 buf->setPosition(sz);
2576 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2577 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2578 for (int i=0; i<16;i++) {
2579 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2580 }
2581 } else if (version == DRW::AC1018) {//2004
2582// sz= buf->size()-132;
2583// buf->setPosition(sz);
2584 buf->moveBitPos(-128);
2585 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2586 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2587 for (int i=0; i<16;i++) {
2588 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2589 }
2590 } else if (version == DRW::AC1021) {//2007
2591 sz= buf->size()-16;
2592 buf->setPosition(sz);
2593 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2594 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2595 for (int i=0; i<16;i++) {
2596 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2597 }
2598 } else if (version == DRW::AC1024) {//2010
2599// sz= buf->size()-93;
2600// buf->setPosition(sz);
2601 buf->moveBitPos(-128);
2602 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2603 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2604 for (int i=0; i<16;i++) {
2605 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2606 }
2607 } else if (version == DRW::AC1027 || version == DRW::AC1032) {//2013+
2608// sz= buf->size()-76;
2609// buf->setPosition(sz);
2610 buf->moveBitPos(-128);
2611 DRW_DBG("\nsetting position to: ")DRW_dbg::dbg("\nsetting position to: "); DRW_DBG(buf->getPosition())DRW_dbg::dbg(buf->getPosition());
2612 DRW_DBG("\ndwg header end sentinel= ")DRW_dbg::dbg("\ndwg header end sentinel= ");
2613 for (int i=0; i<16;i++) {
2614 DRW_DBGH(buf->getRawChar8())DRW_dbg::dbgH(buf->getRawChar8()); DRW_DBG(" ")DRW_dbg::dbg(" ");
2615 }
2616 }
2617
2618 return result;
2619}
2620
2621// ---------------------------------------------------------------------------
2622// DRW_Header::encodeDwg — Phase 3a (drafted 2026-05-14)
2623// ---------------------------------------------------------------------------
2624// Inverse of parseDwg. Emits the bit-packed HEADER section body for R2000
2625// (AC1015). The caller (dwgWriter15::writeDwgHeader) has already emitted
2626// the 16-byte begin sentinel + 4-byte RL section-size placeholder; this
2627// function appends the variable stream starting right after them. The
2628// caller appends the 16-byte end sentinel + 2-byte CRC16 LE after we return
2629// and back-patches the size placeholder.
2630//
2631// For R2000 the handle stream is INLINE with the data stream — buf and
2632// hBbuf are the same accumulator. Future versions will diverge.
2633//
2634// Order of emission must match parseDwg EXACTLY. See deep-review notes
2635// in /Users/dli/.claude/plans/dwg-write-phase3-tables-objects.md for the
2636// 13-handle control-handle block and the conditional layout.
2637
2638namespace {
2639 /// Look up a header var tolerant of either naming convention.
2640 /// DWG-side parseDwg stores bare keys ("LUPREC"); DXF-side parseCode and
2641 /// the app's writeHeader push $-prefixed keys ("$LUPREC"). This helper
2642 /// tries the caller-supplied key first (preserving bare-on-both DWG
2643 /// round-trip semantics), then falls back to the alternate form so the
2644 /// DXF -> DWG export path (where vars were filled with $NAME keys) finds
2645 /// the values instead of emitting encoder defaults. Centralizing the
2646 /// fallback here keeps the DXF reader/writer surfaces untouched.
2647 auto findVar(const DRW_Header& hdr, const std::string& name) {
2648 auto it = hdr.vars.find(name);
2649 if (it != hdr.vars.end()) return it;
2650 if (!name.empty() && name.front() == '$') {
2651 return hdr.vars.find(name.substr(1));
2652 }
2653 return hdr.vars.find(std::string{"$"} + name);
2654 }
2655 /// Look up a 1-bit boolean var in DRW_Header::vars; default 0.
2656 std::uint8_t boolVar(const DRW_Header& hdr, const std::string& name) {
2657 auto it = findVar(hdr, name);
2658 if (it == hdr.vars.end() || !it->second) return 0;
2659 return static_cast<std::uint8_t>(it->second->i_val() & 1);
2660 }
2661 /// Look up a BS/BL int var; default 0 (or caller-supplied default).
2662 std::int32_t intVar(const DRW_Header& hdr, const std::string& name, std::int32_t def = 0) {
2663 auto it = findVar(hdr, name);
2664 if (it == hdr.vars.end() || !it->second) return def;
2665 return it->second->i_val();
2666 }
2667 /// Look up a BD float var; default 0.0 (or caller-supplied).
2668 double dblVar(const DRW_Header& hdr, const std::string& name, double def = 0.0) {
2669 auto it = findVar(hdr, name);
2670 if (it == hdr.vars.end() || !it->second) return def;
2671 return it->second->d_val();
2672 }
2673 /// Look up a 3BD coord var; default {0,0,0}.
2674 DRW_Coord coordVar(const DRW_Header& hdr, const std::string& name) {
2675 auto it = findVar(hdr, name);
2676 if (it == hdr.vars.end() || !it->second
2677 || it->second->type() != DRW_Variant::COORD
2678 || it->second->coord() == nullptr) {
2679 return {0.0, 0.0, 0.0};
2680 }
2681 return *it->second->coord();
2682 }
2683 /// Look up a TV string var; default empty.
2684 UTF8STRINGstd::string strVar(const DRW_Header& hdr, const std::string& name) {
2685 auto it = findVar(hdr, name);
2686 if (it == hdr.vars.end() || !it->second
2687 || it->second->type() != DRW_Variant::STRING) {
2688 return {};
2689 }
2690 return UTF8STRINGstd::string(it->second->c_str());
2691 }
2692 /// Build an absolute hard-pointer handle (code 5), including null refs.
2693 dwgHandle makeHardPtr(std::uint32_t ref) {
2694 dwgHandle h;
2695 h.code = 5;
2696 h.ref = ref;
2697 h.size = 0;
2698 if (ref != 0) {
2699 std::uint32_t t = ref;
2700 while (t != 0) { t >>= 8; ++h.size; }
2701 }
2702 return h;
2703 }
2704 /// Build a hard-owner handle (code 3) for the HEADER's root records.
2705 dwgHandle makeHardOwner(std::uint32_t ref) {
2706 dwgHandle h;
2707 h.code = 3;
2708 h.ref = ref;
2709 h.size = 0;
2710 if (ref != 0) {
2711 std::uint32_t t = ref;
2712 while (t != 0) { t >>= 8; ++h.size; }
2713 }
2714 return h;
2715 }
2716 /// Decompose a stored TDCREATE-style double `julianDay + msec/86_400_000`
2717 /// back into the two BLs encodeDwg writes. Inverse of:
2718 /// day = getBitLong(); msec = getBitLong();
2719 /// stored = day + msec/86_400_000.0;
2720 /// For an empty header (stored == 0.0) the result is (0, 0). Round to the
2721 /// nearest millisecond to absorb the FP error introduced by the division.
2722 void splitTimeVar(double stored, std::int32_t& day, std::int32_t& msecOut) {
2723 constexpr double kMsecPerDay = 86400000.0;
2724 const double dayFloor = std::floor(stored);
2725 day = static_cast<std::int32_t>(dayFloor);
2726 const double frac = stored - dayFloor;
2727 msecOut = static_cast<std::int32_t>(std::lround(frac * kMsecPerDay));
2728 // A msec of exactly 86_400_000 occurs if `frac` is essentially 1 due
2729 // to FP rounding; carry to the next day.
2730 if (msecOut >= static_cast<std::int32_t>(kMsecPerDay)) {
2731 day += 1;
2732 msecOut = 0;
2733 }
2734 }
2735} // namespace
2736
2737bool DRW_Header::encodeDwg(DRW::Version version, dwgBufferW *buf, dwgBufferW *hBbuf,
2738 dwgBufferW *strBuf) {
2739 const std::uint32_t encodeStartBit = buf->bitCount();
2740 m_dwgHandseedBitOffset = kInvalidDwgHandseedBitOffset;
2741 if (version != DRW::AC1015 && version != DRW::AC1018 &&
2742 version != DRW::AC1021 && version != DRW::AC1024 &&
2743 version != DRW::AC1027 &&
2744 version != DRW::AC1032) return false;
2745
2746 // -------- REQUIREDVERSIONS (parseDwg:1786-1789) -------------------------
2747 if (version > DRW::AC1024) {
2748 buf->putBitLongLong(0); // REQUIREDVERSIONS (AC1027+)
2749 }
2750
2751 // -------- Unknown 4 BDs (parseDwg:1789-1792) ----------------------------
2752 buf->putBitDouble(0.0);
2753 buf->putBitDouble(0.0);
2754 buf->putBitDouble(0.0);
2755 buf->putBitDouble(0.0);
2756
2757 // -------- 4 CP8 string unknowns (parseDwg:1793-1798) --------------------
2758 // Gated on `version < AC1021` (2007-). R2000/R2004 hits this branch.
2759 if (version < DRW::AC1021) {
2760 buf->putCP8Text(std::string());
2761 buf->putCP8Text(std::string());
2762 buf->putCP8Text(std::string());
2763 buf->putCP8Text(std::string());
2764 }
2765
2766 // -------- Unknown longs (parseDwg:1799-1800) ----------------------------
2767 // parseDwg comments call these "Unknown long1 (24L)" and "(0L)". Real
2768 // R2000 files have 24 and 0 respectively.
2769 buf->putBitLong(24);
2770 buf->putBitLong(0);
2771
2772 // -------- Current-view handle (parseDwg:1804-1807) ----------------------
2773 // R2000 and earlier only (parseDwg skips this for AC1018+).
2774 if (version < DRW::AC1018) {
2775 hBbuf->putHandle(makeHardPtr(0));
2776 }
2777
2778 // -------- 9 single-bit vars (parseDwg:1808-1819; R2000-relevant set) ----
2779 buf->putBit(boolVar(*this, "DIMASO"));
2780 buf->putBit(boolVar(*this, "DIMSHO"));
2781 buf->putBit(boolVar(*this, "PLINEGEN"));
2782 buf->putBit(boolVar(*this, "ORTHOMODE"));
2783 buf->putBit(boolVar(*this, "REGENMODE"));
2784 buf->putBit(boolVar(*this, "FILLMODE"));
2785 buf->putBit(boolVar(*this, "QTEXTMODE"));
2786 buf->putBit(boolVar(*this, "PSLTSCALE"));
2787 buf->putBit(boolVar(*this, "LIMCHECK"));
2788 if (version > DRW::AC1015) { // R2004+: undocumented bit (parseDwg:1824-1826)
2789 buf->putBit(0);
2790 }
2791
2792 // -------- 11 more single-bit vars (parseDwg:1827-1847) ------------------
2793 buf->putBit(boolVar(*this, "USRTIMER"));
2794 buf->putBit(boolVar(*this, "SKPOLY"));
2795 buf->putBit(boolVar(*this, "ANGDIR"));
2796 buf->putBit(boolVar(*this, "SPLFRAME"));
2797 buf->putBit(boolVar(*this, "MIRRTEXT"));
2798 buf->putBit(boolVar(*this, "WORLDVIEW"));
2799 buf->putBit(boolVar(*this, "TILEMODE"));
2800 buf->putBit(boolVar(*this, "PLIMCHECK"));
2801 buf->putBit(boolVar(*this, "VISRETAIN"));
2802 buf->putBit(boolVar(*this, "DISPSILH"));
2803 buf->putBit(boolVar(*this, "PELLIPSE"));
2804
2805 // -------- PROXIGRAPHICS through PDMODE (parseDwg:1845-1861) -------------
2806 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "PROXIGRAPHICS", 1)));
2807 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "TREEDEPTH", 3020)));
2808 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "LUNITS", 2)));
2809 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "LUPREC", 4)));
2810 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "AUNITS", 0)));
2811 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "AUPREC", 0)));
2812 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "ATTMODE", 1)));
2813 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "PDMODE", 0)));
2814 if (version > DRW::AC1015) { // R2004+: 3 unknown BLs (parseDwg:1868-1872)
2815 buf->putBitLong(0);
2816 buf->putBitLong(0);
2817 buf->putBitLong(0);
2818 }
2819
2820 // -------- USERI1..5 + spline/surface family (parseDwg:1873-1888) --------
2821 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "USERI1")));
2822 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "USERI2")));
2823 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "USERI3")));
2824 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "USERI4")));
2825 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "USERI5")));
2826 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SPLINESEGS", 8)));
2827 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SURFU", 6)));
2828 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SURFV", 6)));
2829 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SURFTYPE", 6)));
2830 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SURFTAB1", 6)));
2831 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SURFTAB2", 6)));
2832 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SPLINETYPE", 6)));
2833 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SHADEDGE", 3)));
2834 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "SHADEDIF", 70)));
2835 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "UNITMODE")));
2836 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "MAXACTVP", 64)));
2837 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "ISOLINES", 4)));
2838 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "CMLJUST")));
2839 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "TEXTQLTY", 50)));
2840
2841 // -------- LTSCALE through CELTSCALE (parseDwg:1889-1909) ----------------
2842 buf->putBitDouble(dblVar(*this, "LTSCALE", 1.0));
2843 buf->putBitDouble(dblVar(*this, "TEXTSIZE", 2.5));
2844 buf->putBitDouble(dblVar(*this, "TRACEWID", 1.0));
2845 buf->putBitDouble(dblVar(*this, "SKETCHINC", 1.0));
2846 buf->putBitDouble(dblVar(*this, "FILLETRAD", 0.0));
2847 buf->putBitDouble(dblVar(*this, "THICKNESS", 0.0));
2848 buf->putBitDouble(dblVar(*this, "ANGBASE", 0.0));
2849 buf->putBitDouble(dblVar(*this, "PDSIZE", 0.0));
2850 buf->putBitDouble(dblVar(*this, "PLINEWID", 0.0));
2851 buf->putBitDouble(dblVar(*this, "USERR1", 0.0));
2852 buf->putBitDouble(dblVar(*this, "USERR2", 0.0));
2853 buf->putBitDouble(dblVar(*this, "USERR3", 0.0));
2854 buf->putBitDouble(dblVar(*this, "USERR4", 0.0));
2855 buf->putBitDouble(dblVar(*this, "USERR5", 0.0));
2856 buf->putBitDouble(dblVar(*this, "CHAMFERA", 0.0));
2857 buf->putBitDouble(dblVar(*this, "CHAMFERB", 0.0));
2858 buf->putBitDouble(dblVar(*this, "CHAMFERC", 0.0));
2859 buf->putBitDouble(dblVar(*this, "CHAMFERD", 0.0));
2860 buf->putBitDouble(dblVar(*this, "FACETRES", 0.5));
2861 buf->putBitDouble(dblVar(*this, "CMLSCALE", 1.0));
2862 buf->putBitDouble(dblVar(*this, "CELTSCALE", 1.0));
2863
2864 // -------- MENU string (gated version < AC1021) --------------------------
2865 if (version < DRW::AC1021) {
2866 buf->putCP8Text(strVar(*this, "MENU"));
2867 }
2868
2869 // -------- TDCREATE / TDUPDATE / TDINDWG / TDUSRTIMER (4 pairs of BLs) ---
2870 {
2871 std::int32_t day, msec;
2872 splitTimeVar(dblVar(*this, "TDCREATE"), day, msec);
2873 buf->putBitLong(day);
2874 buf->putBitLong(msec);
2875 }
2876 {
2877 std::int32_t day, msec;
2878 splitTimeVar(dblVar(*this, "TDUPDATE"), day, msec);
2879 buf->putBitLong(day);
2880 buf->putBitLong(msec);
2881 }
2882 if (version > DRW::AC1015) { // R2004+: 3 unknown BLs (parseDwg:1931-1935)
2883 buf->putBitLong(0);
2884 buf->putBitLong(0);
2885 buf->putBitLong(0);
2886 }
2887 {
2888 std::int32_t day, msec;
2889 splitTimeVar(dblVar(*this, "TDINDWG"), day, msec);
2890 buf->putBitLong(day);
2891 buf->putBitLong(msec);
2892 }
2893 {
2894 std::int32_t day, msec;
2895 splitTimeVar(dblVar(*this, "TDUSRTIMER"), day, msec);
2896 buf->putBitLong(day);
2897 buf->putBitLong(msec);
2898 }
2899
2900 // -------- CECOLOR + first handle block (parseDwg:1947-1963) -------------
2901 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "CECOLOR", 256)));
2902 // HANDSEED — emitted into the DATA stream (`buf`), not hBbuf.
2903 // Stored in DRW_Header::handSeed (set by parseDwg on read; settable
2904 // by the writer caller from the HandleAllocator's high-water mark
2905 // for fresh documents). A zero value emits as a null handle —
2906 // libdxfrw round-trip tolerates it, but AutoCAD will refresh
2907 // HANDSEED to `max(handle)+1` on first save and mark the file
2908 // modified. See Risk 4j.
2909 // Keep a fixed-width payload so the writer can patch HANDSEED after every
2910 // object has received a handle, without shifting later section offsets.
2911 m_dwgHandseedBitOffset = buf->bitCount() - encodeStartBit + 8;
2912 buf->putFixedHandle(0, static_cast<std::uint8_t>(sizeof(handSeed)), handSeed);
2913 // The following 5 handles emit to the HANDLE stream. For R2000 the
2914 // handle stream is inline (buf == hBbuf in our usage).
2915 hBbuf->putHandle(makeHardPtr(clayerHandle != 0 ? clayerHandle
2916 : DRW::DwgLayer0Handle)); // CLAYER
2917 hBbuf->putHandle(makeHardPtr(DRW::DwgStandardTextStyleHandle)); // TEXTSTYLE
2918 hBbuf->putHandle(makeHardPtr(DRW::DwgLtypeByLayerHandle)); // CELTYPE
2919 if (version > DRW::AC1018) { // 2007+: CMATERIAL (parseDwg:1960-1963)
2920 hBbuf->putHandle(makeHardPtr(0));
2921 }
2922 hBbuf->putHandle(makeHardPtr(DRW::DwgStandardDimstyleHandle)); // DIMSTYLE
2923 hBbuf->putHandle(makeHardPtr(0)); // CMLSTYLE
2924
2925 // -------- Paper-space view block (parseDwg:1965-1989) -------------------
2926 buf->putBitDouble(dblVar(*this, "PSVPSCALE", 1.0));
2927 buf->put3BitDouble(coordVar(*this, "PINSBASE"));
2928 buf->put3BitDouble(coordVar(*this, "PEXTMIN"));
2929 buf->put3BitDouble(coordVar(*this, "PEXTMAX"));
2930 buf->put2RawDouble(coordVar(*this, "PLIMMIN"));
2931 buf->put2RawDouble(coordVar(*this, "PLIMMAX"));
2932 buf->putBitDouble(dblVar(*this, "PELEVATION"));
2933 buf->put3BitDouble(coordVar(*this, "PUCSORG"));
2934 buf->put3BitDouble(coordVar(*this, "PUCSXDIR"));
2935 buf->put3BitDouble(coordVar(*this, "PUCSYDIR"));
2936 hBbuf->putHandle(makeHardPtr(0)); // PUCSNAME
2937 hBbuf->putHandle(makeHardPtr(0)); // PUCSORTHOREF
2938 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "PUCSORTHOVIEW")));
2939 hBbuf->putHandle(makeHardPtr(0)); // PUCSBASE
2940 buf->put3BitDouble(coordVar(*this, "PUCSORGTOP"));
2941 buf->put3BitDouble(coordVar(*this, "PUCSORGBOTTOM"));
2942 buf->put3BitDouble(coordVar(*this, "PUCSORGLEFT"));
2943 buf->put3BitDouble(coordVar(*this, "PUCSORGRIGHT"));
2944 buf->put3BitDouble(coordVar(*this, "PUCSORGFRONT"));
2945 buf->put3BitDouble(coordVar(*this, "PUCSORGBACK"));
2946
2947 // -------- Model-space view block (parseDwg:1991-2018) -------------------
2948 buf->put3BitDouble(coordVar(*this, "INSBASE"));
2949 buf->put3BitDouble(coordVar(*this, "EXTMIN"));
2950 buf->put3BitDouble(coordVar(*this, "EXTMAX"));
2951 buf->put2RawDouble(coordVar(*this, "LIMMIN"));
2952 buf->put2RawDouble(coordVar(*this, "LIMMAX"));
2953 buf->putBitDouble(dblVar(*this, "ELEVATION"));
2954 buf->put3BitDouble(coordVar(*this, "UCSORG"));
2955 buf->put3BitDouble(coordVar(*this, "UCSXDIR"));
2956 buf->put3BitDouble(coordVar(*this, "UCSYDIR"));
2957 hBbuf->putHandle(makeHardPtr(0)); // UCSNAME
2958 hBbuf->putHandle(makeHardPtr(0)); // UCSORTHOREF
2959 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "UCSORTHOVIEW")));
2960 hBbuf->putHandle(makeHardPtr(0)); // UCSBASE
2961 buf->put3BitDouble(coordVar(*this, "UCSORGTOP"));
2962 buf->put3BitDouble(coordVar(*this, "UCSORGBOTTOM"));
2963 buf->put3BitDouble(coordVar(*this, "UCSORGLEFT"));
2964 buf->put3BitDouble(coordVar(*this, "UCSORGRIGHT"));
2965 buf->put3BitDouble(coordVar(*this, "UCSORGFRONT"));
2966 buf->put3BitDouble(coordVar(*this, "UCSORGBACK"));
2967 if (version < DRW::AC1021) { // gated: DIMPOST/DIMAPOST as CP8 strings (parseDwg:2019-2022)
2968 buf->putCP8Text(strVar(*this, "DIMPOST"));
2969 buf->putCP8Text(strVar(*this, "DIMAPOST"));
2970 }
2971
2972 // -------- DIM* values for R2000 (parseDwg:2053-2129; R14 branch dropped)
2973 buf->putBitDouble(dblVar(*this, "DIMSCALE", 1.0));
2974 buf->putBitDouble(dblVar(*this, "DIMASZ", 0.18));
2975 buf->putBitDouble(dblVar(*this, "DIMEXO", 0.0625));
2976 buf->putBitDouble(dblVar(*this, "DIMDLI", 0.38));
2977 buf->putBitDouble(dblVar(*this, "DIMEXE", 0.18));
2978 buf->putBitDouble(dblVar(*this, "DIMRND", 0.0));
2979 buf->putBitDouble(dblVar(*this, "DIMDLE", 0.0));
2980 buf->putBitDouble(dblVar(*this, "DIMTP", 0.0));
2981 buf->putBitDouble(dblVar(*this, "DIMTM", 0.0));
2982 if (version > DRW::AC1018) { // 2007+: DIMFXL, DIMJOGANG, DIMTFILL, DIMTFILLCLR (parseDwg:2066-2070)
2983 buf->putBitDouble(dblVar(*this, "DIMFXL", 1.0));
2984 buf->putBitDouble(dblVar(*this, "DIMJOGANG", 0.0));
2985 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTFILL")));
2986 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "DIMTFILLCLR")));
2987 }
2988 // R2000+: 6 bits then 3 BS
2989 buf->putBit(boolVar(*this, "DIMTOL"));
2990 buf->putBit(boolVar(*this, "DIMLIM"));
2991 buf->putBit(boolVar(*this, "DIMTIH"));
2992 buf->putBit(boolVar(*this, "DIMTOH"));
2993 buf->putBit(boolVar(*this, "DIMSE1"));
2994 buf->putBit(boolVar(*this, "DIMSE2"));
2995 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTAD")));
2996 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMZIN")));
2997 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMAZIN")));
2998 if (version > DRW::AC1018) { // 2007+: DIMARCSYM (parseDwg:2083-2085)
2999 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMARCSYM")));
3000 }
3001 buf->putBitDouble(dblVar(*this, "DIMTXT", 0.18));
3002 buf->putBitDouble(dblVar(*this, "DIMCEN", 0.09));
3003 buf->putBitDouble(dblVar(*this, "DIMTSZ", 0.0));
3004 buf->putBitDouble(dblVar(*this, "DIMALTF", 25.4));
3005 buf->putBitDouble(dblVar(*this, "DIMLFAC", 1.0));
3006 buf->putBitDouble(dblVar(*this, "DIMTVP", 0.0));
3007 buf->putBitDouble(dblVar(*this, "DIMTFAC", 1.0));
3008 buf->putBitDouble(dblVar(*this, "DIMGAP", 0.09));
3009 // R2000+: DIMALTRND + 5 more DIM bits
3010 buf->putBitDouble(dblVar(*this, "DIMALTRND", 0.0));
3011 buf->putBit(boolVar(*this, "DIMALT"));
3012 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMALTD", 2)));
3013 buf->putBit(boolVar(*this, "DIMTOFL"));
3014 buf->putBit(boolVar(*this, "DIMSAH"));
3015 buf->putBit(boolVar(*this, "DIMTIX"));
3016 buf->putBit(boolVar(*this, "DIMSOXD"));
3017 // 3 CMC colors
3018 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "DIMCLRD")));
3019 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "DIMCLRE")));
3020 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "DIMCLRT")));
3021 // R2000+ DIM BS family
3022 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMADEC")));
3023 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMDEC", 4)));
3024 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTDEC", 4)));
3025 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMALTU", 2)));
3026 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMALTTD", 2)));
3027 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMAUNIT")));
3028 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMFRAC")));
3029 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMLUNIT", 2)));
3030 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMDSEP", '.')));
3031 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTMOVE")));
3032 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMJUST")));
3033 buf->putBit(boolVar(*this, "DIMSD1"));
3034 buf->putBit(boolVar(*this, "DIMSD2"));
3035 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTOLJ", 1)));
3036 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMTZIN")));
3037 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMALTZ")));
3038 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMALTTZ")));
3039 buf->putBit(boolVar(*this, "DIMUPT"));
3040 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMATFIT", 3)));
3041 if (version > DRW::AC1018) { // 2007+: DIMFXLON (parseDwg:2134-2136)
3042 buf->putBit(boolVar(*this, "DIMFXLON"));
3043 }
3044 if (version > DRW::AC1021) { // 2010+: DIMTXTDIRECTION, DIMALTMZF, DIMMZF (parseDwg:2137-2141)
3045 buf->putBit(boolVar(*this, "DIMTXTDIRECTION"));
3046 buf->putBitDouble(dblVar(*this, "DIMALTMZF", 1.0));
3047 buf->putBitDouble(dblVar(*this, "DIMMZF", 1.0));
3048 }
3049
3050 // -------- DIM handles (R2000+: 5 handles) (parseDwg:2139-2148) ----------
3051 hBbuf->putHandle(makeHardPtr(DRW::DwgStandardTextStyleHandle)); // DIMTXSTY
3052 hBbuf->putHandle(makeHardPtr(0)); // DIMLDRBLK
3053 hBbuf->putHandle(makeHardPtr(0)); // DIMBLK
3054 hBbuf->putHandle(makeHardPtr(0)); // DIMBLK1
3055 hBbuf->putHandle(makeHardPtr(0)); // DIMBLK2
3056 if (version > DRW::AC1018) { // 2007+: DIMLTYPE, DIMLTEX1, DIMLTEX2 (parseDwg:2154-2160)
3057 hBbuf->putHandle(makeHardPtr(0)); // DIMLTYPE
3058 hBbuf->putHandle(makeHardPtr(0)); // DIMLTEX1
3059 hBbuf->putHandle(makeHardPtr(0)); // DIMLTEX2
3060 }
3061
3062 // -------- DIMLWD, DIMLWE (R2000+: 2 BS) (parseDwg:2159-2160) ------------
3063 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMLWD", -2)));
3064 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "DIMLWE", -2)));
3065
3066 // -------- Control-handle block (parseDwg:2162-2199, 12 or 13 handles) ---------
3067 // vpEntHeaderCtrl is R2000 and earlier only (parseDwg skips it for AC1018+).
3068 hBbuf->putHandle(makeHardOwner(blockCtrl)); // BLOCK_CONTROL (0x01)
3069 hBbuf->putHandle(makeHardOwner(layerCtrl)); // LAYER_CONTROL (0x02)
3070 hBbuf->putHandle(makeHardOwner(styleCtrl)); // STYLE_CONTROL (0x03)
3071 hBbuf->putHandle(makeHardOwner(linetypeCtrl)); // LTYPE_CONTROL (0x05)
3072 hBbuf->putHandle(makeHardOwner(viewCtrl)); // VIEW_CONTROL (0x06)
3073 hBbuf->putHandle(makeHardOwner(ucsCtrl)); // UCS_CONTROL (0x07)
3074 hBbuf->putHandle(makeHardOwner(vportCtrl)); // VPORT_CONTROL (0x08)
3075 hBbuf->putHandle(makeHardOwner(appidCtrl)); // APPID_CONTROL (0x09)
3076 hBbuf->putHandle(makeHardOwner(dimstyleCtrl)); // DIMSTYLE_CONTROL (0x0A)
3077 if (version < DRW::AC1018) { // R2000 and earlier only
3078 hBbuf->putHandle(makeHardOwner(vpEntHeaderCtrl)); // VPORT_ENTITY_HEADER_CONTROL (0x0B)
3079 }
3080 hBbuf->putHandle(makeHardPtr(DRW::DwgAcadGroupDictionaryHandle));
3081 hBbuf->putHandle(makeHardPtr(0)); // DICT ACAD_MLINESTYLE
3082 hBbuf->putHandle(makeHardOwner(DRW::DwgNamedObjectsDictionaryHandle));
3083
3084 // -------- Post-control TSTACKALIGN/TSTACKSIZE + 3 NOD-related dict handles
3085 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "TSTACKALIGN", 1)));
3086 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "TSTACKSIZE", 70)));
3087 if (version < DRW::AC1021) { // gated (parseDwg:2208-2211)
3088 buf->putCP8Text(strVar(*this, "HYPERLINKBASE"));
3089 buf->putCP8Text(strVar(*this, "STYLESHEET"));
3090 }
3091 hBbuf->putHandle(makeHardPtr(0)); // DICT LAYOUTS
3092 hBbuf->putHandle(makeHardPtr(0)); // DICT PLOTSETTINGS
3093 hBbuf->putHandle(makeHardPtr(0)); // DICT PLOTSTYLES
3094 if (version > DRW::AC1015) { // R2004+: 2 extra dict handles (parseDwg:2219-2223)
3095 hBbuf->putHandle(makeHardPtr(0)); // DICT MATERIALS
3096 hBbuf->putHandle(makeHardPtr(0)); // DICT COLORS
3097 }
3098 if (version > DRW::AC1018) { // 2007+: DICT VISUALSTYLE (parseDwg:2225-2228)
3099 hBbuf->putHandle(makeHardPtr(0)); // DICT VISUALSTYLE
3100 }
3101 if (version > DRW::AC1024) { // 2013+: unknown handle (parseDwg:2229-2232)
3102 hBbuf->putHandle(makeHardPtr(0));
3103 }
3104
3105 // -------- Flags (BL) + INSUNITS (BS) + CEPSNTYPE (BS) -------------------
3106 buf->putBitLong(0); // Flags — 8 sub-fields per parseDwg comment; defaults to 0
3107 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "INSUNITS")));
3108 std::uint16_t cepsntype = static_cast<std::uint16_t>(intVar(*this, "CEPSNTYPE"));
3109 buf->putBitShort(cepsntype);
3110 if (cepsntype == 3) {
3111 hBbuf->putHandle(makeHardPtr(0)); // CPSNID
3112 }
3113 if (version < DRW::AC1021) { // gated (parseDwg:2242-2245)
3114 buf->putCP8Text(strVar(*this, "FINGERPRINTGUID"));
3115 buf->putCP8Text(strVar(*this, "VERSIONGUID"));
3116 }
3117
3118 // -------- R2004+ RC/BS vars (parseDwg:2247-2261, version > AC1015) -------
3119 if (version > DRW::AC1015) {
3120 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "SORTENTS")));
3121 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "INDEXCTL")));
3122 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "HIDETEXT")));
3123 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "XCLIPFRAME")));
3124 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "DIMASSOC")));
3125 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "HALOGAP")));
3126 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "OBSCUREDCOLOR")));
3127 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "INTERSECTIONCOLOR")));
3128 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "OBSCUREDLTYPE")));
3129 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "INTERSECTIONDISPLAY")));
3130 if (version < DRW::AC1021) { // R2004 only (not R2007+)
3131 buf->putCP8Text(strVar(*this, "PROJECTNAME"));
3132 }
3133 }
3134
3135 // -------- 5 reserved-block handles (parseDwg:2262-2271) -----------------
3136 // PAPER_SPACE, MODEL_SPACE block headers + BYLAYER, BYBLOCK, CONTINUOUS
3137 // linetype records. Reserved handles 0x18, 0x17, 0x10, 0x0F, 0x11.
3138 hBbuf->putHandle(makeHardPtr(0x18)); // BLOCK PAPER_SPACE
3139 hBbuf->putHandle(makeHardPtr(0x17)); // BLOCK MODEL_SPACE
3140 hBbuf->putHandle(makeHardPtr(0x10)); // LTYPE BYLAYER
3141 hBbuf->putHandle(makeHardPtr(0x0F)); // LTYPE BYBLOCK
3142 hBbuf->putHandle(makeHardPtr(0x11)); // LTYPE CONTINUOUS
3143
3144 // -------- R2007+ extra vars (parseDwg:2272-2310, version > AC1018) -------
3145 if (version > DRW::AC1018) {
3146 buf->putBit(boolVar(*this, "CAMERADISPLAY"));
3147 buf->putBitLong(0); // unknown BL 1
3148 buf->putBitLong(0); // unknown BL 2
3149 buf->putBitDouble(0.0); // unknown BD
3150 buf->putBitDouble(dblVar(*this, "STEPSPERSEC", 2.0));
3151 buf->putBitDouble(dblVar(*this, "STEPSIZE", 6.0));
3152 buf->putBitDouble(dblVar(*this, "3DDWFPREC", 2.0));
3153 buf->putBitDouble(dblVar(*this, "LENSLENGTH", 50.0));
3154 buf->putBitDouble(dblVar(*this, "CAMERAHEIGHT", 0.0));
3155 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "SOLIDHIST", 1)));
3156 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "SHOWHIST", 1)));
3157 buf->putBitDouble(dblVar(*this, "PSOLWIDTH", 5.0));
3158 buf->putBitDouble(dblVar(*this, "PSOLHEIGHT", 80.0));
3159 buf->putBitDouble(dblVar(*this, "LOFTANG1", 1.5707963)); // pi/2
3160 buf->putBitDouble(dblVar(*this, "LOFTANG2", 1.5707963));
3161 buf->putBitDouble(dblVar(*this, "LOFTMAG1", 0.0));
3162 buf->putBitDouble(dblVar(*this, "LOFTMAG2", 0.0));
3163 buf->putBitShort(static_cast<std::uint16_t>(intVar(*this, "LOFTPARAM", 7)));
3164 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "LOFTNORMALS", 1)));
3165 buf->putBitDouble(dblVar(*this, "LATITUDE", 37.7950));
3166 buf->putBitDouble(dblVar(*this, "LONGITUDE", -122.394));
3167 buf->putBitDouble(dblVar(*this, "NORTHDIRECTION", 0.0));
3168 buf->putBitLong(static_cast<std::int32_t>(intVar(*this, "TIMEZONE", -8000)));
3169 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "LIGHTGLYPHDISPLAY", 1)));
3170 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "TILEMODELIGHTSYNCH", 1)));
3171 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "DWFFRAME")));
3172 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "DGNFRAME")));
3173 buf->putBit(0); // unknown B
3174 buf->putCmColor(version, static_cast<std::uint16_t>(intVar(*this, "INTERFERECOLOR", 1)));
3175 hBbuf->putHandle(makeHardPtr(0)); // INTERFEREOBJECT VS
3176 hBbuf->putHandle(makeHardPtr(0)); // INTERFEREVPVS
3177 hBbuf->putHandle(makeHardPtr(0)); // DRAGVS
3178 buf->putRawChar8(static_cast<std::uint8_t>(intVar(*this, "CSHADOW")));
3179 buf->putBitDouble(0.0); // unknown BD
3180 }
3181
3182 // -------- R14+ trailing 4 BS unknowns (parseDwg:2307-2312) --------------
3183 buf->putBitShort(0);
3184 buf->putBitShort(0);
3185 buf->putBitShort(0);
3186 buf->putBitShort(0);
3187
3188 // -------- R2007+ string stream (inverse of parseDwg:2329-2372) ----------
3189 // For R2007+ every header TV/TU string lives in a separate string stream,
3190 // read consecutively in field-schema order. Collect them here in that
3191 // exact order; dwgWriter assembles the [data][strings][footer] layout and
3192 // back-patches bitSize so the reader's backward scan finds them. Pre-2007
3193 // versions emit these inline above (gated version < AC1021).
3194 if (version > DRW::AC1018 && strBuf != nullptr) {
3195 strBuf->putUCSText(std::string()); // unknown text 1
3196 strBuf->putUCSText(std::string()); // unknown text 2
3197 strBuf->putUCSText(std::string()); // unknown text 3
3198 strBuf->putUCSText(std::string()); // unknown text 4
3199 strBuf->putUCSText(strVar(*this, "MENU"));
3200 strBuf->putUCSText(strVar(*this, "DIMPOST"));
3201 strBuf->putUCSText(strVar(*this, "DIMAPOST"));
3202 if (version > DRW::AC1021) { // 2010+
3203 strBuf->putUCSText(strVar(*this, "DIMALTMZS"));
3204 strBuf->putUCSText(strVar(*this, "DIMMZS"));
3205 }
3206 strBuf->putUCSText(strVar(*this, "HYPERLINKBASE"));
3207 strBuf->putUCSText(strVar(*this, "STYLESHEET"));
3208 strBuf->putUCSText(strVar(*this, "FINGERPRINTGUID"));
3209 strBuf->putUCSText(strVar(*this, "VERSIONGUID"));
3210 strBuf->putUCSText(strVar(*this, "PROJECTNAME"));
3211 }
3212
3213 return true;
3214}
3215
3216int DRW_Header::measurement(const int unit) {
3217 switch (unit) {
3218 case Units::Inch:
3219 case Units::Foot:
3220 case Units::Mile:
3221 case Units::Microinch:
3222 case Units::Mil:
3223 case Units::Yard:
3224 return Units::English;
3225
3226 default:
3227 break;
3228 }
3229
3230 return Units::Metric;
3231}