@mlightcad/data-model 1.15.17 → 1.15.19

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 (38) hide show
  1. package/dist/data-model.cjs +16 -16
  2. package/lib/base/AcDbObject.d.ts +46 -0
  3. package/lib/base/AcDbObject.d.ts.map +1 -1
  4. package/lib/base/AcDbObject.js +76 -1
  5. package/lib/base/AcDbObject.js.map +1 -1
  6. package/lib/dxf/AcDbDxfDocumentReader.d.ts +11 -2
  7. package/lib/dxf/AcDbDxfDocumentReader.d.ts.map +1 -1
  8. package/lib/dxf/AcDbDxfDocumentReader.js +21 -5
  9. package/lib/dxf/AcDbDxfDocumentReader.js.map +1 -1
  10. package/lib/entity/AcDbFcf.d.ts +24 -0
  11. package/lib/entity/AcDbFcf.d.ts.map +1 -1
  12. package/lib/entity/AcDbFcf.js +39 -1
  13. package/lib/entity/AcDbFcf.js.map +1 -1
  14. package/lib/entity/AcDbLeader.d.ts +161 -7
  15. package/lib/entity/AcDbLeader.d.ts.map +1 -1
  16. package/lib/entity/AcDbLeader.js +486 -35
  17. package/lib/entity/AcDbLeader.js.map +1 -1
  18. package/lib/entity/dimension/AcDbDimension.d.ts +25 -3
  19. package/lib/entity/dimension/AcDbDimension.d.ts.map +1 -1
  20. package/lib/entity/dimension/AcDbDimension.js +42 -5
  21. package/lib/entity/dimension/AcDbDimension.js.map +1 -1
  22. package/lib/index.d.ts +2 -1
  23. package/lib/index.d.ts.map +1 -1
  24. package/lib/index.js +1 -0
  25. package/lib/index.js.map +1 -1
  26. package/lib/misc/AcDbDataGenerator.d.ts +7 -0
  27. package/lib/misc/AcDbDataGenerator.d.ts.map +1 -1
  28. package/lib/misc/AcDbDataGenerator.js +28 -18
  29. package/lib/misc/AcDbDataGenerator.js.map +1 -1
  30. package/lib/misc/AcDbDimStyleOverrides.d.ts +104 -0
  31. package/lib/misc/AcDbDimStyleOverrides.d.ts.map +1 -0
  32. package/lib/misc/AcDbDimStyleOverrides.js +509 -0
  33. package/lib/misc/AcDbDimStyleOverrides.js.map +1 -0
  34. package/lib/misc/index.d.ts +2 -0
  35. package/lib/misc/index.d.ts.map +1 -1
  36. package/lib/misc/index.js +1 -0
  37. package/lib/misc/index.js.map +1 -1
  38. package/package.json +5 -5
@@ -49,10 +49,14 @@ var __values = (this && this.__values) || function(o) {
49
49
  };
50
50
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
51
51
  };
52
- import { AcGeBox3d, AcGePoint2d, AcGePoint3d, AcGeSpline3d, AcGeVector3d } from '@mlightcad/geometry-engine';
53
- import { AcDbBlockTableRecord, AcDbDimStyleTableRecord, AcDbDimTextVertical } from '../database/index.js';
52
+ import { AcCmColor } from '@mlightcad/common';
53
+ import { AcGeArea2d, AcGeBox3d, AcGeMatrix3d, AcGePoint2d, AcGePoint3d, AcGePolyline2d, AcGeSpline3d, AcGeVector3d } from '@mlightcad/geometry-engine';
54
+ import { AcDbBlockTableRecord, AcDbDimStyleTableRecord } from '../database/index.js';
55
+ import { ACDB_DSTYLE_XDATA_APP, acdbResolveEffectiveDimStyle } from '../misc/AcDbDimStyleOverrides.js';
54
56
  import { acdbDrawTessellateOptions } from '../misc/AcDbDrawTessellate.js';
57
+ import { acdbDecodeDimStyleColor } from '../misc/AcDbMLeaderStyleColorCodec.js';
55
58
  import { AcDbOsnapMode } from '../misc/AcDbOsnapMode.js';
59
+ import { AcDbRenderingCache } from '../misc/AcDbRenderingCache.js';
56
60
  import { AcDbCurve } from './AcDbCurve.js';
57
61
  import { acdbMovePointArrayGripAt } from './AcDbGripHelpers.js';
58
62
  import { acdbIntersectPrimitivesFromPointPath } from './AcDbIntersectHelpers.js';
