@linkiez/dxf-renew 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.github/instructions/code-patterns.instructions.md +1 -1
  2. package/.github/instructions/exdxf.instruction.md +161 -0
  3. package/.github/instructions/tdd.instructions.md +271 -0
  4. package/.yarn/install-state.gz +0 -0
  5. package/CHANGELOG.md +23 -0
  6. package/CONTRIBUTING.md +16 -14
  7. package/PLAN.md +34 -84
  8. package/README.md +43 -8
  9. package/dist/dxf.js +1388 -376
  10. package/docs/DIMENSION_SUMMARY.md +11 -5
  11. package/docs/DXF_VERSION_SUPPORT.md +45 -0
  12. package/docs/ENTITY_SVG_ROADMAP.md +96 -0
  13. package/docs/EZDXF_REFERENCE_SITEMAP.md +55 -0
  14. package/docs/FIXTURE_VALIDATION_EZDXF.md +62 -0
  15. package/docs/README.md +22 -0
  16. package/docs/SVG_RENDERING_INTEGRATION_TESTS.md +119 -0
  17. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +1 -1
  18. package/lib/Helper.cjs +2 -2
  19. package/lib/Helper.cjs.map +2 -2
  20. package/lib/Helper.js +2 -2
  21. package/lib/Helper.js.map +2 -2
  22. package/lib/denormalise.cjs +131 -91
  23. package/lib/denormalise.cjs.map +2 -2
  24. package/lib/denormalise.js +131 -91
  25. package/lib/denormalise.js.map +2 -2
  26. package/lib/dimensionToSVG.cjs +318 -53
  27. package/lib/dimensionToSVG.cjs.map +3 -3
  28. package/lib/dimensionToSVG.js +316 -52
  29. package/lib/dimensionToSVG.js.map +2 -2
  30. package/lib/handlers/entities.cjs +90 -26
  31. package/lib/handlers/entities.cjs.map +3 -3
  32. package/lib/handlers/entities.js +90 -26
  33. package/lib/handlers/entities.js.map +3 -3
  34. package/lib/handlers/entity/dgnUnderlay.cjs +106 -0
  35. package/lib/handlers/entity/dgnUnderlay.cjs.map +7 -0
  36. package/lib/handlers/entity/dgnUnderlay.js +71 -0
  37. package/lib/handlers/entity/dgnUnderlay.js.map +7 -0
  38. package/lib/handlers/entity/dimension.cjs +24 -0
  39. package/lib/handlers/entity/dimension.cjs.map +2 -2
  40. package/lib/handlers/entity/dimension.js +24 -0
  41. package/lib/handlers/entity/dimension.js.map +2 -2
  42. package/lib/handlers/entity/dwfUnderlay.cjs +106 -0
  43. package/lib/handlers/entity/dwfUnderlay.cjs.map +7 -0
  44. package/lib/handlers/entity/dwfUnderlay.js +71 -0
  45. package/lib/handlers/entity/dwfUnderlay.js.map +7 -0
  46. package/lib/handlers/entity/image.cjs +123 -0
  47. package/lib/handlers/entity/image.cjs.map +7 -0
  48. package/lib/handlers/entity/image.js +88 -0
  49. package/lib/handlers/entity/image.js.map +7 -0
  50. package/lib/handlers/entity/leader.cjs +148 -0
  51. package/lib/handlers/entity/leader.cjs.map +7 -0
  52. package/lib/handlers/entity/leader.js +113 -0
  53. package/lib/handlers/entity/leader.js.map +7 -0
  54. package/lib/handlers/entity/pdfUnderlay.cjs +106 -0
  55. package/lib/handlers/entity/pdfUnderlay.cjs.map +7 -0
  56. package/lib/handlers/entity/pdfUnderlay.js +71 -0
  57. package/lib/handlers/entity/pdfUnderlay.js.map +7 -0
  58. package/lib/handlers/entity/tolerance.cjs +90 -0
  59. package/lib/handlers/entity/tolerance.cjs.map +7 -0
  60. package/lib/handlers/entity/tolerance.js +55 -0
  61. package/lib/handlers/entity/tolerance.js.map +7 -0
  62. package/lib/handlers/objects.cjs +257 -136
  63. package/lib/handlers/objects.cjs.map +2 -2
  64. package/lib/handlers/objects.js +257 -136
  65. package/lib/handlers/objects.js.map +2 -2
  66. package/lib/toSVG.cjs +71 -8
  67. package/lib/toSVG.cjs.map +3 -3
  68. package/lib/toSVG.js +72 -9
  69. package/lib/toSVG.js.map +2 -2
  70. package/lib/types/dimension-entity.cjs.map +1 -1
  71. package/lib/types/entity.cjs.map +1 -1
  72. package/lib/types/image-entity.cjs +17 -0
  73. package/lib/types/image-entity.cjs.map +7 -0
  74. package/lib/types/image-entity.js +1 -0
  75. package/lib/types/image-entity.js.map +7 -0
  76. package/lib/types/index.cjs +8 -0
  77. package/lib/types/index.cjs.map +2 -2
  78. package/lib/types/index.js +4 -0
  79. package/lib/types/index.js.map +2 -2
  80. package/lib/types/leader-entity.cjs +17 -0
  81. package/lib/types/leader-entity.cjs.map +7 -0
  82. package/lib/types/leader-entity.js +1 -0
  83. package/lib/types/leader-entity.js.map +7 -0
  84. package/lib/types/options.cjs.map +1 -1
  85. package/lib/types/tables.cjs.map +1 -1
  86. package/lib/types/tolerance-entity.cjs +17 -0
  87. package/lib/types/tolerance-entity.cjs.map +7 -0
  88. package/lib/types/tolerance-entity.js +1 -0
  89. package/lib/types/tolerance-entity.js.map +7 -0
  90. package/lib/types/underlay-entity.cjs +17 -0
  91. package/lib/types/underlay-entity.cjs.map +7 -0
  92. package/lib/types/underlay-entity.js +1 -0
  93. package/lib/types/underlay-entity.js.map +7 -0
  94. package/lib/util/escapeXmlText.cjs +27 -0
  95. package/lib/util/escapeXmlText.cjs.map +7 -0
  96. package/lib/util/escapeXmlText.js +7 -0
  97. package/lib/util/escapeXmlText.js.map +7 -0
  98. package/package.json +6 -1
  99. package/playwright.config.cjs +20 -0
  100. package/src/Helper.ts +3 -3
  101. package/src/denormalise.ts +182 -116
  102. package/src/dimensionToSVG.ts +466 -54
  103. package/src/handlers/entities.ts +109 -34
  104. package/src/handlers/entity/dgnUnderlay.ts +94 -0
  105. package/src/handlers/entity/dimension.ts +27 -1
  106. package/src/handlers/entity/dwfUnderlay.ts +94 -0
  107. package/src/handlers/entity/image.ts +118 -0
  108. package/src/handlers/entity/leader.ts +153 -0
  109. package/src/handlers/entity/pdfUnderlay.ts +94 -0
  110. package/src/handlers/entity/tolerance.ts +75 -0
  111. package/src/handlers/objects.ts +323 -139
  112. package/src/toSVG.ts +98 -7
  113. package/src/types/dimension-entity.ts +11 -0
  114. package/src/types/entity.ts +10 -0
  115. package/src/types/image-entity.ts +35 -0
  116. package/src/types/index.ts +4 -0
  117. package/src/types/leader-entity.ts +40 -0
  118. package/src/types/options.ts +41 -0
  119. package/src/types/tables.ts +84 -0
  120. package/src/types/tolerance-entity.ts +20 -0
  121. package/src/types/underlay-entity.ts +35 -0
  122. package/src/util/escapeXmlText.ts +10 -0
  123. package/tools/browser_test_server.cjs +87 -0
  124. package/tools/ezdxf_generate_dimensions_all_types.py +246 -0
  125. package/tools/ezdxf_generate_dimensions_angular_3p.py +59 -0
  126. package/tools/ezdxf_generate_dimensions_large_scale.py +87 -0
  127. package/tools/ezdxf_regenerate_problem_fixtures.py +184 -0
  128. package/tools/ezdxf_validate_fixtures.py +165 -0
  129. package/docs/DIMENSION_SUMMARY.pt-BR.md +0 -248
  130. package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +0 -54
  131. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +0 -169
package/dist/dxf.js CHANGED
@@ -1391,8 +1391,8 @@ var dxf = (() => {
1391
1391
  "node_modules/lodash/_Set.js"(exports, module) {
1392
1392
  var getNative = require_getNative();
1393
1393
  var root = require_root();
1394
- var Set = getNative(root, "Set");
1395
- module.exports = Set;
1394
+ var Set2 = getNative(root, "Set");
1395
+ module.exports = Set2;
1396
1396
  }
1397
1397
  });
1398
1398
 
