Bug Summary

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