@@ -60,6 +64,8 @@ import { AcDbMText } from './AcDbMText.js';
60
64
  import { acdbCollectLineSegmentOsnapPoints, acdbPickNearestOsnapPoint } from './AcDbOsnapHelpers.js';
61
65
  import { acdbOffsetVertexPathAsPolyline, AcDbPolyline } from './AcDbPolyline.js';
62
66
  import { acdbCollectMTextOrientedCorners, acdbEstimatePlainTextWidth, acdbResolveMTextLayoutMetrics, acdbScorePointAgainstMTextLayout, acdbStripMTextControlCodes } from './AcDbTextExtentsHelpers.js';
67
+ import { acdbEnsureDimArrowBlocks, acdbResolveArrowBlockName, CLOSED_FILLED_ARROW_BLOCK } from './dimension/AcDbDimBlockBuilder.js';
68
+ import { acdbDimFeatureScale } from './dimension/AcDbDimFeatureScale.js';
63
69
  /**
64
70
  * Defines the annotation type for leader entities.
65
71
  */
@@ -297,6 +303,8 @@ var AcDbLeader = /** @class */ (function (_super) {
297
303
  */
298
304
  set: function (value) {
299
305
  this._dimensionStyle = value;
306
+ this._dimStyle = undefined;
307
+ this._dimStyleName = undefined;
300
308
  },
301
309
  enumerable: false,
302
310
  configurable: true
@@ -414,6 +422,162 @@ var AcDbLeader = /** @class */ (function (_super) {
414
422
  enumerable: false,
415
423
  configurable: true
416
424
  });
425
+ Object.defineProperty(AcDbLeader.prototype, "properties", {
426
+ /**
427
+ * Returns the runtime property definition of this leader so the property
428
+ * palette can show and edit it like other entities.
429
+ *
430
+ * The palette resolves each `name` through the `entity.property` locale
431
+ * namespace and each enum `label` through `entity.enum`, so the names used
432
+ * here are the ones translated by the viewer.
433
+ */
434
+ get: function () {
435
+ var _this = this;
436
+ return {
437
+ type: this.type,
438
+ groups: [
439
+ this.getGeneralProperties(),
440
+ {
441
+ groupName: 'leader',
442
+ properties: [
443
+ this.createProperty('dimensionStyleName', 'string', function () { return _this.dimensionStyle; }, function (value) {
444
+ _this.dimensionStyle = value;
445
+ }),
446
+ this.createProperty('annoType', 'enum', function () { return _this.annoType; }, function (value) {
447
+ _this.annoType = value;
448
+ }, [
449
+ {
450
+ label: AcDbLeaderAnnotationType[AcDbLeaderAnnotationType.MText],
451
+ value: AcDbLeaderAnnotationType.MText
452
+ },
453
+ {
454
+ label: AcDbLeaderAnnotationType[AcDbLeaderAnnotationType.Fcf],
455
+ value: AcDbLeaderAnnotationType.Fcf
456
+ },
457
+ {
458
+ label: AcDbLeaderAnnotationType[AcDbLeaderAnnotationType.BlockReference],
459
+ value: AcDbLeaderAnnotationType.BlockReference
460
+ },
461
+ {
462
+ label: AcDbLeaderAnnotationType[AcDbLeaderAnnotationType.NoAnnotation],
463
+ value: AcDbLeaderAnnotationType.NoAnnotation
464
+ }
465
+ ]),
466
+ this.createProperty('hasArrowHead', 'boolean', function () { return _this.hasArrowHead; }, function (value) {
467
+ _this.hasArrowHead = value;
468
+ }),
469
+ this.createProperty('hasHookLine', 'boolean', function () { return _this.hasHookLine; }, function (value) {
470
+ _this.hasHookLine = value;
471
+ }),
472
+ this.createProperty('isHookLineSameDirection', 'boolean', function () { return _this.isHookLineSameDirection; }, function (value) {
473
+ _this.isHookLineSameDirection = value;
474
+ }),
475
+ this.createProperty('isSplined', 'boolean', function () { return _this.isSplined; }, function (value) {
476
+ _this.isSplined = value;
477
+ }),
478
+ this.createProperty('associatedAnnotation', 'string', function () { return _this._associatedAnnotation; }),
479
+ this.createProperty('byBlockColor', 'int', function () { return _this._byBlockColor; })
480
+ ]
481
+ },
482
+ {
483
+ groupName: 'text',
484
+ properties: [
485
+ this.createProperty('textHeight', 'float', function () { return _this.textHeight; }, function (value) {
486
+ _this.textHeight = value;
487
+ }),
488
+ this.createProperty('textWidth', 'float', function () { return _this.textWidth; }, function (value) {
489
+ _this.textWidth = value;
490
+ })
491
+ ]
492
+ },
493
+ {
494
+ groupName: 'geometry',
495
+ properties: __spreadArray(__spreadArray(__spreadArray(__spreadArray([
496
+ {
497
+ name: 'vertices',
498
+ type: 'array',
499
+ editable: false,
500
+ itemSchema: {
501
+ properties: [
502
+ { name: 'x', type: 'float', editable: false },
503
+ { name: 'y', type: 'float', editable: false },
504
+ { name: 'z', type: 'float', editable: false }
505
+ ]
506
+ },
507
+ accessor: {
508
+ get: function () {
509
+ return _this.vertices.map(function (vertex) { return ({
510
+ x: vertex.x,
511
+ y: vertex.y,
512
+ z: vertex.z
513
+ }); });
514
+ }
515
+ }
516
+ }
517
+ ], __read(this.createPoint3dProperties('normal', function () { return _this._normal; })), false), __read(this.createPoint3dProperties('horizontalDirection', function () { return _this._horizontalDirection; })), false), __read(this.createOptionalPoint3dProperties('offsetFromBlock', function () { return _this.offsetFromBlock; }, function (value) {
518
+ _this.offsetFromBlock = value;
519
+ })), false), __read(this.createOptionalPoint3dProperties('offsetFromAnnotation', function () { return _this.offsetFromAnnotation; }, function (value) {
520
+ _this.offsetFromAnnotation = value;
521
+ })), false)
522
+ }
523
+ ]
524
+ };
525
+ },
526
+ enumerable: false,
527
+ configurable: true
528
+ });
529
+ /**
530
+ * Builds one runtime property, marking it editable only when a setter exists.
531
+ */
532
+ AcDbLeader.prototype.createProperty = function (name, type, get, set, options) {
533
+ return {
534
+ name: name,
535
+ type: type,
536
+ editable: set != null,
537
+ options: options,
538
+ accessor: set ? { get: get, set: set } : { get: get }
539
+ };
540
+ };
541
+ /**
542
+ * Builds the X/Y/Z properties of a required vector.
543
+ */
544
+ AcDbLeader.prototype.createPoint3dProperties = function (prefix, getVector) {
545
+ return [
546
+ this.createProperty("".concat(prefix, "X"), 'float', function () { return getVector().x; }, function (value) {
547
+ getVector().x = value;
548
+ }),
549
+ this.createProperty("".concat(prefix, "Y"), 'float', function () { return getVector().y; }, function (value) {
550
+ getVector().y = value;
551
+ }),
552
+ this.createProperty("".concat(prefix, "Z"), 'float', function () { return getVector().z; }, function (value) {
553
+ getVector().z = value;
554
+ })
555
+ ];
556
+ };
557
+ /**
558
+ * Builds the X/Y/Z properties of a vector that may not be present yet.
559
+ *
560
+ * Reading an absent vector returns `undefined` so the palette shows an empty
561
+ * cell; writing any component materializes the vector with the other
562
+ * components defaulting to `0`.
563
+ */
564
+ AcDbLeader.prototype.createOptionalPoint3dProperties = function (prefix, getVector, setVector) {
565
+ var _this = this;
566
+ var createAxis = function (axis) {
567
+ return _this.createProperty("".concat(prefix).concat(axis.toUpperCase()), 'float', function () { var _a; return (_a = getVector()) === null || _a === void 0 ? void 0 : _a[axis]; }, function (value) {
568
+ var _a, _b, _c;
569
+ if (value == null)
570
+ return;
571
+ var vector = getVector();
572
+ setVector({
573
+ x: axis === 'x' ? value : ((_a = vector === null || vector === void 0 ? void 0 : vector.x) !== null && _a !== void 0 ? _a : 0),
574
+ y: axis === 'y' ? value : ((_b = vector === null || vector === void 0 ? void 0 : vector.y) !== null && _b !== void 0 ? _b : 0),
575
+ z: axis === 'z' ? value : ((_c = vector === null || vector === void 0 ? void 0 : vector.z) !== null && _c !== void 0 ? _c : 0)
576
+ });
577
+ });
578
+ };
579
+ return [createAxis('x'), createAxis('y'), createAxis('z')];
580
+ };
417
581
  /**
418
582
  * Appends vertex to the end of the vertex list for this leader. If vertex is not in the plane of the
419
583
  * leader, then it will be projected parallel the leader's normal onto the leader's plane and the
@@ -583,11 +747,20 @@ var AcDbLeader = /** @class */ (function (_super) {
583
747
  };
584
748
  Object.defineProperty(AcDbLeader.prototype, "directBatchPrimitive", {
585
749
  /**
586
- * This leader always draws as a single `lineStrip` primitive.
750
+ * This leader draws as a single `lineStrip` primitive unless drawing it
751
+ * needs more than the entity color already applied by `worldDraw`.
752
+ *
753
+ * An arrowhead (DXF 71) adds a second primitive. A DIMCLRD or group 77 color
754
+ * that differs from the entity color is applied inside `subWorldDraw`, and a
755
+ * geometry-only batch would keep the entity color instead. Either case falls
756
+ * back to the legacy draw path. The style lookup is memoized on the leader.
587
757
  *
588
758
  * @internal
589
759
  */
590
760
  get: function () {
761
+ var mayDrawArrowHead = this._hasArrowHead && this._vertices.length >= 2;
762
+ if (mayDrawArrowHead || this.leaderLineColorDiffersFromEntity())
763
+ return null;
591
764
  return 'lineStrip';
592
765
  },
593
766
  enumerable: false,
@@ -597,7 +770,238 @@ var AcDbLeader = /** @class */ (function (_super) {
597
770
  * @inheritdoc
598
771
  */
599
772
  AcDbLeader.prototype.subWorldDraw = function (renderer) {
600
- return renderer.lines(this.collectDrawPoints(renderer));
773
+ var _this = this;
774
+ var entities = [];
775
+ var points = this.collectDrawPoints(renderer);
776
+ var leaderColor = this.resolveLeaderLineColor();
777
+ var traits = renderer.subEntityTraits;
778
+ var drawGeometry = function () {
779
+ if (points.length > 0) {
780
+ entities.push(renderer.lines(points));
781
+ }
782
+ var arrowHead = _this.drawArrowHead(renderer, points, leaderColor);
783
+ if (arrowHead)
784
+ entities.push(arrowHead);
785
+ };
786
+ // Geometry-only renderers omit traits. Touch them only when a dimension
787
+ // color has to replace the entity color for this draw.
788
+ if (leaderColor && traits) {
789
+ var previousColor = traits.color;
790
+ traits.color = leaderColor;
791
+ try {
792
+ drawGeometry();
793
+ }
794
+ finally {
795
+ traits.color = previousColor;
796
+ }
797
+ }
798
+ else {
799
+ drawGeometry();
800
+ }
801
+ if (entities.length === 0)
802
+ return renderer.lines([]);
803
+ return entities.length === 1 ? entities[0] : renderer.group(entities);
804
+ };
805
+ Object.defineProperty(AcDbLeader.prototype, "hasRenderableArrowHead", {
806
+ /**
807
+ * Whether an arrowhead primitive is emitted at the leader start.
808
+ *
809
+ * DXF group code 71 (`hasArrowHead`) is authoritative: when it is 0 AutoCAD
810
+ * draws no arrowhead at all. The arrow geometry itself comes from the
811
+ * dimension style (DIMLDRBLK arrow block scaled by DIMASZ).
812
+ */
813
+ get: function () {
814
+ if (!this._hasArrowHead || this.numVertices < 2)
815
+ return false;
816
+ if (this.resolveArrowHeadBlockName() === '')
817
+ return false;
818
+ return this.resolveArrowHeadSize() > 0;
819
+ },
820
+ enumerable: false,
821
+ configurable: true
822
+ });
823
+ /**
824
+ * Color of the leader line and arrowhead.
825
+ *
826
+ * AutoCAD paints both from DIMCLRD. An explicit ACI (including a DSTYLE
827
+ * override) wins over the entity color, which is why a ByLayer leader on
828
+ * layer 0 still draws red when DIMCLRD is 1. ByBlock keeps the entity
829
+ * color, unless DXF group 77 names a color to use in that case. Group 77
830
+ * follows the same ACI convention as group 62: 256 is ByLayer.
831
+ *
832
+ * @returns The dimension color, or `undefined` when the entity color
833
+ * already on the renderer traits should be kept.
834
+ */
835
+ AcDbLeader.prototype.resolveLeaderLineColor = function () {
836
+ var style = this.resolveDimensionStyle();
837
+ if (!style)
838
+ return undefined;
839
+ var dimColor = acdbDecodeDimStyleColor(style.dimclrd);
840
+ if (dimColor.isByBlock)
841
+ return this.resolveByBlockLeaderColor();
842
+ if (dimColor.isByLayer)
843
+ return this.resolveLayerLeaderColor();
844
+ return dimColor;
845
+ };
846
+ /**
847
+ * Whether {@link resolveLeaderLineColor} would paint something other than
848
+ * the color `worldDraw` already stored on the renderer.
849
+ */
850
+ AcDbLeader.prototype.leaderLineColorDiffersFromEntity = function () {
851
+ var leaderColor = this.resolveLeaderLineColor();
852
+ if (!leaderColor)
853
+ return false;
854
+ try {
855
+ return !leaderColor.equals(this.resolvedColor);
856
+ }
857
+ catch (_a) {
858
+ return true;
859
+ }
860
+ };
861
+ /**
862
+ * DXF group 77, used only when DIMCLRD is ByBlock.
863
+ *
864
+ * `0` and a missing value keep the entity color. `256` is ByLayer.
865
+ */
866
+ AcDbLeader.prototype.resolveByBlockLeaderColor = function () {
867
+ var override = this._byBlockColor;
868
+ if (override == null || override === 0)
869
+ return undefined;
870
+ if (override === 256)
871
+ return this.resolveLayerLeaderColor();
872
+ if (override > 0 && override < 256) {
873
+ var color = new AcCmColor();
874
+ color.colorIndex = override;
875
+ return color;
876
+ }
877
+ return undefined;
878
+ };
879
+ /**
880
+ * Layer color for DIMCLRD / group 77 ByLayer.
881
+ *
882
+ * The returned color is a clone so assigning it to renderer traits cannot
883
+ * mutate the layer table record.
884
+ */
885
+ AcDbLeader.prototype.resolveLayerLeaderColor = function () {
886
+ var _a;
887
+ try {
888
+ return (_a = this.getLayerColor()) === null || _a === void 0 ? void 0 : _a.clone();
889
+ }
890
+ catch (_b) {
891
+ return undefined;
892
+ }
893
+ };
894
+ /**
895
+ * Draws the arrowhead (DXF group code 71) at the first leader vertex.
896
+ *
897
+ * The tip sits on the first vertex and the tail points toward the second
898
+ * vertex. Arrow blocks are authored with the tip at the block origin and the
899
+ * tail along -X, so the insert angle maps block +X onto the outward leader
900
+ * direction. When the referenced block is missing, the built-in AutoCAD
901
+ * arrow blocks are generated on demand; only the default closed filled arrow
902
+ * can still be reproduced procedurally if that lookup also fails.
903
+ *
904
+ * @param renderer - Renderer used to create the primitive.
905
+ * @param points - Leader draw points whose first entry is the arrow tip.
906
+ * @param leaderColor - DIMCLRD color, when it replaces the entity color.
907
+ * @returns The arrowhead primitive, or `undefined` when none is drawn.
908
+ */
909
+ AcDbLeader.prototype.drawArrowHead = function (renderer, points, leaderColor) {
910
+ var _a;
911
+ if (!this.hasRenderableArrowHead || points.length < 2)
912
+ return undefined;
913
+ var tip = points[0];
914
+ var next = points.find(function (point) { return !point.equals(tip); });
915
+ if (!next)
916
+ return undefined;
917
+ var intoBody = new AcGeVector3d().subVectors(next, tip);
918
+ if (intoBody.lengthSq() === 0)
919
+ return undefined;
920
+ intoBody.normalize();
921
+ var size = this.resolveArrowHeadSize();
922
+ var angle = Math.atan2(-intoBody.y, -intoBody.x);
923
+ var blockName = this.resolveArrowHeadBlockName();
924
+ var blockTableRecord = this.resolveArrowHeadBlock(blockName);
925
+ if (blockTableRecord) {
926
+ var basePoint = (_a = blockTableRecord.origin) !== null && _a !== void 0 ? _a : AcGePoint3d.ORIGIN;
927
+ var mBase = new AcGeMatrix3d().makeTranslation(-basePoint.x, -basePoint.y, -basePoint.z);
928
+ var mScale = new AcGeMatrix3d().makeScale(size, size, size);
929
+ var mRot = new AcGeMatrix3d().makeRotationZ(angle);
930
+ var mInsert = new AcGeMatrix3d().makeTranslation(tip.x, tip.y, tip.z);
931
+ var matrix = new AcGeMatrix3d()
932
+ .multiplyMatrices(mInsert, mRot)
933
+ .multiply(mScale)
934
+ .multiply(mBase);
935
+ return AcDbRenderingCache.instance.draw(renderer, blockTableRecord, leaderColor !== null && leaderColor !== void 0 ? leaderColor : this.resolvedColor, [], true, matrix, new AcGeVector3d(this.normal));
936
+ }
937
+ // Only the default closed-filled arrow can be reproduced procedurally.
938
+ if (blockName !== CLOSED_FILLED_ARROW_BLOCK)
939
+ return undefined;
940
+ var baseCenter = tip.clone().addScaledVector(intoBody, size);
941
+ var halfWidth = size / 6;
942
+ var perpendicular = new AcGeVector3d(-intoBody.y, intoBody.x, intoBody.z);
943
+ var left = baseCenter.clone().addScaledVector(perpendicular, halfWidth);
944
+ var right = baseCenter.clone().addScaledVector(perpendicular, -halfWidth);
945
+ var area = new AcGeArea2d();
946
+ area.add(new AcGePolyline2d([tip, left, right, tip], true));
947
+ var traits = renderer.subEntityTraits;
948
+ var originalFillType = traits.fillType;
949
+ traits.fillType = {
950
+ solidFill: true,
951
+ patternAngle: 0,
952
+ definitionLines: []
953
+ };
954
+ var entity = renderer.area(area);
955
+ traits.fillType = originalFillType;
956
+ return entity;
957
+ };
958
+ /**
959
+ * Resolves the arrowhead size in drawing units.
960
+ *
961
+ * AutoCAD documents DIMASZ as "the size of dimension line **and leader line**
962
+ * arrowheads", so leaders always use DIMASZ (not the DIMTSZ oblique-tick size,
963
+ * which only replaces terminators on linear/radius/diameter dimensions).
964
+ * DIMASZ is scaled by the effective dimension/annotation scale.
965
+ */
966
+ AcDbLeader.prototype.resolveArrowHeadSize = function () {
967
+ var _a;
968
+ var dimStyle = this.resolveDimensionStyle();
969
+ if (!dimStyle) {
970
+ return AcDbDimStyleTableRecord.DEFAULT_DIM_VALUES.dimasz;
971
+ }
972
+ var scale = acdbDimFeatureScale(dimStyle, this);
973
+ var size = ((_a = dimStyle.dimasz) !== null && _a !== void 0 ? _a : 0) * (scale > 0 ? scale : 1);
974
+ return size > 0 ? size : 0;
975
+ };
976
+ /**
977
+ * Resolves the leader arrowhead block name from DIMLDRBLK.
978
+ *
979
+ * An empty DIMLDRBLK means the default closed filled arrow; `_NONE` resolves
980
+ * to an empty name so no arrowhead is drawn.
981
+ */
982
+ AcDbLeader.prototype.resolveArrowHeadBlockName = function () {
983
+ var dimStyle = this.resolveDimensionStyle();
984
+ return acdbResolveArrowBlockName(dimStyle === null || dimStyle === void 0 ? void 0 : dimStyle.dimldrblk);
985
+ };
986
+ /**
987
+ * Looks up the arrowhead block table record by name.
988
+ */
989
+ AcDbLeader.prototype.resolveArrowHeadBlock = function (name) {
990
+ if (!name)
991
+ return undefined;
992
+ var database = this.tryGetDatabase();
993
+ if (!database)
994
+ return undefined;
995
+ var existing = database.tables.blockTable.getAt(name);
996
+ if (existing)
997
+ return existing;
998
+ // Arrowhead blocks such as `_DOT` / `_ARCHTICK` are AutoCAD built-ins and
999
+ // are often missing from the drawing's block table; dimension entities
1000
+ // generate them on demand, so leaders must do the same before giving up.
1001
+ var dimStyle = this.resolveDimensionStyle();
1002
+ if (dimStyle)
1003
+ acdbEnsureDimArrowBlocks(database, dimStyle);
1004
+ return database.tables.blockTable.getAt(name);
601
1005
  };
602
1006
  /**
603
1007
  * Builds the leader polyline including the optional horizontal hook line
@@ -621,26 +1025,19 @@ var AcDbLeader = /** @class */ (function (_super) {
621
1025
  return points;
622
1026
  };
623
1027
  /**
624
- * Whether a hook line should be rendered for the landing vertex.
1028
+ * Whether a hook line (the landing segment at the annotation end) should be
1029
+ * rendered for the landing vertex.
1030
+ *
1031
+ * DXF group code 75 (and its DWG equivalent `hookline_on`) is authoritative:
1032
+ * when it is 0 AutoCAD does not draw any landing segment, even if the leader
1033
+ * happens to sit next to a text entity. Only a leader that advertises a hook
1034
+ * line is extended here.
625
1035
  */
626
1036
  AcDbLeader.prototype.shouldDrawHookLine = function (lastVertex) {
627
- var _a;
628
- if (this.resolveHookLineLength(lastVertex) <= 0) {
629
- return false;
630
- }
631
- if (this._hasHookLine) {
632
- return true;
633
- }
634
- var mtext = this.resolveAssociatedMText();
635
- if (mtext && this.resolveHookSpanFromMText(mtext, lastVertex) > 0) {
636
- return true;
637
- }
638
- if (this._annoType !== AcDbLeaderAnnotationType.MText) {
1037
+ if (!this._hasHookLine) {
639
1038
  return false;
640
1039
  }
641
- var dimStyle = this.resolveDimensionStyle();
642
- var dimtad = (_a = dimStyle === null || dimStyle === void 0 ? void 0 : dimStyle.dimtad) !== null && _a !== void 0 ? _a : AcDbDimStyleTableRecord.DEFAULT_DIM_VALUES.dimtad;
643
- return dimtad !== AcDbDimTextVertical.Center;
1040
+ return this.resolveHookLineLength(lastVertex) > 0;
644
1041
  };
645
1042
  /**
646
1043
  * Computes the hook-line endpoint from the last leader vertex.
@@ -654,32 +1051,43 @@ var AcDbLeader = /** @class */ (function (_super) {
654
1051
  return lastVertex.clone().addScaledVector(direction, hookLength);
655
1052
  };
656
1053
  /**
657
- * Resolves hook-line length using dimension-style gap plus associated MTEXT
658
- * geometry when available.
1054
+ * Resolves the hook-line (landing segment) length and side.
1055
+ *
1056
+ * The landing segment spans the annotation box (DXF 41 / associated MTEXT
1057
+ * width) plus the dimension-style gap. A negative DXF 41 means the author
1058
+ * flipped the landing to the opposite side, which matches AutoCAD. When no
1059
+ * annotation width can be resolved there is nothing to land under, so the
1060
+ * hook line is skipped instead of drawing a gap-sized stub past the author's
1061
+ * own geometry.
1062
+ *
1063
+ * @returns The absolute landing length.
659
1064
  */
660
1065
  AcDbLeader.prototype.resolveHookLineLength = function (lastVertex) {
661
- var _a, _b;
1066
+ var _a;
662
1067
  var dimStyle = this.resolveDimensionStyle();
663
1068
  var gap = ((_a = dimStyle === null || dimStyle === void 0 ? void 0 : dimStyle.dimgap) !== null && _a !== void 0 ? _a : AcDbDimStyleTableRecord.DEFAULT_DIM_VALUES.dimgap) *
664
- ((_b = dimStyle === null || dimStyle === void 0 ? void 0 : dimStyle.dimscale) !== null && _b !== void 0 ? _b : AcDbDimStyleTableRecord.DEFAULT_DIM_VALUES.dimscale);
665
- var length = this._textWidth + gap;
1069
+ (dimStyle ? acdbDimFeatureScale(dimStyle, this) : 1);
1070
+ var declaredWidth = Math.abs(this._textWidth);
1071
+ var length = declaredWidth > 0 ? declaredWidth + gap : 0;
666
1072
  var mtext = this.resolveAssociatedMText();
667
1073
  if (mtext) {
668
1074
  var span = this.resolveHookSpanFromMText(mtext, lastVertex);
669
- if (span > 0) {
670
- length = Math.max(length, span);
1075
+ if (span > length) {
1076
+ length = span;
671
1077
  }
672
1078
  else {
673
1079
  var width = this.resolveAnnotationWidth(mtext);
674
- if (width > 0) {
675
- length = Math.max(length, width);
676
- }
1080
+ if (width > length)
1081
+ length = width;
677
1082
  }
678
1083
  }
679
1084
  return length;
680
1085
  };
681
1086
  /**
682
1087
  * Returns the signed axis along which the hook line extends.
1088
+ *
1089
+ * DXF 74 gives the hook-line direction relative to the horizontal vector and
1090
+ * a negative DXF 41 (annotation box width) flips it once more.
683
1091
  */
684
1092
  AcDbLeader.prototype.resolveHookAxis = function () {
685
1093
  var direction = this._horizontalDirection.clone();
@@ -689,12 +1097,18 @@ var AcDbLeader = /** @class */ (function (_super) {
689
1097
  else {
690
1098
  direction.normalize();
691
1099
  }
1100
+ // Same direction as the horizontal vector → +1; a negative DXF 41 flips it.
692
1101
  var sign = this._isHookLineSameDirection ? 1 : -1;
1102
+ if (this._textWidth < 0)
1103
+ sign = -sign;
693
1104
  direction.multiplyScalar(sign);
694
1105
  return direction;
695
1106
  };
696
1107
  /**
697
1108
  * Computes hook span from the landing vertex to the far edge of MTEXT bounds.
1109
+ *
1110
+ * The span is measured along the resolved landing axis, which already folds
1111
+ * in the DXF 74 direction and a negative DXF 41 flip.
698
1112
  */
699
1113
  AcDbLeader.prototype.resolveHookSpanFromMText = function (mtext, lastVertex) {
700
1114
  var e_1, _a;
@@ -763,6 +1177,14 @@ var AcDbLeader = /** @class */ (function (_super) {
763
1177
  };
764
1178
  /**
765
1179
  * Resolves the dimension style referenced by this leader.
1180
+ *
1181
+ * Entity-level `ACAD`/`DSTYLE` XData overrides are layered on top of the
1182
+ * referenced table record, so per-leader changes to DIMASZ / DIMGAP /
1183
+ * DIMLDRBLK take effect the way AutoCAD draws them.
1184
+ *
1185
+ * The resolved record is memoized: a leader with overrides needs the
1186
+ * detached style copy, and `subWorldDraw` asks for the style several times
1187
+ * per frame (arrow size, arrow block name, hook gap).
766
1188
  */
767
1189
  AcDbLeader.prototype.resolveDimensionStyle = function () {
768
1190
  var _a;
@@ -771,10 +1193,40 @@ var AcDbLeader = /** @class */ (function (_super) {
771
1193
  if (!styleName || !database) {
772
1194
  return undefined;
773
1195
  }
774
- return database.tables.dimStyleTable.getAt(styleName);
1196
+ if (this._dimStyle && this._dimStyleName === styleName) {
1197
+ return this._dimStyle;
1198
+ }
1199
+ var base = database.tables.dimStyleTable.getAt(styleName);
1200
+ var resolved = acdbResolveEffectiveDimStyle(this, base, database);
1201
+ this._dimStyle = resolved;
1202
+ this._dimStyleName = styleName;
1203
+ return resolved;
1204
+ };
1205
+ /**
1206
+ * Drops the memoized effective style when `ACAD` XData changes.
1207
+ */
1208
+ AcDbLeader.prototype.onXDataChanged = function (appId) {
1209
+ if (appId === ACDB_DSTYLE_XDATA_APP) {
1210
+ this._dimStyle = undefined;
1211
+ this._dimStyleName = undefined;
1212
+ }
1213
+ };
1214
+ /**
1215
+ * Drops the memoized effective style when the leader moves to another
1216
+ * database, because the referenced style record belongs to the previous one.
1217
+ */
1218
+ AcDbLeader.prototype.onDatabaseChanged = function () {
1219
+ this._dimStyle = undefined;
1220
+ this._dimStyleName = undefined;
775
1221
  };
776
1222
  /**
777
1223
  * Resolves the MTEXT annotation associated with this leader.
1224
+ *
1225
+ * An explicit `associatedAnnotation` hard pointer (DXF 340) always wins.
1226
+ * The spatial search is only a fallback for leaders that were created with an
1227
+ * MTEXT annotation (DXF 73 = 0); a standalone leader (DXF 73 = 3) has no
1228
+ * annotation, so borrowing an unrelated nearby MTEXT would corrupt its
1229
+ * landing geometry.
778
1230
  */
779
1231
  AcDbLeader.prototype.resolveAssociatedMText = function () {
780
1232
  var e_2, _a;
@@ -784,11 +1236,10 @@ var AcDbLeader = /** @class */ (function (_super) {
784
1236
  }
785
1237
  if (this._associatedAnnotation) {
786
1238
  var object = database.getObjectById(this._associatedAnnotation);
787
- if (object instanceof AcDbMText) {
788
- return object;
789
- }
1239
+ return object instanceof AcDbMText ? object : undefined;
790
1240
  }
791
- if (this._vertices.length === 0) {
1241
+ if (this._annoType !== AcDbLeaderAnnotationType.MText ||
1242
+ this._vertices.length === 0) {
792
1243
  return undefined;
793
1244
  }
794
1245
  var ownerId = this.getAttrWithoutException('ownerId');