@@ -1412,7 +1412,7 @@ var dxf = (() => {
1412
1412
  var DataView = require_DataView();
1413
1413
  var Map = require_Map();
1414
1414
  var Promise2 = require_Promise();
1415
- var Set = require_Set();
1415
+ var Set2 = require_Set();
1416
1416
  var WeakMap = require_WeakMap();
1417
1417
  var baseGetTag = require_baseGetTag();
1418
1418
  var toSource = require_toSource();
@@ -1425,10 +1425,10 @@ var dxf = (() => {
1425
1425
  var dataViewCtorString = toSource(DataView);
1426
1426
  var mapCtorString = toSource(Map);
1427
1427
  var promiseCtorString = toSource(Promise2);
1428
- var setCtorString = toSource(Set);
1428
+ var setCtorString = toSource(Set2);
1429
1429
  var weakMapCtorString = toSource(WeakMap);
1430
1430
  var getTag = baseGetTag;
1431
- if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map && getTag(new Map()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set && getTag(new Set()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) {
1431
+ if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map && getTag(new Map()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set2 && getTag(new Set2()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) {
1432
1432
  getTag = function(value) {
1433
1433
  var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : void 0, ctorString = Ctor ? toSource(Ctor) : "";
1434
1434
  if (ctorString) {
@@ -3316,9 +3316,75 @@ var dxf = (() => {
3316
3316
  };
3317
3317
  var circle_default = { TYPE: TYPE6, process: process6 };
3318
3318
 
3319
- // src/handlers/entity/dimension.ts
3320
- var TYPE7 = "DIMENSION";
3319
+ // src/handlers/entity/dgnUnderlay.ts
3320
+ var TYPE7 = "DGNUNDERLAY";
3321
3321
  var process7 = (tuples) => {
3322
+ return tuples.reduce(
3323
+ (entity, tuple) => {
3324
+ const type = tuple[0];
3325
+ const value = tuple[1];
3326
+ switch (type) {
3327
+ case 340:
3328
+ entity.underlayDefinitionHandle = String(value);
3329
+ break;
3330
+ case 10:
3331
+ entity.insertionPoint.x = value;
3332
+ break;
3333
+ case 20:
3334
+ entity.insertionPoint.y = value;
3335
+ break;
3336
+ case 30:
3337
+ entity.insertionPoint.z = value;
3338
+ break;
3339
+ case 41:
3340
+ entity.scale.x = value;
3341
+ break;
3342
+ case 42:
3343
+ entity.scale.y = value;
3344
+ break;
3345
+ case 43:
3346
+ entity.scale.z = value;
3347
+ break;
3348
+ case 50:
3349
+ entity.rotation = value;
3350
+ break;
3351
+ case 210:
3352
+ entity.normal.x = value;
3353
+ break;
3354
+ case 220:
3355
+ entity.normal.y = value;
3356
+ break;
3357
+ case 230:
3358
+ entity.normal.z = value;
3359
+ break;
3360
+ case 280:
3361
+ entity.flags = value;
3362
+ break;
3363
+ case 281:
3364
+ entity.contrast = value;
3365
+ break;
3366
+ case 282:
3367
+ entity.fade = value;
3368
+ break;
3369
+ default:
3370
+ Object.assign(entity, parseCommonEntityProperties(type, value));
3371
+ break;
3372
+ }
3373
+ return entity;
3374
+ },
3375
+ {
3376
+ type: TYPE7,
3377
+ insertionPoint: { x: 0, y: 0, z: 0 },
3378
+ scale: { x: 1, y: 1, z: 1 },
3379
+ normal: { x: 0, y: 0, z: 1 }
3380
+ }
3381
+ );
3382
+ };
3383
+ var dgnUnderlay_default = { TYPE: TYPE7, process: process7 };
3384
+
3385
+ // src/handlers/entity/dimension.ts
3386
+ var TYPE8 = "DIMENSION";
3387
+ var process8 = (tuples) => {
3322
3388
  return tuples.reduce(
3323
3389
  (entity, tuple) => {
3324
3390
  const type = tuple[0];
@@ -3369,6 +3435,30 @@ var dxf = (() => {
3369
3435
  case 34:
3370
3436
  entity.measureEnd.z = value;
3371
3437
  break;
3438
+ case 15:
3439
+ entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 };
3440
+ entity.angleVertex.x = value;
3441
+ break;
3442
+ case 25:
3443
+ entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 };
3444
+ entity.angleVertex.y = value;
3445
+ break;
3446
+ case 35:
3447
+ entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 };
3448
+ entity.angleVertex.z = value;
3449
+ break;
3450
+ case 16:
3451
+ entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 };
3452
+ entity.arcPoint.x = value;
3453
+ break;
3454
+ case 26:
3455
+ entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 };
3456
+ entity.arcPoint.y = value;
3457
+ break;
3458
+ case 36:
3459
+ entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 };
3460
+ entity.arcPoint.z = value;
3461
+ break;
3372
3462
  case 50:
3373
3463
  entity.rotation = value;
3374
3464
  break;
@@ -3429,7 +3519,7 @@ var dxf = (() => {
3429
3519
  return entity;
3430
3520
  },
3431
3521
  {
3432
- type: TYPE7,
3522
+ type: TYPE8,
3433
3523
  start: { x: 0, y: 0, z: 0 },
3434
3524
  measureStart: { x: 0, y: 0, z: 0 },
3435
3525
  measureEnd: { x: 0, y: 0, z: 0 },
@@ -3477,11 +3567,143 @@ var dxf = (() => {
3477
3567
  userDefinedLocation
3478
3568
  };
3479
3569
  }
3480
- var dimension_default = { TYPE: TYPE7, process: process7 };
3570
+ var dimension_default = { TYPE: TYPE8, process: process8 };
3571
+
3572
+ // src/handlers/entity/dwfUnderlay.ts
3573
+ var TYPE9 = "DWFUNDERLAY";
3574
+ var process9 = (tuples) => {
3575
+ return tuples.reduce(
3576
+ (entity, tuple) => {
3577
+ const type = tuple[0];
3578
+ const value = tuple[1];
3579
+ switch (type) {
3580
+ case 340:
3581
+ entity.underlayDefinitionHandle = String(value);
3582
+ break;
3583
+ case 10:
3584
+ entity.insertionPoint.x = value;
3585
+ break;
3586
+ case 20:
3587
+ entity.insertionPoint.y = value;
3588
+ break;
3589
+ case 30:
3590
+ entity.insertionPoint.z = value;
3591
+ break;
3592
+ case 41:
3593
+ entity.scale.x = value;
3594
+ break;
3595
+ case 42:
3596
+ entity.scale.y = value;
3597
+ break;
3598
+ case 43:
3599
+ entity.scale.z = value;
3600
+ break;
3601
+ case 50:
3602
+ entity.rotation = value;
3603
+ break;
3604
+ case 210:
3605
+ entity.normal.x = value;
3606
+ break;
3607
+ case 220:
3608
+ entity.normal.y = value;
3609
+ break;
3610
+ case 230:
3611
+ entity.normal.z = value;
3612
+ break;
3613
+ case 280:
3614
+ entity.flags = value;
3615
+ break;
3616
+ case 281:
3617
+ entity.contrast = value;
3618
+ break;
3619
+ case 282:
3620
+ entity.fade = value;
3621
+ break;
3622
+ default:
3623
+ Object.assign(entity, parseCommonEntityProperties(type, value));
3624
+ break;
3625
+ }
3626
+ return entity;
3627
+ },
3628
+ {
3629
+ type: TYPE9,
3630
+ insertionPoint: { x: 0, y: 0, z: 0 },
3631
+ scale: { x: 1, y: 1, z: 1 },
3632
+ normal: { x: 0, y: 0, z: 1 }
3633
+ }
3634
+ );
3635
+ };
3636
+ var dwfUnderlay_default = { TYPE: TYPE9, process: process9 };
3637
+
3638
+ // src/handlers/entity/pdfUnderlay.ts
3639
+ var TYPE10 = "PDFUNDERLAY";
3640
+ var process10 = (tuples) => {
3641
+ return tuples.reduce(
3642
+ (entity, tuple) => {
3643
+ const type = tuple[0];
3644
+ const value = tuple[1];
3645
+ switch (type) {
3646
+ case 340:
3647
+ entity.underlayDefinitionHandle = String(value);
3648
+ break;
3649
+ case 10:
3650
+ entity.insertionPoint.x = value;
3651
+ break;
3652
+ case 20:
3653
+ entity.insertionPoint.y = value;
3654
+ break;
3655
+ case 30:
3656
+ entity.insertionPoint.z = value;
3657
+ break;
3658
+ case 41:
3659
+ entity.scale.x = value;
3660
+ break;
3661
+ case 42:
3662
+ entity.scale.y = value;
3663
+ break;
3664
+ case 43:
3665
+ entity.scale.z = value;
3666
+ break;
3667
+ case 50:
3668
+ entity.rotation = value;
3669
+ break;
3670
+ case 210:
3671
+ entity.normal.x = value;
3672
+ break;
3673
+ case 220:
3674
+ entity.normal.y = value;
3675
+ break;
3676
+ case 230:
3677
+ entity.normal.z = value;
3678
+ break;
3679
+ case 280:
3680
+ entity.flags = value;
3681
+ break;
3682
+ case 281:
3683
+ entity.contrast = value;
3684
+ break;
3685
+ case 282:
3686
+ entity.fade = value;
3687
+ break;
3688
+ default:
3689
+ Object.assign(entity, parseCommonEntityProperties(type, value));
3690
+ break;
3691
+ }
3692
+ return entity;
3693
+ },
3694
+ {
3695
+ type: TYPE10,
3696
+ insertionPoint: { x: 0, y: 0, z: 0 },
3697
+ scale: { x: 1, y: 1, z: 1 },
3698
+ normal: { x: 0, y: 0, z: 1 }
3699
+ }
3700
+ );
3701
+ };
3702
+ var pdfUnderlay_default = { TYPE: TYPE10, process: process10 };
3481
3703
 
3482
3704
  // src/handlers/entity/ellipse.ts
3483
- var TYPE8 = "ELLIPSE";
3484
- var process8 = (tuples) => {
3705
+ var TYPE11 = "ELLIPSE";
3706
+ var process11 = (tuples) => {
3485
3707
  return tuples.reduce(
3486
3708
  (entity, tuple) => {
3487
3709
  const type = tuple[0];
@@ -3521,14 +3743,14 @@ var dxf = (() => {
3521
3743
  return entity;
3522
3744
  },
3523
3745
  {
3524
- type: TYPE8
3746
+ type: TYPE11
3525
3747
  }
3526
3748
  );
3527
3749
  };
3528
- var ellipse_default = { TYPE: TYPE8, process: process8 };
3750
+ var ellipse_default = { TYPE: TYPE11, process: process11 };
3529
3751
 
3530
3752
  // src/handlers/entity/hatch.ts
3531
- var TYPE9 = "HATCH";
3753
+ var TYPE12 = "HATCH";
3532
3754
  var status = "IDLE";
3533
3755
  var drawEntity = {};
3534
3756
  var drawType = 0;
@@ -3536,7 +3758,7 @@ var dxf = (() => {
3536
3758
  var seed = null;
3537
3759
  var loop = { references: [], entities: [] };
3538
3760
  var polyPoint = null;
3539
- var process9 = (tuples) => {
3761
+ var process12 = (tuples) => {
3540
3762
  status = "IDLE";
3541
3763
  drawEntity = {};
3542
3764
  drawType = 0;
@@ -3745,7 +3967,7 @@ var dxf = (() => {
3745
3967
  return entity;
3746
3968
  },
3747
3969
  {
3748
- type: TYPE9,
3970
+ type: TYPE12,
3749
3971
  elevation: { x: 0, y: 0, z: 0 },
3750
3972
  extrusionDir: { x: 0, y: 0, z: 1 },
3751
3973
  pattern: {
@@ -3775,7 +3997,7 @@ var dxf = (() => {
3775
3997
  }
3776
3998
  );
3777
3999
  };
3778
- var hatch_default = { TYPE: TYPE9, process: process9 };
4000
+ var hatch_default = { TYPE: TYPE12, process: process12 };
3779
4001
  function createDrawEntity(type) {
3780
4002
  if (isPolyline) return {};
3781
4003
  switch (type) {
@@ -3957,9 +4179,92 @@ var dxf = (() => {
3957
4179
  }
3958
4180
  }
3959
4181
 
4182
+ // src/handlers/entity/image.ts
4183
+ var TYPE13 = "IMAGE";
4184
+ var process13 = (tuples) => {
4185
+ return tuples.reduce(
4186
+ (entity, tuple) => {
4187
+ const type = tuple[0];
4188
+ const value = tuple[1];
4189
+ switch (type) {
4190
+ case 90:
4191
+ entity.classVersion = value;
4192
+ break;
4193
+ case 10:
4194
+ entity.insertionPoint.x = value;
4195
+ break;
4196
+ case 20:
4197
+ entity.insertionPoint.y = value;
4198
+ break;
4199
+ case 30:
4200
+ entity.insertionPoint.z = value;
4201
+ break;
4202
+ case 11:
4203
+ entity.uVector.x = value;
4204
+ break;
4205
+ case 21:
4206
+ entity.uVector.y = value;
4207
+ break;
4208
+ case 31:
4209
+ entity.uVector.z = value;
4210
+ break;
4211
+ case 12:
4212
+ entity.vVector.x = value;
4213
+ break;
4214
+ case 22:
4215
+ entity.vVector.y = value;
4216
+ break;
4217
+ case 32:
4218
+ entity.vVector.z = value;
4219
+ break;
4220
+ case 13:
4221
+ entity.pixelSizeX = value;
4222
+ break;
4223
+ case 23:
4224
+ entity.pixelSizeY = value;
4225
+ break;
4226
+ case 340:
4227
+ entity.imageDefHandle = String(value);
4228
+ break;
4229
+ case 360:
4230
+ entity.imageDefReactorHandle = String(value);
4231
+ break;
4232
+ case 70:
4233
+ entity.displayProperties = value;
4234
+ break;
4235
+ case 280:
4236
+ entity.clippingState = value;
4237
+ break;
4238
+ case 281:
4239
+ entity.brightness = value;
4240
+ break;
4241
+ case 282:
4242
+ entity.contrast = value;
4243
+ break;
4244
+ case 283:
4245
+ entity.fade = value;
4246
+ break;
4247
+ default:
4248
+ Object.assign(entity, parseCommonEntityProperties(type, value));
4249
+ break;
4250
+ }
4251
+ return entity;
4252
+ },
4253
+ {
4254
+ type: TYPE13,
4255
+ insertionPoint: {},
4256
+ uVector: {},
4257
+ vVector: {},
4258
+ pixelSizeX: 0,
4259
+ pixelSizeY: 0
4260
+ }
4261
+ );
4262
+ };
4263
+ var image_default = { TYPE: TYPE13, process: process13 };
4264
+
3960
4265
  // src/handlers/entity/insert.ts
3961
- var TYPE10 = "INSERT";
3962
- var process10 = (tuples) => {
4266
+ var TYPE14 = "INSERT";
4267
+ var process14 = (tuples) => {
3963
4268
  return tuples.reduce(
3964
4269
  (entity, tuple) => {
3965
4270
  const type = tuple[0];
@@ -4017,15 +4322,123 @@ var dxf = (() => {
4017
4322
  return entity;
4018
4323
  },
4019
4324
  {
4020
- type: TYPE10
4325
+ type: TYPE14
4021
4326
  }
4022
4327
  );
4023
4328
  };
4024
- var insert_default = { TYPE: TYPE10, process: process10 };
4329
+ var insert_default = { TYPE: TYPE14, process: process14 };
4330
+
4331
+ // src/handlers/entity/leader.ts
4332
+ var TYPE15 = "LEADER";
4333
+ function ensureVector3(entity, key) {
4334
+ if (!entity[key]) entity[key] = { x: 0, y: 0, z: 0 };
4335
+ return entity[key];
4336
+ }
4337
+ var process15 = (tuples) => {
4338
+ return tuples.reduce(
4339
+ (entity, tuple) => {
4340
+ const type = tuple[0];
4341
+ const value = tuple[1];
4342
+ switch (type) {
4343
+ case 3:
4344
+ entity.dimensionStyleName = String(value);
4345
+ break;
4346
+ case 71:
4347
+ entity.arrowheadFlag = value;
4348
+ break;
4349
+ case 72:
4350
+ entity.pathType = value;
4351
+ break;
4352
+ case 73:
4353
+ entity.creationFlag = value;
4354
+ break;
4355
+ case 74:
4356
+ entity.hooklineDirectionFlag = value;
4357
+ break;
4358
+ case 75:
4359
+ entity.hooklineFlag = value;
4360
+ break;
4361
+ case 40:
4362
+ entity.textHeight = value;
4363
+ break;
4364
+ case 41:
4365
+ entity.textWidth = value;
4366
+ break;
4367
+ case 76:
4368
+ entity.vertexCount = value;
4369
+ break;
4370
+ case 10:
4371
+ entity.vertices.push({ x: value, y: 0, z: 0 });
4372
+ break;
4373
+ case 20: {
4374
+ const current = entity.vertices[entity.vertices.length - 1];
4375
+ if (current) current.y = value;
4376
+ break;
4377
+ }
4378
+ case 30: {
4379
+ const current = entity.vertices[entity.vertices.length - 1];
4380
+ if (current) current.z = value;
4381
+ break;
4382
+ }
4383
+ case 77:
4384
+ entity.color = value;
4385
+ break;
4386
+ case 340:
4387
+ entity.annotationHandle = String(value);
4388
+ break;
4389
+ case 210:
4390
+ ensureVector3(entity, "normal").x = value;
4391
+ break;
4392
+ case 220:
4393
+ ensureVector3(entity, "normal").y = value;
4394
+ break;
4395
+ case 230:
4396
+ ensureVector3(entity, "normal").z = value;
4397
+ break;
4398
+ case 211:
4399
+ ensureVector3(entity, "horizontalDirection").x = value;
4400
+ break;
4401
+ case 221:
4402
+ ensureVector3(entity, "horizontalDirection").y = value;
4403
+ break;
4404
+ case 231:
4405
+ ensureVector3(entity, "horizontalDirection").z = value;
4406
+ break;
4407
+ case 212:
4408
+ ensureVector3(entity, "blockOffset").x = value;
4409
+ break;
4410
+ case 222:
4411
+ ensureVector3(entity, "blockOffset").y = value;
4412
+ break;
4413
+ case 232:
4414
+ ensureVector3(entity, "blockOffset").z = value;
4415
+ break;
4416
+ case 213:
4417
+ ensureVector3(entity, "annotationOffset").x = value;
4418
+ break;
4419
+ case 223:
4420
+ ensureVector3(entity, "annotationOffset").y = value;
4421
+ break;
4422
+ case 233:
4423
+ ensureVector3(entity, "annotationOffset").z = value;
4424
+ break;
4425
+ default:
4426
+ Object.assign(entity, parseCommonEntityProperties(type, value));
4427
+ break;
4428
+ }
4429
+ return entity;
4430
+ },
4431
+ {
4432
+ type: TYPE15,
4433
+ vertices: []
4434
+ }
4435
+ );
4436
+ };
4437
+ var leader_default = { TYPE: TYPE15, process: process15 };
4025
4438
 
4026
4439
  // src/handlers/entity/line.ts
4027
- var TYPE11 = "LINE";
4028
- var process11 = (tuples) => {
4440
+ var TYPE16 = "LINE";
4441
+ var process16 = (tuples) => {
4029
4442
  return tuples.reduce(
4030
4443
  (entity, tuple) => {
4031
4444
  const type = tuple[0];
@@ -4059,17 +4472,17 @@ var dxf = (() => {
4059
4472
  return entity;
4060
4473
  },
4061
4474
  {
4062
- type: TYPE11,
4475
+ type: TYPE16,
4063
4476
  start: {},
4064
4477
  end: {}
4065
4478
  }
4066
4479
  );
4067
4480
  };
4068
- var line_default = { TYPE: TYPE11, process: process11 };
4481
+ var line_default = { TYPE: TYPE16, process: process16 };
4069
4482
 
4070
4483
  // src/handlers/entity/lwpolyline.ts
4071
- var TYPE12 = "LWPOLYLINE";
4072
- var process12 = (tuples) => {
4484
+ var TYPE17 = "LWPOLYLINE";
4485
+ var process17 = (tuples) => {
4073
4486
  let vertex;
4074
4487
  return tuples.reduce(
4075
4488
  (entity, tuple) => {
@@ -4102,16 +4515,16 @@ var dxf = (() => {
4102
4515
  return entity;
4103
4516
  },
4104
4517
  {
4105
- type: TYPE12,
4518
+ type: TYPE17,
4106
4519
  vertices: []
4107
4520
  }
4108
4521
  );
4109
4522
  };
4110
- var lwpolyline_default = { TYPE: TYPE12, process: process12 };
4523
+ var lwpolyline_default = { TYPE: TYPE17, process: process17 };
4111
4524
 
4112
4525
  // src/handlers/entity/ole2Frame.ts
4113
- var TYPE13 = "OLE2FRAME";
4114
- var process13 = (tuples) => {
4526
+ var TYPE18 = "OLE2FRAME";
4527
+ var process18 = (tuples) => {
4115
4528
  return tuples.reduce(
4116
4529
  (entity, tuple) => {
4117
4530
  const type = tuple[0];
@@ -4160,16 +4573,16 @@ var dxf = (() => {
4160
4573
  return entity;
4161
4574
  },
4162
4575
  {
4163
- type: TYPE13,
4576
+ type: TYPE18,
4164
4577
  data: ""
4165
4578
  }
4166
4579
  );
4167
4580
  };
4168
- var ole2Frame_default = { TYPE: TYPE13, process: process13 };
4581
+ var ole2Frame_default = { TYPE: TYPE18, process: process18 };
4169
4582
 
4170
4583
  // src/handlers/entity/point.ts
4171
- var TYPE14 = "POINT";
4172
- var process14 = (tuples) => {
4584
+ var TYPE19 = "POINT";
4585
+ var process19 = (tuples) => {
4173
4586
  return tuples.reduce(
4174
4587
  (entity, tuple) => {
4175
4588
  const type = tuple[0];
@@ -4194,15 +4607,15 @@ var dxf = (() => {
4194
4607
  return entity;
4195
4608
  },
4196
4609
  {
4197
- type: TYPE14
4610
+ type: TYPE19
4198
4611
  }
4199
4612
  );
4200
4613
  };
4201
- var point_default = { TYPE: TYPE14, process: process14 };
4614
+ var point_default = { TYPE: TYPE19, process: process19 };
4202
4615
 
4203
4616
  // src/handlers/entity/polyline.ts
4204
- var TYPE15 = "POLYLINE";
4205
- var process15 = (tuples) => {
4617
+ var TYPE20 = "POLYLINE";
4618
+ var process20 = (tuples) => {
4206
4619
  return tuples.reduce(
4207
4620
  (entity, tuple) => {
4208
4621
  const type = tuple[0];
@@ -4223,16 +4636,16 @@ var dxf = (() => {
4223
4636
  return entity;
4224
4637
  },
4225
4638
  {
4226
- type: TYPE15,
4639
+ type: TYPE20,
4227
4640
  vertices: []
4228
4641
  }
4229
4642
  );
4230
4643
  };
4231
- var polyline_default = { TYPE: TYPE15, process: process15 };
4644
+ var polyline_default = { TYPE: TYPE20, process: process20 };
4232
4645
 
4233
4646
  // src/handlers/entity/solid.ts
4234
- var TYPE16 = "SOLID";
4235
- var process16 = (tuples) => {
4647
+ var TYPE21 = "SOLID";
4648
+ var process21 = (tuples) => {
4236
4649
  return tuples.reduce(
4237
4650
  (entity, tuple) => {
4238
4651
  const type = tuple[0];
@@ -4284,16 +4697,16 @@ var dxf = (() => {
4284
4697
  return entity;
4285
4698
  },
4286
4699
  {
4287
- type: TYPE16,
4700
+ type: TYPE21,
4288
4701
  corners: [{}, {}, {}, {}]
4289
4702
  }
4290
4703
  );
4291
4704
  };
4292
- var solid_default = { TYPE: TYPE16, process: process16 };
4705
+ var solid_default = { TYPE: TYPE21, process: process21 };
4293
4706
 
4294
4707
  // src/handlers/entity/spline.ts
4295
- var TYPE17 = "SPLINE";
4296
- var process17 = (tuples) => {
4708
+ var TYPE22 = "SPLINE";
4709
+ var process22 = (tuples) => {
4297
4710
  let controlPoint;
4298
4711
  return tuples.reduce(
4299
4712
  (entity, tuple) => {
@@ -4352,17 +4765,17 @@ var dxf = (() => {
4352
4765
  return entity;
4353
4766
  },
4354
4767
  {
4355
- type: TYPE17,
4768
+ type: TYPE22,
4356
4769
  controlPoints: [],
4357
4770
  knots: []
4358
4771
  }
4359
4772
  );
4360
4773
  };
4361
- var spline_default = { TYPE: TYPE17, process: process17 };
4774
+ var spline_default = { TYPE: TYPE22, process: process22 };
4362
4775
 
4363
4776
  // src/handlers/entity/threeDFace.ts
4364
- var TYPE18 = "3DFACE";
4365
- var process18 = (tuples) => {
4777
+ var TYPE23 = "3DFACE";
4778
+ var process23 = (tuples) => {
4366
4779
  return tuples.reduce(
4367
4780
  (entity, tuple) => {
4368
4781
  const type = tuple[0];
@@ -4411,22 +4824,72 @@ var dxf = (() => {
4411
4824
  return entity;
4412
4825
  },
4413
4826
  {
4414
- type: TYPE18,
4827
+ type: TYPE23,
4415
4828
  vertices: [{}, {}, {}, {}]
4416
4829
  }
4417
4830
  );
4418
4831
  };
4419
- var threeDFace_default = { TYPE: TYPE18, process: process18 };
4832
+ var threeDFace_default = { TYPE: TYPE23, process: process23 };
4833
+
4834
+ // src/handlers/entity/tolerance.ts
4835
+ var TYPE24 = "TOLERANCE";
4836
+ function ensureVector32(entity, key) {
4837
+ entity[key] ??= { x: 0, y: 0, z: 0 };
4838
+ return entity[key];
4839
+ }
4840
+ var process24 = (tuples) => {
4841
+ return tuples.reduce(
4842
+ (entity, tuple) => {
4843
+ const code = tuple[0];
4844
+ const value = tuple[1];
4845
+ switch (code) {
4846
+ case 3:
4847
+ entity.dimensionStyleName = String(value);
4848
+ break;
4849
+ case 10:
4850
+ ensureVector32(entity, "insertionPoint").x = value;
4851
+ break;
4852
+ case 20:
4853
+ ensureVector32(entity, "insertionPoint").y = value;
4854
+ break;
4855
+ case 30:
4856
+ ensureVector32(entity, "insertionPoint").z = value;
4857
+ break;
4858
+ case 1:
4859
+ entity.text = String(value);
4860
+ break;
4861
+ case 11:
4862
+ ensureVector32(entity, "xAxisDirection").x = value;
4863
+ break;
4864
+ case 21:
4865
+ ensureVector32(entity, "xAxisDirection").y = value;
4866
+ break;
4867
+ case 31:
4868
+ ensureVector32(entity, "xAxisDirection").z = value;
4869
+ break;
4870
+ default:
4871
+ Object.assign(entity, parseCommonEntityProperties(code, value));
4872
+ break;
4873
+ }
4874
+ return entity;
4875
+ },
4876
+ {
4877
+ type: TYPE24,
4878
+ insertionPoint: { x: 0, y: 0, z: 0 }
4879
+ }
4880
+ );
4881
+ };
4882
+ var tolerance_default = { TYPE: TYPE24, process: process24 };
4420
4883
 
4421
4884
  // src/handlers/entity/vertex.ts
4422
- var TYPE19 = "VERTEX";
4885
+ var TYPE25 = "VERTEX";
4423
4886
  var ensureFaces = (entity) => {
4424
4887
  entity.faces = entity.faces || [];
4425
4888
  if ("x" in entity && !entity.x) delete entity.x;
4426
4889
  if ("y" in entity && !entity.y) delete entity.y;
4427
4890
  if ("z" in entity && !entity.z) delete entity.z;
4428
4891
  };
4429
- var process19 = (tuples) => {
4892
+ var process25 = (tuples) => {
4430
4893
  return tuples.reduce((entity, tuple) => {
4431
4894
  const type = tuple[0];
4432
4895
  const value = tuple[1];
@@ -4465,11 +4928,11 @@ var dxf = (() => {
4465
4928
  return entity;
4466
4929
  }, {});
4467
4930
  };
4468
- var vertex_default = { TYPE: TYPE19, process: process19 };
4931
+ var vertex_default = { TYPE: TYPE25, process: process25 };
4469
4932
 
4470
4933
  // src/handlers/entity/viewport.ts
4471
- var TYPE20 = "VIEWPORT";
4472
- var process20 = (tuples) => {
4934
+ var TYPE26 = "VIEWPORT";
4935
+ var process26 = (tuples) => {
4473
4936
  return tuples.reduce(
4474
4937
  (entity, tuple) => {
4475
4938
  const type = tuple[0];
@@ -4567,7 +5030,7 @@ var dxf = (() => {
4567
5030
  return entity;
4568
5031
  },
4569
5032
  {
4570
- type: TYPE20,
5033
+ type: TYPE26,
4571
5034
  center: {},
4572
5035
  centerDCS: {},
4573
5036
  snap: {},
@@ -4578,7 +5041,7 @@ var dxf = (() => {
4578
5041
  }
4579
5042
  );
4580
5043
  };
4581
- var viewport_default = { TYPE: TYPE20, process: process20 };
5044
+ var viewport_default = { TYPE: TYPE26, process: process26 };
4582
5045
 
4583
5046
  // src/handlers/entities.ts
4584
5047
  var handlers = [
@@ -4593,7 +5056,13 @@ var dxf = (() => {
4593
5056
  spline_default,
4594
5057
  solid_default,
4595
5058
  hatch_default,
5059
+ image_default,
5060
+ leader_default,
5061
+ dwfUnderlay_default,
5062
+ dgnUnderlay_default,
5063
+ pdfUnderlay_default,
4596
5064
  mtext_default,
5065
+ tolerance_default,
4597
5066
  attdef_default,
4598
5067
  attrib_default,
4599
5068
  text_default,
@@ -4606,8 +5075,84 @@ var dxf = (() => {
4606
5075
  acc[mod.TYPE] = mod;
4607
5076
  return acc;
4608
5077
  }, {});
5078
+ var EntityGroupProcessor = class {
5079
+ constructor() {
5080
+ this.entities = [];
5081
+ }
5082
+ getEntities() {
5083
+ return this.entities;
5084
+ }
5085
+ finalize() {
5086
+ this.flushOpenPolyline("DXF ended with an open POLYLINE (missing SEQEND); flushing open polyline");
5087
+ }
5088
+ processGroup(tuples) {
5089
+ const entityType = String(tuples[0][1]);
5090
+ const contentTuples = tuples.slice(1);
5091
+ switch (entityType) {
5092
+ case "SEQEND":
5093
+ this.endSequence();
5094
+ break;
5095
+ case "POLYLINE":
5096
+ this.startPolyline(contentTuples);
5097
+ break;
5098
+ case "VERTEX":
5099
+ this.addVertex(contentTuples);
5100
+ break;
5101
+ default:
5102
+ this.addEntity(entityType, contentTuples);
5103
+ break;
5104
+ }
5105
+ }
5106
+ parseEntity(entityType, contentTuples) {
5107
+ const handler = handlers[entityType];
5108
+ if (!handler) {
5109
+ logger_default.warn("unsupported type in ENTITIES section:", entityType);
5110
+ return void 0;
5111
+ }
5112
+ return handler.process(contentTuples);
5113
+ }
5114
+ flushOpenPolyline(reason) {
5115
+ if (!this.currentPolyline) return;
5116
+ logger_default.warn(reason);
5117
+ this.currentPolyline = void 0;
5118
+ }
5119
+ endSequence() {
5120
+ this.currentPolyline = void 0;
5121
+ }
5122
+ startPolyline(contentTuples) {
5123
+ this.flushOpenPolyline(
5124
+ "POLYLINE started while previous POLYLINE is still open; flushing previous polyline"
5125
+ );
5126
+ const e = this.parseEntity("POLYLINE", contentTuples);
5127
+ if (!e) return;
5128
+ this.currentPolyline = e;
5129
+ this.entities.push(e);
5130
+ }
5131
+ addVertex(contentTuples) {
5132
+ const e = this.parseEntity("VERTEX", contentTuples);
5133
+ if (!e) return;
5134
+ if (!this.currentPolyline) {
5135
+ logger_default.error("ignoring invalid VERTEX entity");
5136
+ return;
5137
+ }
5138
+ this.currentPolyline.vertices.push(e);
5139
+ }
5140
+ addEntity(entityType, contentTuples) {
5141
+ this.flushOpenPolyline("POLYLINE sequence ended without SEQEND; flushing open polyline");
5142
+ const e = this.parseEntity(entityType, contentTuples);
5143
+ if (!e) return;
5144
+ this.entities.push(e);
5145
+ }
5146
+ };
5147
+ function processEntityGroups(entityGroups) {
5148
+ const processor = new EntityGroupProcessor();
5149
+ for (const tuples of entityGroups) {
5150
+ processor.processGroup(tuples);
5151
+ }
5152
+ processor.finalize();
5153
+ return processor.getEntities();
5154
+ }
4609
5155
  function parseEntities(tuples) {
4610
- const entities = [];
4611
5156
  const entityGroups = [];
4612
5157
  let currentEntityTuples = [];
4613
5158
  for (const tuple of tuples) {
@@ -4618,31 +5163,7 @@ var dxf = (() => {
4618
5163
  }
4619
5164
  currentEntityTuples.push(tuple);
4620
5165
  }
4621
- let currentPolyline;
4622
- for (const tuples2 of entityGroups) {
4623
- const entityType = tuples2[0][1];
4624
- const contentTuples = tuples2.slice(1);
4625
- if (entityType in handlers) {
4626
- const e = handlers[entityType].process(contentTuples);
4627
- if (entityType === "POLYLINE") {
4628
- currentPolyline = e;
4629
- entities.push(e);
4630
- } else if (entityType === "VERTEX") {
4631
- if (currentPolyline) {
4632
- currentPolyline.vertices.push(e);
4633
- } else {
4634
- logger_default.error("ignoring invalid VERTEX entity");
4635
- }
4636
- } else if (entityType === "SEQEND") {
4637
- currentPolyline = void 0;
4638
- } else {
4639
- entities.push(e);
4640
- }
4641
- } else {
4642
- logger_default.warn("unsupported type in ENTITIES section:", entityType);
4643
- }
4644
- }
4645
- return entities;
5166
+ return processEntityGroups(entityGroups);
4646
5167
  }
4647
5168
 
4648
5169
  // src/handlers/blocks.ts
@@ -4774,152 +5295,273 @@ var dxf = (() => {
4774
5295
  }
4775
5296
  return header;
4776
5297
  }
4777
-
4778
- // src/handlers/objects.ts
4779
- function parseObjects(tuples) {
4780
- let state;
4781
- const objects = {
4782
- layouts: []
5298
+
5299
+ // src/handlers/objects.ts
5300
+ function groupObjectsByZero(tuples) {
5301
+ const groups = [];
5302
+ let current;
5303
+ for (const tuple of tuples) {
5304
+ const code = tuple[0];
5305
+ if (code === 0) {
5306
+ if (current && current.length > 0) groups.push(current);
5307
+ current = [tuple];
5308
+ continue;
5309
+ }
5310
+ if (!current) continue;
5311
+ current.push(tuple);
5312
+ }
5313
+ if (current && current.length > 0) groups.push(current);
5314
+ return groups;
5315
+ }
5316
+ var LAYOUT_FLOAT_FIELDS = {
5317
+ 10: "minLimitX",
5318
+ 20: "minLimitY",
5319
+ 11: "maxLimitX",
5320
+ 21: "maxLimitY",
5321
+ 12: "x",
5322
+ 22: "y",
5323
+ 32: "z",
5324
+ 14: "minX",
5325
+ 24: "minY",
5326
+ 34: "minZ",
5327
+ 15: "maxX",
5328
+ 25: "maxY",
5329
+ 35: "maxZ",
5330
+ 146: "elevation",
5331
+ 13: "ucsX",
5332
+ 23: "ucsY",
5333
+ 33: "ucsZ",
5334
+ 16: "ucsXaxisX",
5335
+ 26: "ucsXaxisY",
5336
+ 36: "ucsXaxisZ",
5337
+ 17: "ucsYaxisX",
5338
+ 27: "ucsYaxisY",
5339
+ 37: "ucsYaxisZ"
5340
+ };
5341
+ var LAYOUT_DIRECT_FIELDS = {
5342
+ 1: "name",
5343
+ 5: "handle",
5344
+ 71: "tabOrder",
5345
+ 330: "tableRecord",
5346
+ 331: "lastActiveViewport",
5347
+ 333: "shadePlot"
5348
+ };
5349
+ var LAYOUT_UCS_TYPE = {
5350
+ 0: "NOT ORTHOGRAPHIC",
5351
+ 1: "TOP",
5352
+ 2: "BOTTOM",
5353
+ 3: "FRONT",
5354
+ 4: "BACK",
5355
+ 5: "LEFT",
5356
+ 6: "RIGHT"
5357
+ };
5358
+ function consumeLayoutStartTuple(current, tuple) {
5359
+ if (tuple[1] === "LAYOUT") return { state: "layout", layout: {} };
5360
+ return { state: "IDLE", layout: current.layout };
5361
+ }
5362
+ function consumeLayoutSubclassTuple(current, tuple) {
5363
+ if (tuple[0] === 100 && tuple[1] === "AcDbLayout") return { state: "AcDbLayout", layout: current.layout };
5364
+ return current;
5365
+ }
5366
+ function applyLayoutFieldTuple(layout, tuple) {
5367
+ const type = tuple[0];
5368
+ const value = tuple[1];
5369
+ const floatKey = LAYOUT_FLOAT_FIELDS[type];
5370
+ if (floatKey) {
5371
+ ;
5372
+ layout[floatKey] = Number.parseFloat(String(value));
5373
+ return;
5374
+ }
5375
+ const directKey = LAYOUT_DIRECT_FIELDS[type];
5376
+ if (directKey) {
5377
+ ;
5378
+ layout[directKey] = value;
5379
+ return;
5380
+ }
5381
+ if (type === 70) {
5382
+ layout.flag = value === 1 ? "PSLTSCALE" : "LIMCHECK";
5383
+ return;
5384
+ }
5385
+ if (type === 76) {
5386
+ const ucsType = LAYOUT_UCS_TYPE[Number(value)];
5387
+ if (ucsType) layout.ucsType = ucsType;
5388
+ }
5389
+ }
5390
+ function consumeLayoutTuple(current, tuple) {
5391
+ if (tuple[0] === 0) return consumeLayoutStartTuple(current, tuple);
5392
+ if (current.state === "layout") return consumeLayoutSubclassTuple(current, tuple);
5393
+ if (current.state === "AcDbLayout" && current.layout) applyLayoutFieldTuple(current.layout, tuple);
5394
+ return current;
5395
+ }
5396
+ function parseLayoutObject(group) {
5397
+ let current = { state: "IDLE" };
5398
+ for (const tuple of group) current = consumeLayoutTuple(current, tuple);
5399
+ return current.layout;
5400
+ }
5401
+ function parseDictionaryObject(group) {
5402
+ if (group[0]?.[1] !== "DICTIONARY") return void 0;
5403
+ const dict = {
5404
+ type: "DICTIONARY",
5405
+ entries: {}
4783
5406
  };
4784
- let layout;
4785
- for (const tuple of tuples) {
5407
+ let pendingKey;
5408
+ for (const tuple of group.slice(1)) {
4786
5409
  const type = tuple[0];
4787
5410
  const value = tuple[1];
4788
- if (type === 0) {
4789
- state = "IDLE";
5411
+ if (type === 5) {
5412
+ dict.handle = value;
5413
+ continue;
4790
5414
  }
4791
- if (value === "LAYOUT") {
4792
- state = "layout";
4793
- layout = {};
4794
- objects.layouts.push(layout);
5415
+ if (type === 330) {
5416
+ dict.ownerHandle = value;
5417
+ continue;
4795
5418
  }
4796
- if (state === "layout" && type !== 0) {
4797
- switch (type) {
4798
- case 100:
4799
- if (value === "AcDbLayout") state = "AcDbLayout";
4800
- break;
4801
- }
5419
+ if (type === 3) {
5420
+ pendingKey = String(value);
5421
+ continue;
4802
5422
  }
4803
- if (state === "AcDbLayout" && type !== 0 && layout) {
4804
- switch (type) {
4805
- case 1:
4806
- layout.name = value;
4807
- break;
4808
- case 5:
4809
- layout.handle = value;
4810
- break;
4811
- case 10:
4812
- layout.minLimitX = Number.parseFloat(String(value));
4813
- break;
4814
- case 20:
4815
- layout.minLimitY = Number.parseFloat(String(value));
4816
- break;
4817
- case 11:
4818
- layout.maxLimitX = Number.parseFloat(String(value));
4819
- break;
4820
- case 21:
4821
- layout.maxLimitY = Number.parseFloat(String(value));
4822
- break;
4823
- case 12:
4824
- layout.x = Number.parseFloat(String(value));
4825
- break;
4826
- case 22:
4827
- layout.y = Number.parseFloat(String(value));
4828
- break;
4829
- case 32:
4830
- layout.z = Number.parseFloat(String(value));
4831
- break;
4832
- case 14:
4833
- layout.minX = Number.parseFloat(String(value));
4834
- break;
4835
- case 24:
4836
- layout.minY = Number.parseFloat(String(value));
4837
- break;
4838
- case 34:
4839
- layout.minZ = Number.parseFloat(String(value));
4840
- break;
4841
- case 15:
4842
- layout.maxX = Number.parseFloat(String(value));
4843
- break;
4844
- case 25:
4845
- layout.maxY = Number.parseFloat(String(value));
4846
- break;
4847
- case 35:
4848
- layout.maxZ = Number.parseFloat(String(value));
4849
- break;
4850
- case 70:
4851
- layout.flag = value === 1 ? "PSLTSCALE" : "LIMCHECK";
4852
- break;
4853
- case 71:
4854
- layout.tabOrder = value;
4855
- break;
4856
- case 146:
4857
- layout.elevation = Number.parseFloat(String(value));
4858
- break;
4859
- case 13:
4860
- layout.ucsX = Number.parseFloat(String(value));
4861
- break;
4862
- case 23:
4863
- layout.ucsY = Number.parseFloat(String(value));
4864
- break;
4865
- case 33:
4866
- layout.ucsZ = Number.parseFloat(String(value));
4867
- break;
4868
- case 16:
4869
- layout.ucsXaxisX = Number.parseFloat(String(value));
4870
- break;
4871
- case 26:
4872
- layout.ucsXaxisY = Number.parseFloat(String(value));
4873
- break;
4874
- case 36:
4875
- layout.ucsXaxisZ = Number.parseFloat(String(value));
4876
- break;
4877
- case 17:
4878
- layout.ucsYaxisX = Number.parseFloat(String(value));
4879
- break;
4880
- case 27:
4881
- layout.ucsYaxisY = Number.parseFloat(String(value));
4882
- break;
4883
- case 37:
4884
- layout.ucsYaxisZ = Number.parseFloat(String(value));
4885
- break;
4886
- case 76:
4887
- switch (value) {
4888
- case 0:
4889
- layout.ucsType = "NOT ORTHOGRAPHIC";
4890
- break;
4891
- case 1:
4892
- layout.ucsType = "TOP";
4893
- break;
4894
- case 2:
4895
- layout.ucsType = "BOTTOM";
4896
- break;
4897
- case 3:
4898
- layout.ucsType = "FRONT";
4899
- break;
4900
- case 4:
4901
- layout.ucsType = "BACK";
4902
- break;
4903
- case 5:
4904
- layout.ucsType = "LEFT";
4905
- break;
4906
- case 6:
4907
- layout.ucsType = "RIGHT";
4908
- break;
4909
- }
4910
- break;
4911
- case 330:
4912
- layout.tableRecord = value;
4913
- break;
4914
- case 331:
4915
- layout.lastActiveViewport = value;
4916
- break;
4917
- case 333:
4918
- layout.shadePlot = value;
4919
- break;
4920
- }
5423
+ if ((type === 350 || type === 360) && pendingKey) {
5424
+ dict.entries[pendingKey] = String(value);
5425
+ pendingKey = void 0;
4921
5426
  }
4922
5427
  }
5428
+ return dict;
5429
+ }
5430
+ function parseXRecordObject(group) {
5431
+ if (group[0]?.[1] !== "XRECORD") return void 0;
5432
+ const tuples = group.slice(1);
5433
+ const xRecord = {
5434
+ type: "XRECORD",
5435
+ tuples
5436
+ };
5437
+ for (const tuple of tuples) {
5438
+ const type = tuple[0];
5439
+ const value = tuple[1];
5440
+ if (type === 5) xRecord.handle = value;
5441
+ if (type === 330) xRecord.ownerHandle = value;
5442
+ }
5443
+ return xRecord;
5444
+ }
5445
+ function parseImageDefObject(group) {
5446
+ if (group[0]?.[1] !== "IMAGEDEF") return void 0;
5447
+ const tuples = group.slice(1);
5448
+ const imageDef = {
5449
+ type: "IMAGEDEF",
5450
+ tuples
5451
+ };
5452
+ for (const tuple of tuples) {
5453
+ const type = tuple[0];
5454
+ const value = tuple[1];
5455
+ if (type === 5) imageDef.handle = value;
5456
+ if (type === 330 && imageDef.ownerHandle === void 0) imageDef.ownerHandle = value;
5457
+ if (type === 1) imageDef.fileName = String(value);
5458
+ if (type === 10) imageDef.pixelSizeX = Number(value);
5459
+ if (type === 20) imageDef.pixelSizeY = Number(value);
5460
+ }
5461
+ return imageDef;
5462
+ }
5463
+ function parseImageDefReactorObject(group) {
5464
+ if (group[0]?.[1] !== "IMAGEDEF_REACTOR") return void 0;
5465
+ const tuples = group.slice(1);
5466
+ const reactor = {
5467
+ type: "IMAGEDEF_REACTOR",
5468
+ tuples
5469
+ };
5470
+ for (const tuple of tuples) {
5471
+ const type = tuple[0];
5472
+ const value = tuple[1];
5473
+ if (type === 5) reactor.handle = value;
5474
+ if (type === 330) reactor.imageHandle = value;
5475
+ }
5476
+ return reactor;
5477
+ }
5478
+ var UNDERLAY_DEFINITION_OBJECT_TYPES = /* @__PURE__ */ new Set([
5479
+ "UNDERLAYDEFINITION",
5480
+ "PDFDEFINITION",
5481
+ "DWFDEFINITION",
5482
+ "DGNDEFINITION"
5483
+ ]);
5484
+ function parseUnderlayDefinitionObject(group) {
5485
+ const objectType = group[0]?.[1];
5486
+ if (typeof objectType !== "string") return void 0;
5487
+ if (!UNDERLAY_DEFINITION_OBJECT_TYPES.has(objectType)) return void 0;
5488
+ const tuples = group.slice(1);
5489
+ const def = {
5490
+ type: objectType,
5491
+ tuples
5492
+ };
5493
+ for (const tuple of tuples) {
5494
+ const type = tuple[0];
5495
+ const value = tuple[1];
5496
+ if (type === 5) def.handle = value;
5497
+ if (type === 330 && def.ownerHandle === void 0) def.ownerHandle = value;
5498
+ if (type === 1) def.fileName = String(value);
5499
+ if (type === 2) def.underlayName = String(value);
5500
+ }
5501
+ return def;
5502
+ }
5503
+ var OBJECT_GROUP_HANDLERS = {
5504
+ LAYOUT: (objects, group) => {
5505
+ const layout = parseLayoutObject(group);
5506
+ if (layout) objects.layouts.push(layout);
5507
+ },
5508
+ DICTIONARY: (objects, group) => {
5509
+ const dict = parseDictionaryObject(group);
5510
+ const handle = dict?.handle ? String(dict.handle) : void 0;
5511
+ if (dict && handle) objects.dictionaries[handle] = dict;
5512
+ },
5513
+ XRECORD: (objects, group) => {
5514
+ const xRecord = parseXRecordObject(group);
5515
+ const handle = xRecord?.handle ? String(xRecord.handle) : void 0;
5516
+ if (xRecord && handle) objects.xRecords[handle] = xRecord;
5517
+ },
5518
+ IMAGEDEF: (objects, group) => {
5519
+ const imageDef = parseImageDefObject(group);
5520
+ const handle = imageDef?.handle ? String(imageDef.handle) : void 0;
5521
+ if (imageDef && handle) objects.imageDefs[handle] = imageDef;
5522
+ },
5523
+ IMAGEDEF_REACTOR: (objects, group) => {
5524
+ const reactor = parseImageDefReactorObject(group);
5525
+ const handle = reactor?.handle ? String(reactor.handle) : void 0;
5526
+ if (reactor && handle) objects.imageDefReactors[handle] = reactor;
5527
+ },
5528
+ UNDERLAYDEFINITION: (objects, group) => {
5529
+ const def = parseUnderlayDefinitionObject(group);
5530
+ const handle = def?.handle ? String(def.handle) : void 0;
5531
+ if (def && handle) objects.underlayDefinitions[handle] = def;
5532
+ },
5533
+ PDFDEFINITION: (objects, group) => {
5534
+ const def = parseUnderlayDefinitionObject(group);
5535
+ const handle = def?.handle ? String(def.handle) : void 0;
5536
+ if (def && handle) objects.underlayDefinitions[handle] = def;
5537
+ },
5538
+ DWFDEFINITION: (objects, group) => {
5539
+ const def = parseUnderlayDefinitionObject(group);
5540
+ const handle = def?.handle ? String(def.handle) : void 0;
5541
+ if (def && handle) objects.underlayDefinitions[handle] = def;
5542
+ },
5543
+ DGNDEFINITION: (objects, group) => {
5544
+ const def = parseUnderlayDefinitionObject(group);
5545
+ const handle = def?.handle ? String(def.handle) : void 0;
5546
+ if (def && handle) objects.underlayDefinitions[handle] = def;
5547
+ }
5548
+ };
5549
+ function parseObjects(tuples) {
5550
+ const objects = {
5551
+ layouts: [],
5552
+ dictionaries: {},
5553
+ xRecords: {},
5554
+ imageDefs: {},
5555
+ imageDefReactors: {},
5556
+ underlayDefinitions: {}
5557
+ };
5558
+ const groups = groupObjectsByZero(tuples);
5559
+ for (const group of groups) {
5560
+ const objectType = group[0]?.[1];
5561
+ if (typeof objectType !== "string") continue;
5562
+ const handler = OBJECT_GROUP_HANDLERS[objectType];
5563
+ if (handler) handler(objects, group);
5564
+ }
4923
5565
  return objects;
4924
5566
  }
4925
5567
 
@@ -5559,6 +6201,133 @@ var dxf = (() => {
5559
6201
 
5560
6202
  // src/denormalise.ts
5561
6203
  var import_cloneDeep = __toESM(require_cloneDeep(), 1);
6204
+ function adjustLineForBlockBasePoint(entity, block) {
6205
+ const line = entity;
6206
+ line.start.x -= block.x;
6207
+ line.start.y -= block.y;
6208
+ line.end.x -= block.x;
6209
+ line.end.y -= block.y;
6210
+ }
6211
+ function adjustPolylineForBlockBasePoint(entity, block) {
6212
+ const poly = entity;
6213
+ for (const v of poly.vertices) {
6214
+ if (v.x !== void 0) v.x -= block.x;
6215
+ if (v.y !== void 0) v.y -= block.y;
6216
+ }
6217
+ }
6218
+ function adjustCircleForBlockBasePoint(entity, block) {
6219
+ const circle2 = entity;
6220
+ circle2.x -= block.x;
6221
+ circle2.y -= block.y;
6222
+ }
6223
+ function adjustEllipseForBlockBasePoint(entity, block) {
6224
+ const ellipse2 = entity;
6225
+ ellipse2.x -= block.x;
6226
+ ellipse2.y -= block.y;
6227
+ }
6228
+ function adjustArcForBlockBasePoint(entity, block) {
6229
+ const arc2 = entity;
6230
+ arc2.x -= block.x;
6231
+ arc2.y -= block.y;
6232
+ }
6233
+ function adjustSplineForBlockBasePoint(entity, block) {
6234
+ const spline = entity;
6235
+ for (const cp of spline.controlPoints) {
6236
+ cp.x -= block.x;
6237
+ cp.y -= block.y;
6238
+ }
6239
+ }
6240
+ function adjustTextForBlockBasePoint(entity, block) {
6241
+ const text2 = entity;
6242
+ if (text2.x !== void 0) text2.x -= block.x;
6243
+ if (text2.y !== void 0) text2.y -= block.y;
6244
+ if (text2.x2 !== void 0) text2.x2 -= block.x;
6245
+ if (text2.y2 !== void 0) text2.y2 -= block.y;
6246
+ }
6247
+ function adjustMTextForBlockBasePoint(entity, block) {
6248
+ const mtext2 = entity;
6249
+ if (mtext2.x !== void 0) mtext2.x -= block.x;
6250
+ if (mtext2.y !== void 0) mtext2.y -= block.y;
6251
+ }
6252
+ function adjustDimensionForBlockBasePoint(entity, block) {
6253
+ const dim = entity;
6254
+ dim.start.x -= block.x;
6255
+ dim.start.y -= block.y;
6256
+ dim.textMidpoint.x -= block.x;
6257
+ dim.textMidpoint.y -= block.y;
6258
+ dim.measureStart.x -= block.x;
6259
+ dim.measureStart.y -= block.y;
6260
+ dim.measureEnd.x -= block.x;
6261
+ dim.measureEnd.y -= block.y;
6262
+ }
6263
+ var BLOCK_BASEPOINT_ADJUSTERS = {
6264
+ LINE: adjustLineForBlockBasePoint,
6265
+ LWPOLYLINE: adjustPolylineForBlockBasePoint,
6266
+ POLYLINE: adjustPolylineForBlockBasePoint,
6267
+ CIRCLE: adjustCircleForBlockBasePoint,
6268
+ ELLIPSE: adjustEllipseForBlockBasePoint,
6269
+ ARC: adjustArcForBlockBasePoint,
6270
+ SPLINE: adjustSplineForBlockBasePoint,
6271
+ TEXT: adjustTextForBlockBasePoint,
6272
+ MTEXT: adjustMTextForBlockBasePoint,
6273
+ DIMENSION: adjustDimensionForBlockBasePoint
6274
+ };
6275
+ function applyBlockBasePointAdjustment(entity, block) {
6276
+ const adjust = BLOCK_BASEPOINT_ADJUSTERS[entity.type];
6277
+ if (adjust) adjust(entity, block);
6278
+ }
6279
+ function computeRectangularArrayVectors(insert) {
6280
+ const rowCount = insert.rowCount ?? 1;
6281
+ const columnCount = insert.columnCount ?? 1;
6282
+ const rowSpacing = insert.rowSpacing ?? 0;
6283
+ const columnSpacing = insert.columnSpacing ?? 0;
6284
+ const rotation = insert.rotation ?? 0;
6285
+ if (rowCount <= 1 && columnCount <= 1) {
6286
+ return { rowVec: { x: 0, y: 0 }, colVec: { x: 0, y: 0 } };
6287
+ }
6288
+ const cos = Math.cos(rotation * Math.PI / 180);
6289
+ const sin = Math.sin(rotation * Math.PI / 180);
6290
+ return {
6291
+ rowVec: { x: -sin * rowSpacing, y: cos * rowSpacing },
6292
+ colVec: { x: cos * columnSpacing, y: sin * columnSpacing }
6293
+ };
6294
+ }
6295
+ function expandInsert(insert, blocksByName, transforms, gatherEntities) {
6296
+ const block = blocksByName[insert.block];
6297
+ if (!block) {
6298
+ logger_default.error("no block found for insert. block:", insert.block);
6299
+ return [];
6300
+ }
6301
+ const rowCount = insert.rowCount ?? 1;
6302
+ const columnCount = insert.columnCount ?? 1;
6303
+ const { rowVec, colVec } = computeRectangularArrayVectors(insert);
6304
+ const current = [];
6305
+ for (let r = 0; r < rowCount; r++) {
6306
+ for (let c = 0; c < columnCount; c++) {
6307
+ const t = {
6308
+ x: insert.x + rowVec.x * r + colVec.x * c,
6309
+ y: insert.y + rowVec.y * r + colVec.y * c,
6310
+ scaleX: insert.scaleX,
6311
+ scaleY: insert.scaleY,
6312
+ scaleZ: insert.scaleZ,
6313
+ extrusionX: insert.extrusionX,
6314
+ extrusionY: insert.extrusionY,
6315
+ extrusionZ: insert.extrusionZ,
6316
+ rotation: insert.rotation
6317
+ };
6318
+ const transforms2 = transforms.slice(0);
6319
+ transforms2.push(t);
6320
+ const blockEntities = block.entities.map((be) => {
6321
+ const be2 = (0, import_cloneDeep.default)(be);
6322
+ be2.layer = insert.layer;
6323
+ applyBlockBasePointAdjustment(be2, block);
6324
+ return be2;
6325
+ });
6326
+ current.push(...gatherEntities(blockEntities, transforms2));
6327
+ }
6328
+ }
6329
+ return current;
6330
+ }
5562
6331
  function denormalise(parseResult) {
5563
6332
  const blocksByName = parseResult.blocks.reduce(
5564
6333
  (acc, b) => {
@@ -5568,99 +6337,12 @@ var dxf = (() => {
5568
6337
  {}
5569
6338
  );
5570
6339
  const gatherEntities = (entities, transforms) => {
5571
- let current = [];
6340
+ const current = [];
5572
6341
  for (const e of entities) {
5573
6342
  if (e.type === "INSERT") {
5574
- const insert = e;
5575
- const block = blocksByName[insert.block];
5576
- if (!block) {
5577
- logger_default.error("no block found for insert. block:", insert.block);
5578
- continue;
5579
- }
5580
- const rowCount = insert.rowCount ?? 1;
5581
- const columnCount = insert.columnCount ?? 1;
5582
- const rowSpacing = insert.rowSpacing ?? 0;
5583
- const columnSpacing = insert.columnSpacing ?? 0;
5584
- const rotation = insert.rotation ?? 0;
5585
- let rowVec;
5586
- let colVec;
5587
- if (rowCount > 1 || columnCount > 1) {
5588
- const cos = Math.cos(rotation * Math.PI / 180);
5589
- const sin = Math.sin(rotation * Math.PI / 180);
5590
- rowVec = { x: -sin * rowSpacing, y: cos * rowSpacing };
5591
- colVec = { x: cos * columnSpacing, y: sin * columnSpacing };
5592
- } else {
5593
- rowVec = { x: 0, y: 0 };
5594
- colVec = { x: 0, y: 0 };
5595
- }
5596
- for (let r = 0; r < rowCount; r++) {
5597
- for (let c = 0; c < columnCount; c++) {
5598
- const t = {
5599
- x: insert.x + rowVec.x * r + colVec.x * c,
5600
- y: insert.y + rowVec.y * r + colVec.y * c,
5601
- scaleX: insert.scaleX,
5602
- scaleY: insert.scaleY,
5603
- scaleZ: insert.scaleZ,
5604
- extrusionX: insert.extrusionX,
5605
- extrusionY: insert.extrusionY,
5606
- extrusionZ: insert.extrusionZ,
5607
- rotation: insert.rotation
5608
- };
5609
- const transforms2 = transforms.slice(0);
5610
- transforms2.push(t);
5611
- const blockEntities = block.entities.map((be) => {
5612
- const be2 = (0, import_cloneDeep.default)(be);
5613
- be2.layer = insert.layer;
5614
- switch (be2.type) {
5615
- case "LINE": {
5616
- const line = be2;
5617
- line.start.x -= block.x;
5618
- line.start.y -= block.y;
5619
- line.end.x -= block.x;
5620
- line.end.y -= block.y;
5621
- break;
5622
- }
5623
- case "LWPOLYLINE":
5624
- case "POLYLINE": {
5625
- const poly = be2;
5626
- for (const v of poly.vertices) {
5627
- if (v.x !== void 0) v.x -= block.x;
5628
- if (v.y !== void 0) v.y -= block.y;
5629
- }
5630
- break;
5631
- }
5632
- case "CIRCLE": {
5633
- const circle2 = be2;
5634
- circle2.x -= block.x;
5635
- circle2.y -= block.y;
5636
- break;
5637
- }
5638
- case "ELLIPSE": {
5639
- const ellipse2 = be2;
5640
- ellipse2.x -= block.x;
5641
- ellipse2.y -= block.y;
5642
- break;
5643
- }
5644
- case "ARC": {
5645
- const arc2 = be2;
5646
- arc2.x -= block.x;
5647
- arc2.y -= block.y;
5648
- break;
5649
- }
5650
- case "SPLINE": {
5651
- const spline = be2;
5652
- for (const cp of spline.controlPoints) {
5653
- cp.x -= block.x;
5654
- cp.y -= block.y;
5655
- }
5656
- break;
5657
- }
5658
- }
5659
- return be2;
5660
- });
5661
- current = current.concat(gatherEntities(blockEntities, transforms2));
5662
- }
5663
- }
6343
+ current.push(
6344
+ ...expandInsert(e, blocksByName, transforms, gatherEntities)
6345
+ );
5664
6346
  } else {
5665
6347
  const e2 = (0, import_cloneDeep.default)(e);
5666
6348
  e2.transforms = transforms.slice().reverse();
@@ -6367,6 +7049,173 @@ var dxf = (() => {
6367
7049
 
6368
7050
  // src/dimensionToSVG.ts
6369
7051
  var import_vecks3 = __toESM(require_lib(), 1);
7052
+
7053
+ // src/util/escapeXmlText.ts
7054
+ function escapeXmlText(value) {
7055
+ return value.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;").split('"').join("&quot;").split("'").join("&apos;");
7056
+ }
7057
+
7058
+ // src/dimensionToSVG.ts
7059
+ var DEFAULT_DIMENSION_DECIMALS = 2;
7060
+ var AUTOSCALE_VIEWPORT_REFERENCE = 40;
7061
+ var computeViewportAutoScaleFactor = (viewport, options) => {
7062
+ const viewportMin = Math.min(Math.abs(viewport.width), Math.abs(viewport.height));
7063
+ if (!Number.isFinite(viewportMin) || viewportMin <= 0) return 1;
7064
+ const reference = options?.dimension?.autoScaleViewportReference;
7065
+ const safeReference = Number.isFinite(reference) && (reference ?? 0) > 0 ? reference : AUTOSCALE_VIEWPORT_REFERENCE;
7066
+ return viewportMin / safeReference;
7067
+ };
7068
+ var getViewportMin = (viewport) => {
7069
+ const viewportMin = Math.min(Math.abs(viewport.width), Math.abs(viewport.height));
7070
+ return Number.isFinite(viewportMin) ? viewportMin : Number.NaN;
7071
+ };
7072
+ var getViewportPercentageSize = (viewport, percent) => {
7073
+ if (!Number.isFinite(percent) || (percent ?? 0) <= 0) return void 0;
7074
+ const viewportMin = getViewportMin(viewport);
7075
+ if (!Number.isFinite(viewportMin) || viewportMin <= 0) return void 0;
7076
+ return viewportMin * (percent / 100);
7077
+ };
7078
+ var getDimensionGeometryBBox = (entity) => {
7079
+ const bbox = new import_vecks3.Box2();
7080
+ const points = [
7081
+ entity.start,
7082
+ entity.angleVertex,
7083
+ entity.arcPoint,
7084
+ entity.textMidpoint,
7085
+ entity.measureStart,
7086
+ entity.measureEnd
7087
+ ];
7088
+ for (const p of points) {
7089
+ if (!p) continue;
7090
+ const x = p.x;
7091
+ const y = p.y;
7092
+ if (!Number.isFinite(x) || !Number.isFinite(y)) continue;
7093
+ bbox.expandByPoint({ x, y });
7094
+ }
7095
+ return bbox;
7096
+ };
7097
+ var getScaledDimensionSizes = (dimStyle, options, viewport) => {
7098
+ const autoScale = options?.dimension?.autoScale === true;
7099
+ const baseArrowSize = dimStyle?.dimAsz ?? 2.5;
7100
+ const baseTextHeight = dimStyle?.dimTxt ?? 2.5;
7101
+ const baseExtLineOffset = dimStyle?.dimExo ?? 0.625;
7102
+ const baseExtLineExtension = dimStyle?.dimExe ?? 1.25;
7103
+ if (!autoScale || !viewport) {
7104
+ return {
7105
+ arrowSize: baseArrowSize,
7106
+ textHeight: baseTextHeight,
7107
+ extLineOffset: baseExtLineOffset,
7108
+ extLineExtension: baseExtLineExtension
7109
+ };
7110
+ }
7111
+ const scale = computeViewportAutoScaleFactor(viewport, options);
7112
+ const perc = options?.dimension?.autoScaleViewportPercentages;
7113
+ const arrowFromPct = getViewportPercentageSize(viewport, perc?.arrowSize);
7114
+ const textFromPct = getViewportPercentageSize(viewport, perc?.textHeight);
7115
+ const offsetFromPct = getViewportPercentageSize(viewport, perc?.extLineOffset);
7116
+ const extensionFromPct = getViewportPercentageSize(viewport, perc?.extLineExtension);
7117
+ return {
7118
+ arrowSize: arrowFromPct ?? baseArrowSize * scale,
7119
+ textHeight: textFromPct ?? baseTextHeight * scale,
7120
+ extLineOffset: offsetFromPct ?? baseExtLineOffset * scale,
7121
+ extLineExtension: extensionFromPct ?? baseExtLineExtension * scale
7122
+ };
7123
+ };
7124
+ var formatDimensionValue = (value, decimals = DEFAULT_DIMENSION_DECIMALS) => {
7125
+ if (!Number.isFinite(value)) return "";
7126
+ const rounded = round10(value, -decimals);
7127
+ return rounded.toFixed(decimals);
7128
+ };
7129
+ var computeRadiusFallback = (entity) => {
7130
+ const cx = entity.start?.x ?? 0;
7131
+ const cy = entity.start?.y ?? 0;
7132
+ const x1 = entity.measureStart?.x ?? 0;
7133
+ const y1 = entity.measureStart?.y ?? 0;
7134
+ const x2 = entity.measureEnd?.x ?? 0;
7135
+ const y2 = entity.measureEnd?.y ?? 0;
7136
+ const r1 = Math.hypot(x1 - cx, y1 - cy);
7137
+ const r2 = Math.hypot(x2 - cx, y2 - cy);
7138
+ const chord = Math.hypot(x2 - x1, y2 - y1);
7139
+ return Math.max(r1, r2, chord);
7140
+ };
7141
+ var computeLinearDistance = (x1, y1, x2, y2) => Math.hypot(x2 - x1, y2 - y1);
7142
+ var computeAngularDegreesMinimal = (cx, cy, x1, y1, x2, y2) => {
7143
+ const a1 = Math.atan2(y1 - cy, x1 - cx);
7144
+ const a2 = Math.atan2(y2 - cy, x2 - cx);
7145
+ let delta = Math.abs(a2 - a1);
7146
+ while (delta > Math.PI * 2) delta -= Math.PI * 2;
7147
+ if (delta > Math.PI) delta = Math.PI * 2 - delta;
7148
+ return delta * 180 / Math.PI;
7149
+ };
7150
+ var computeAngularDegreesCCW = (cx, cy, x1, y1, x2, y2) => {
7151
+ const a1 = Math.atan2(y1 - cy, x1 - cx);
7152
+ const a2 = Math.atan2(y2 - cy, x2 - cx);
7153
+ let delta = a2 - a1;
7154
+ while (delta < 0) delta += Math.PI * 2;
7155
+ while (delta >= Math.PI * 2) delta -= Math.PI * 2;
7156
+ return delta * 180 / Math.PI;
7157
+ };
7158
+ var computeDimensionMeasurement = (entity) => {
7159
+ const x1 = entity.measureStart?.x ?? 0;
7160
+ const y1 = entity.measureStart?.y ?? 0;
7161
+ const x2 = entity.measureEnd?.x ?? 0;
7162
+ const y2 = entity.measureEnd?.y ?? 0;
7163
+ switch (entity.dimensionType) {
7164
+ case 0:
7165
+ case 1:
7166
+ case 6: {
7167
+ const dist = computeLinearDistance(x1, y1, x2, y2);
7168
+ return formatDimensionValue(dist);
7169
+ }
7170
+ case 3: {
7171
+ const dist = computeLinearDistance(x1, y1, x2, y2);
7172
+ if (dist > 0) return formatDimensionValue(dist);
7173
+ const radius = computeRadiusFallback(entity);
7174
+ return formatDimensionValue(radius * 2);
7175
+ }
7176
+ case 4: {
7177
+ const dist = computeLinearDistance(x1, y1, x2, y2);
7178
+ if (dist > 0) return formatDimensionValue(dist);
7179
+ const radius = computeRadiusFallback(entity);
7180
+ return formatDimensionValue(radius);
7181
+ }
7182
+ case 2: {
7183
+ const cx = entity.start?.x ?? 0;
7184
+ const cy = entity.start?.y ?? 0;
7185
+ const degrees = computeAngularDegreesMinimal(cx, cy, x1, y1, x2, y2);
7186
+ const formatted = formatDimensionValue(degrees);
7187
+ return formatted ? `${formatted}\xB0` : "";
7188
+ }
7189
+ case 5: {
7190
+ const cx = entity.angleVertex?.x ?? 0;
7191
+ const cy = entity.angleVertex?.y ?? 0;
7192
+ const degrees = computeAngularDegreesCCW(cx, cy, x1, y1, x2, y2);
7193
+ const formatted = formatDimensionValue(degrees);
7194
+ return formatted ? `${formatted}\xB0` : "";
7195
+ }
7196
+ default:
7197
+ return "";
7198
+ }
7199
+ };
7200
+ var resolveDimensionText = (entity) => {
7201
+ const raw = typeof entity.text === "string" ? entity.text : "";
7202
+ const trimmed = raw.trim();
7203
+ const measured = computeDimensionMeasurement(entity);
7204
+ if (!trimmed) return measured;
7205
+ if (trimmed.includes("<>")) {
7206
+ return trimmed.split("<>").join(measured);
7207
+ }
7208
+ return trimmed;
7209
+ };
7210
+ var expandBBoxForMarker = (bbox, x, y, size) => {
7211
+ bbox.expandByPoint({ x: x - size, y: y - size });
7212
+ bbox.expandByPoint({ x: x + size, y: y + size });
7213
+ };
7214
+ var expandBBoxForText = (bbox, x, y, height, content) => {
7215
+ const textWidth = content.length * height * 0.6;
7216
+ bbox.expandByPoint({ x: x - textWidth / 2, y: y - height });
7217
+ bbox.expandByPoint({ x: x + textWidth / 2, y: y + height });
7218
+ };
6370
7219
  function colorNumberToSVG(colorNumber) {
6371
7220
  if (colorNumber === void 0 || colorNumber < 0) {
6372
7221
  return "currentColor";
@@ -6389,38 +7238,117 @@ var dxf = (() => {
6389
7238
  extLineWeight: dimStyle?.dimLwe ?? 0.5
6390
7239
  };
6391
7240
  }
6392
- function dimensionToSVG(entity, dimStyle) {
7241
+ function dimensionToSVG(entity, dimStyle, options, viewport) {
6393
7242
  switch (entity.dimensionType) {
6394
7243
  case 0:
6395
7244
  // Rotated, horizontal, or vertical
6396
7245
  case 1:
6397
- return renderLinearDimension(entity, dimStyle);
7246
+ return renderLinearDimension(entity, dimStyle, options, viewport);
6398
7247
  case 2:
6399
- return renderAngularDimension(entity, dimStyle);
7248
+ return renderAngularDimension(entity, dimStyle, options, viewport);
7249
+ case 5:
7250
+ return renderAngular3PointDimension(entity, dimStyle, options, viewport);
6400
7251
  case 3:
6401
- return renderDiameterDimension(entity, dimStyle);
7252
+ return renderDiameterDimension(entity, dimStyle, options, viewport);
6402
7253
  case 4:
6403
- return renderRadialDimension(entity, dimStyle);
7254
+ return renderRadialDimension(entity, dimStyle, options, viewport);
6404
7255
  case 6:
6405
- return renderOrdinateDimension(entity, dimStyle);
7256
+ return renderOrdinateDimension(entity, dimStyle, options, viewport);
6406
7257
  default:
6407
7258
  return renderFallbackDimension(entity);
6408
7259
  }
6409
7260
  }
6410
- function createArrowMarker(id, size, color) {
6411
- const arrowPath = `M 0 0 L ${size} ${size / 2} L 0 ${size} z`;
6412
- return `<marker id="${id}" markerWidth="${size}" markerHeight="${size}" refX="${size}" refY="${size / 2}" orient="auto" markerUnits="strokeWidth">
7261
+ function renderAngular3PointDimension(entity, dimStyle, options, viewport) {
7262
+ const bbox = new import_vecks3.Box2();
7263
+ const elements = [];
7264
+ const markers = [];
7265
+ const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport);
7266
+ const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle);
7267
+ const vertexX = entity.angleVertex?.x ?? 0;
7268
+ const vertexY = entity.angleVertex?.y ?? 0;
7269
+ const x1 = entity.measureStart?.x ?? 0;
7270
+ const y1 = entity.measureStart?.y ?? 0;
7271
+ const x2 = entity.measureEnd?.x ?? 0;
7272
+ const y2 = entity.measureEnd?.y ?? 0;
7273
+ const startArcX = entity.start?.x ?? 0;
7274
+ const startArcY = entity.start?.y ?? 0;
7275
+ const arcPointX = entity.arcPoint?.x;
7276
+ const arcPointY = entity.arcPoint?.y;
7277
+ const arcPointRadius = Number.isFinite(arcPointX) && Number.isFinite(arcPointY) ? Math.hypot(arcPointX - vertexX, arcPointY - vertexY) : Number.NaN;
7278
+ const useArcPoint = Number.isFinite(arcPointRadius) && arcPointRadius > 1e-9;
7279
+ const arcLocationX = useArcPoint ? arcPointX : startArcX;
7280
+ const arcLocationY = useArcPoint ? arcPointY : startArcY;
7281
+ const textX = entity.textMidpoint?.x ?? arcLocationX;
7282
+ const textY = entity.textMidpoint?.y ?? arcLocationY;
7283
+ bbox.expandByPoint({ x: vertexX, y: vertexY });
7284
+ bbox.expandByPoint({ x: x1, y: y1 });
7285
+ bbox.expandByPoint({ x: x2, y: y2 });
7286
+ bbox.expandByPoint({ x: arcLocationX, y: arcLocationY });
7287
+ bbox.expandByPoint({ x: textX, y: textY });
7288
+ const a1 = Math.atan2(y1 - vertexY, x1 - vertexX);
7289
+ const a2 = Math.atan2(y2 - vertexY, x2 - vertexX);
7290
+ let radius = Math.hypot(arcLocationX - vertexX, arcLocationY - vertexY);
7291
+ if (!Number.isFinite(radius) || radius <= 1e-9) {
7292
+ radius = Math.hypot(textX - vertexX, textY - vertexY);
7293
+ }
7294
+ if (!Number.isFinite(radius) || radius <= 1e-9) {
7295
+ radius = Math.max(
7296
+ Math.hypot(x1 - vertexX, y1 - vertexY),
7297
+ Math.hypot(x2 - vertexX, y2 - vertexY)
7298
+ );
7299
+ }
7300
+ const arcStartX = vertexX + radius * Math.cos(a1);
7301
+ const arcStartY = vertexY + radius * Math.sin(a1);
7302
+ const arcEndX = vertexX + radius * Math.cos(a2);
7303
+ const arcEndY = vertexY + radius * Math.sin(a2);
7304
+ bbox.expandByPoint({ x: arcStartX, y: arcStartY });
7305
+ bbox.expandByPoint({ x: arcEndX, y: arcEndY });
7306
+ const markerId1 = `dim-angular-3p-arrow-start-${Date.now()}`;
7307
+ const markerId2 = `dim-angular-3p-arrow-end-${Date.now()}`;
7308
+ markers.push(
7309
+ createArrowMarker(markerId1, arrowSize, dimLineColor, "backward"),
7310
+ createArrowMarker(markerId2, arrowSize, dimLineColor, "forward")
7311
+ );
7312
+ elements.push(
7313
+ `<line x1="${x1}" y1="${y1}" x2="${arcStartX}" y2="${arcStartY}" stroke="${extLineColor}" stroke-width="${extLineWeight}" />`,
7314
+ `<line x1="${x2}" y1="${y2}" x2="${arcEndX}" y2="${arcEndY}" stroke="${extLineColor}" stroke-width="${extLineWeight}" />`
7315
+ );
7316
+ let delta = a2 - a1;
7317
+ while (delta < 0) delta += Math.PI * 2;
7318
+ while (delta >= Math.PI * 2) delta -= Math.PI * 2;
7319
+ const largeArcFlag = delta > Math.PI ? 1 : 0;
7320
+ const sweepFlag = 1;
7321
+ expandBBoxForMarker(bbox, arcStartX, arcStartY, arrowSize);
7322
+ expandBBoxForMarker(bbox, arcEndX, arcEndY, arrowSize);
7323
+ elements.push(
7324
+ `<path d="M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${arcEndX} ${arcEndY}" fill="none" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-start="url(#${markerId1})" marker-end="url(#${markerId2})" />`
7325
+ );
7326
+ const resolvedText = resolveDimensionText(entity);
7327
+ if (resolvedText) {
7328
+ const midAngle = a1 + delta / 2;
7329
+ const textRotation = midAngle * 180 / Math.PI;
7330
+ expandBBoxForText(bbox, textX, textY, textHeight, resolvedText);
7331
+ elements.push(
7332
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(resolvedText)}</text>`
7333
+ );
7334
+ }
7335
+ return {
7336
+ bbox,
7337
+ element: `<defs>${markers.join("")}</defs><g>${elements.join("")}</g>`
7338
+ };
7339
+ }
7340
+ function createArrowMarker(id, size, color, direction = "forward") {
7341
+ const arrowPath = direction === "forward" ? `M 0 0 L ${size} ${size / 2} L 0 ${size} z` : `M ${size} 0 L 0 ${size / 2} L ${size} ${size} z`;
7342
+ const refX = direction === "forward" ? size : 0;
7343
+ return `<marker id="${id}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${size / 2}" orient="auto" markerUnits="userSpaceOnUse">
6413
7344
  <path d="${arrowPath}" fill="${color}" />
6414
7345
  </marker>`;
6415
7346
  }
6416
- function renderLinearDimension(entity, dimStyle) {
7347
+ function renderLinearDimension(entity, dimStyle, options, viewport) {
6417
7348
  const bbox = new import_vecks3.Box2();
6418
7349
  const elements = [];
6419
7350
  const markers = [];
6420
- const arrowSize = dimStyle?.dimAsz ?? 2.5;
6421
- const textHeight = dimStyle?.dimTxt ?? 2.5;
6422
- const extLineOffset = dimStyle?.dimExo ?? 0.625;
6423
- const extLineExtension = dimStyle?.dimExe ?? 1.25;
7351
+ const { arrowSize, textHeight, extLineOffset, extLineExtension } = getScaledDimensionSizes(dimStyle, options, viewport);
6424
7352
  const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle);
6425
7353
  const defPoint1X = entity.measureStart?.x ?? 0;
6426
7354
  const defPoint1Y = entity.measureStart?.y ?? 0;
@@ -6443,8 +7371,8 @@ var dxf = (() => {
6443
7371
  const markerId1 = `dim-arrow-start-${Date.now()}`;
6444
7372
  const markerId2 = `dim-arrow-end-${Date.now()}`;
6445
7373
  markers.push(
6446
- createArrowMarker(markerId1, arrowSize, dimLineColor),
6447
- createArrowMarker(markerId2, arrowSize, dimLineColor)
7374
+ createArrowMarker(markerId1, arrowSize, dimLineColor, "backward"),
7375
+ createArrowMarker(markerId2, arrowSize, dimLineColor, "forward")
6448
7376
  );
6449
7377
  const extLine1StartX = defPoint1X + Math.cos(perpAngle) * extLineOffset;
6450
7378
  const extLine1StartY = defPoint1Y + Math.sin(perpAngle) * extLineOffset;
@@ -6454,15 +7382,23 @@ var dxf = (() => {
6454
7382
  const extLine2StartY = defPoint2Y + Math.sin(perpAngle) * extLineOffset;
6455
7383
  const extLine2EndX = dimLine2X + Math.cos(perpAngle) * extLineExtension;
6456
7384
  const extLine2EndY = dimLine2Y + Math.sin(perpAngle) * extLineExtension;
7385
+ bbox.expandByPoint({ x: extLine1StartX, y: extLine1StartY });
7386
+ bbox.expandByPoint({ x: extLine1EndX, y: extLine1EndY });
7387
+ bbox.expandByPoint({ x: extLine2StartX, y: extLine2StartY });
7388
+ bbox.expandByPoint({ x: extLine2EndX, y: extLine2EndY });
7389
+ expandBBoxForMarker(bbox, dimLine1X, dimLine1Y, arrowSize);
7390
+ expandBBoxForMarker(bbox, dimLine2X, dimLine2Y, arrowSize);
6457
7391
  elements.push(
6458
7392
  `<line x1="${extLine1StartX}" y1="${extLine1StartY}" x2="${extLine1EndX}" y2="${extLine1EndY}" stroke="${extLineColor}" stroke-width="${extLineWeight}" />`,
6459
7393
  `<line x1="${extLine2StartX}" y1="${extLine2StartY}" x2="${extLine2EndX}" y2="${extLine2EndY}" stroke="${extLineColor}" stroke-width="${extLineWeight}" />`,
6460
7394
  `<line x1="${dimLine1X}" y1="${dimLine1Y}" x2="${dimLine2X}" y2="${dimLine2Y}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-start="url(#${markerId1})" marker-end="url(#${markerId2})" />`
6461
7395
  );
6462
- if (entity.text) {
7396
+ const resolvedText = resolveDimensionText(entity);
7397
+ if (resolvedText) {
6463
7398
  const textRotation = angle * 180 / Math.PI;
7399
+ expandBBoxForText(bbox, textX, textY, textHeight, resolvedText);
6464
7400
  elements.push(
6465
- `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${entity.text}</text>`
7401
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(resolvedText)}</text>`
6466
7402
  );
6467
7403
  }
6468
7404
  return {
@@ -6470,12 +7406,11 @@ var dxf = (() => {
6470
7406
  element: `<defs>${markers.join("")}</defs><g>${elements.join("")}</g>`
6471
7407
  };
6472
7408
  }
6473
- function renderAngularDimension(entity, dimStyle) {
7409
+ function renderAngularDimension(entity, dimStyle, options, viewport) {
6474
7410
  const bbox = new import_vecks3.Box2();
6475
7411
  const elements = [];
6476
7412
  const markers = [];
6477
- const arrowSize = dimStyle?.dimAsz ?? 2.5;
6478
- const textHeight = dimStyle?.dimTxt ?? 2.5;
7413
+ const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport);
6479
7414
  const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle);
6480
7415
  const centerX = entity.start?.x ?? 0;
6481
7416
  const centerY = entity.start?.y ?? 0;
@@ -6492,8 +7427,8 @@ var dxf = (() => {
6492
7427
  const markerId1 = `dim-angular-arrow-start-${Date.now()}`;
6493
7428
  const markerId2 = `dim-angular-arrow-end-${Date.now()}`;
6494
7429
  markers.push(
6495
- createArrowMarker(markerId1, arrowSize, dimLineColor),
6496
- createArrowMarker(markerId2, arrowSize, dimLineColor)
7430
+ createArrowMarker(markerId1, arrowSize, dimLineColor, "backward"),
7431
+ createArrowMarker(markerId2, arrowSize, dimLineColor, "forward")
6497
7432
  );
6498
7433
  elements.push(
6499
7434
  `<line x1="${centerX}" y1="${centerY}" x2="${x1}" y2="${y1}" stroke="${extLineColor}" stroke-width="${extLineWeight}" />`,
@@ -6510,11 +7445,13 @@ var dxf = (() => {
6510
7445
  elements.push(
6511
7446
  `<path d="M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${arcEndX} ${arcEndY}" fill="none" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-start="url(#${markerId1})" marker-end="url(#${markerId2})" />`
6512
7447
  );
6513
- if (entity.text) {
7448
+ const resolvedText = resolveDimensionText(entity);
7449
+ if (resolvedText) {
6514
7450
  const midAngle = (startAngle + endAngle) / 2;
6515
7451
  const textRotation = midAngle * 180 / Math.PI;
7452
+ expandBBoxForText(bbox, textX, textY, textHeight, resolvedText);
6516
7453
  elements.push(
6517
- `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${entity.text}</text>`
7454
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(resolvedText)}</text>`
6518
7455
  );
6519
7456
  }
6520
7457
  return {
@@ -6522,12 +7459,11 @@ var dxf = (() => {
6522
7459
  element: `<defs>${markers.join("")}</defs><g>${elements.join("")}</g>`
6523
7460
  };
6524
7461
  }
6525
- function renderDiameterDimension(entity, dimStyle) {
7462
+ function renderDiameterDimension(entity, dimStyle, options, viewport) {
6526
7463
  const bbox = new import_vecks3.Box2();
6527
7464
  const elements = [];
6528
7465
  const markers = [];
6529
- const arrowSize = dimStyle?.dimAsz ?? 2.5;
6530
- const textHeight = dimStyle?.dimTxt ?? 2.5;
7466
+ const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport);
6531
7467
  const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle);
6532
7468
  const x1 = entity.measureStart?.x ?? 0;
6533
7469
  const y1 = entity.measureStart?.y ?? 0;
@@ -6538,28 +7474,33 @@ var dxf = (() => {
6538
7474
  bbox.expandByPoint({ x: x1, y: y1 });
6539
7475
  bbox.expandByPoint({ x: x2, y: y2 });
6540
7476
  bbox.expandByPoint({ x: textX, y: textY });
6541
- const markerId = `dim-diameter-arrow-${Date.now()}`;
6542
- markers.push(createArrowMarker(markerId, arrowSize, dimLineColor));
6543
- elements.push(
6544
- `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-end="url(#${markerId})" />`
6545
- );
6546
- const diameterText = entity.text ? `\u2300${entity.text}` : "\u2300";
7477
+ const diameterLen = Math.hypot(x2 - x1, y2 - y1);
7478
+ if (Number.isFinite(diameterLen) && diameterLen > 1e-6) {
7479
+ const markerId = `dim-diameter-arrow-${Date.now()}`;
7480
+ markers.push(createArrowMarker(markerId, arrowSize, dimLineColor, "backward"));
7481
+ elements.push(
7482
+ `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-end="url(#${markerId})" />`
7483
+ );
7484
+ expandBBoxForMarker(bbox, x2, y2, arrowSize);
7485
+ }
7486
+ const resolvedText = resolveDimensionText(entity);
7487
+ const diameterText = resolvedText ? `\u2300${resolvedText}` : "\u2300";
6547
7488
  const angle = Math.atan2(y2 - y1, x2 - x1);
6548
7489
  const textRotation = angle * 180 / Math.PI;
7490
+ expandBBoxForText(bbox, textX, textY, textHeight, diameterText);
6549
7491
  elements.push(
6550
- `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${diameterText}</text>`
7492
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(diameterText)}</text>`
6551
7493
  );
6552
7494
  return {
6553
7495
  bbox,
6554
7496
  element: `<defs>${markers.join("")}</defs><g>${elements.join("")}</g>`
6555
7497
  };
6556
7498
  }
6557
- function renderRadialDimension(entity, dimStyle) {
7499
+ function renderRadialDimension(entity, dimStyle, options, viewport) {
6558
7500
  const bbox = new import_vecks3.Box2();
6559
7501
  const elements = [];
6560
7502
  const markers = [];
6561
- const arrowSize = dimStyle?.dimAsz ?? 2.5;
6562
- const textHeight = dimStyle?.dimTxt ?? 2.5;
7503
+ const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport);
6563
7504
  const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle);
6564
7505
  const x1 = entity.measureStart?.x ?? 0;
6565
7506
  const y1 = entity.measureStart?.y ?? 0;
@@ -6570,26 +7511,32 @@ var dxf = (() => {
6570
7511
  bbox.expandByPoint({ x: x1, y: y1 });
6571
7512
  bbox.expandByPoint({ x: x2, y: y2 });
6572
7513
  bbox.expandByPoint({ x: textX, y: textY });
6573
- const markerId = `dim-radius-arrow-${Date.now()}`;
6574
- markers.push(createArrowMarker(markerId, arrowSize, dimLineColor));
6575
- elements.push(
6576
- `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-end="url(#${markerId})" />`
6577
- );
6578
- const radiusText = entity.text ? `R${entity.text}` : "R";
7514
+ const radiusLen = Math.hypot(x2 - x1, y2 - y1);
7515
+ if (Number.isFinite(radiusLen) && radiusLen > 1e-6) {
7516
+ const markerId = `dim-radius-arrow-${Date.now()}`;
7517
+ markers.push(createArrowMarker(markerId, arrowSize, dimLineColor, "backward"));
7518
+ elements.push(
7519
+ `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" marker-end="url(#${markerId})" />`
7520
+ );
7521
+ expandBBoxForMarker(bbox, x2, y2, arrowSize);
7522
+ }
7523
+ const resolvedText = resolveDimensionText(entity);
7524
+ const radiusText = resolvedText ? `R${resolvedText}` : "R";
6579
7525
  const angle = Math.atan2(y2 - y1, x2 - x1);
6580
7526
  const textRotation = angle * 180 / Math.PI;
7527
+ expandBBoxForText(bbox, textX, textY, textHeight, radiusText);
6581
7528
  elements.push(
6582
- `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${radiusText}</text>`
7529
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(radiusText)}</text>`
6583
7530
  );
6584
7531
  return {
6585
7532
  bbox,
6586
7533
  element: `<defs>${markers.join("")}</defs><g>${elements.join("")}</g>`
6587
7534
  };
6588
7535
  }
6589
- function renderOrdinateDimension(entity, dimStyle) {
7536
+ function renderOrdinateDimension(entity, dimStyle, options, viewport) {
6590
7537
  const bbox = new import_vecks3.Box2();
6591
7538
  const elements = [];
6592
- const textHeight = dimStyle?.dimTxt ?? 2.5;
7539
+ const { textHeight } = getScaledDimensionSizes(dimStyle, options, viewport);
6593
7540
  const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle);
6594
7541
  const x1 = entity.measureStart?.x ?? 0;
6595
7542
  const y1 = entity.measureStart?.y ?? 0;
@@ -6603,11 +7550,13 @@ var dxf = (() => {
6603
7550
  elements.push(
6604
7551
  `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${dimLineColor}" stroke-width="${dimLineWeight}" />`
6605
7552
  );
6606
- if (entity.text) {
7553
+ const resolvedText = resolveDimensionText(entity);
7554
+ if (resolvedText) {
6607
7555
  const angle = Math.atan2(y2 - y1, x2 - x1);
6608
7556
  const textRotation = angle * 180 / Math.PI;
7557
+ expandBBoxForText(bbox, textX, textY, textHeight, resolvedText);
6609
7558
  elements.push(
6610
- `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${entity.text}</text>`
7559
+ `<text x="${textX}" y="${textY}" font-size="${textHeight}" fill="${textColor}" text-anchor="middle" transform="rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(resolvedText)}</text>`
6611
7560
  );
6612
7561
  }
6613
7562
  return {
@@ -6622,9 +7571,10 @@ var dxf = (() => {
6622
7571
  const textX = entity.textMidpoint.x ?? 0;
6623
7572
  const textY = entity.textMidpoint.y ?? 0;
6624
7573
  bbox.expandByPoint({ x: textX, y: textY });
6625
- if (entity.text) {
7574
+ const resolvedText = resolveDimensionText(entity);
7575
+ if (resolvedText) {
6626
7576
  elements.push(
6627
- `<text x="${textX}" y="${textY}" font-size="2.5" text-anchor="middle" transform="scale(1,-1) translate(0 ${-2 * textY})">${entity.text}</text>`
7577
+ `<text x="${textX}" y="${textY}" font-size="2.5" text-anchor="middle" transform="scale(1,-1) translate(0 ${-2 * textY})">${escapeXmlText(resolvedText)}</text>`
6628
7578
  );
6629
7579
  }
6630
7580
  }
@@ -6884,6 +7834,23 @@ var dxf = (() => {
6884
7834
  entity.transforms ?? []
6885
7835
  );
6886
7836
  };
7837
+ var leader = (entity) => {
7838
+ if (!entity.vertices || entity.vertices.length < 2) return null;
7839
+ const bbox0 = entity.vertices.reduce(
7840
+ (acc, p) => acc.expandByPoint({ x: p.x, y: p.y }),
7841
+ new import_vecks5.Box2()
7842
+ );
7843
+ const d = entity.vertices.reduce((acc, p, i) => {
7844
+ acc += i === 0 ? "M" : "L";
7845
+ acc += p.x + "," + p.y;
7846
+ return acc;
7847
+ }, "");
7848
+ return transformBoundingBoxAndElement(
7849
+ bbox0,
7850
+ `<path d="${d}" />`,
7851
+ entity.transforms ?? []
7852
+ );
7853
+ };
6887
7854
  var circle = (entity) => {
6888
7855
  const bbox0 = new import_vecks5.Box2().expandByPoint({
6889
7856
  x: entity.x + entity.r,
@@ -7023,7 +7990,7 @@ var dxf = (() => {
7023
7990
  const textWidth = content.length * height * 0.6;
7024
7991
  const bbox0 = new import_vecks5.Box2().expandByPoint({ x, y }).expandByPoint({ x: x + textWidth, y: y + height });
7025
7992
  const rotationDegrees = rotation * 180 / Math.PI;
7026
- const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`;
7993
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`;
7027
7994
  const { bbox, element } = addFlipXIfApplicable(entity, {
7028
7995
  bbox: bbox0,
7029
7996
  element: element0
@@ -7039,15 +8006,31 @@ var dxf = (() => {
7039
8006
  const bbox0 = new import_vecks5.Box2().expandByPoint({ x, y }).expandByPoint({ x: x + textWidth, y: y + height });
7040
8007
  const rotation = entity.xAxisX !== void 0 && entity.xAxisY !== void 0 ? Math.atan2(entity.xAxisY, entity.xAxisX) : 0;
7041
8008
  const rotationDegrees = rotation * 180 / Math.PI;
7042
- const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`;
8009
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`;
8010
+ const { bbox, element } = addFlipXIfApplicable(entity, {
8011
+ bbox: bbox0,
8012
+ element: element0
8013
+ });
8014
+ return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? []);
8015
+ };
8016
+ var tolerance = (entity) => {
8017
+ const x = entity.insertionPoint?.x ?? 0;
8018
+ const y = entity.insertionPoint?.y ?? 0;
8019
+ const height = 1;
8020
+ const content = entity.text ?? "";
8021
+ const rotation = entity.xAxisDirection ? Math.atan2(entity.xAxisDirection.y, entity.xAxisDirection.x) : 0;
8022
+ const rotationDegrees = rotation * 180 / Math.PI;
8023
+ const textWidth = content.length * height * 0.6;
8024
+ const bbox0 = new import_vecks5.Box2().expandByPoint({ x, y }).expandByPoint({ x: x + textWidth, y: y + height });
8025
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`;
7043
8026
  const { bbox, element } = addFlipXIfApplicable(entity, {
7044
8027
  bbox: bbox0,
7045
8028
  element: element0
7046
8029
  });
7047
8030
  return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? []);
7048
8031
  };
7049
- var dimension = (entity, dimStyle) => {
7050
- const result = dimensionToSVG(entity, dimStyle);
8032
+ var dimension = (entity, dimStyle, options, viewport) => {
8033
+ const result = dimensionToSVG(entity, dimStyle, options, viewport);
7051
8034
  return transformBoundingBoxAndElement(
7052
8035
  result.bbox,
7053
8036
  result.element,
@@ -7086,7 +8069,7 @@ var dxf = (() => {
7086
8069
  const element = `<g>${paths.join("")}</g>`;
7087
8070
  return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? []);
7088
8071
  };
7089
- var entityToBoundsAndElement = (entity, dimStyles) => {
8072
+ var entityToBoundsAndElement = (entity, dimStyles, options, viewport) => {
7090
8073
  switch (entity.type) {
7091
8074
  case "CIRCLE":
7092
8075
  return circle(entity);
@@ -7102,7 +8085,7 @@ var dxf = (() => {
7102
8085
  const dimEntity = entity;
7103
8086
  const styleName = typeof dimEntity.styleName === "string" ? dimEntity.styleName : void 0;
7104
8087
  const dimStyle = styleName && dimStyles ? dimStyles[styleName] : void 0;
7105
- return dimension(dimEntity, dimStyle);
8088
+ return dimension(dimEntity, dimStyle, options, viewport);
7106
8089
  }
7107
8090
  case "SPLINE": {
7108
8091
  const splineEntity = entity;
@@ -7126,18 +8109,47 @@ var dxf = (() => {
7126
8109
  case "LWPOLYLINE": {
7127
8110
  return lwpolyline(entity);
7128
8111
  }
8112
+ case "LEADER": {
8113
+ return leader(entity);
8114
+ }
8115
+ case "TOLERANCE": {
8116
+ return tolerance(entity);
8117
+ }
7129
8118
  default:
7130
8119
  logger_default.warn("entity type not supported in SVG rendering:", entity.type);
7131
8120
  return null;
7132
8121
  }
7133
8122
  };
7134
- function toSVG(parsed) {
8123
+ function toSVG(parsed, options = {}) {
7135
8124
  const entities = denormalise(parsed);
7136
8125
  const dimStyles = parsed.tables.dimStyles;
8126
+ const geometryBBox = entities.reduce((acc, entity) => {
8127
+ if (entity.type === "DIMENSION") {
8128
+ const bbox2 = getDimensionGeometryBBox(entity);
8129
+ if (bbox2.valid) {
8130
+ acc.expandByPoint(bbox2.min);
8131
+ acc.expandByPoint(bbox2.max);
8132
+ }
8133
+ return acc;
8134
+ }
8135
+ const boundsAndElement = entityToBoundsAndElement(entity, dimStyles, options);
8136
+ if (boundsAndElement?.bbox.valid) {
8137
+ acc.expandByPoint(boundsAndElement.bbox.min);
8138
+ acc.expandByPoint(boundsAndElement.bbox.max);
8139
+ }
8140
+ return acc;
8141
+ }, new import_vecks5.Box2());
8142
+ const viewport = geometryBBox.valid ? {
8143
+ width: geometryBBox.max.x - geometryBBox.min.x,
8144
+ height: geometryBBox.max.y - geometryBBox.min.y
8145
+ } : {
8146
+ width: 0,
8147
+ height: 0
8148
+ };
7137
8149
  const { bbox, elements } = entities.reduce(
7138
8150
  (acc, entity) => {
7139
8151
  const rgb = getRGBForEntity(parsed.tables.layers, entity);
7140
- const boundsAndElement = entityToBoundsAndElement(entity, dimStyles);
8152
+ const boundsAndElement = entityToBoundsAndElement(entity, dimStyles, options, viewport);
7141
8153
  if (boundsAndElement) {
7142
8154
  const { bbox: bbox2, element } = boundsAndElement;
7143
8155
  if (bbox2.valid) {
@@ -7223,8 +8235,8 @@ var dxf = (() => {
7223
8235
  }
7224
8236
  return this._groups;
7225
8237
  }
7226
- toSVG() {
7227
- return toSVG(this.parsed);
8238
+ toSVG(options) {
8239
+ return toSVG(this.parsed, options);
7228
8240
  }
7229
8241
  toPolylines() {
7230
8242
  return toPolylines(this.parsed);