@ifc-lite/drawing-2d 2.0.0 → 2.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 (49) hide show
  1. package/dist/color-raster.d.ts +95 -0
  2. package/dist/color-raster.d.ts.map +1 -0
  3. package/dist/color-raster.js +225 -0
  4. package/dist/color-raster.js.map +1 -0
  5. package/dist/drawing-generator.d.ts +12 -0
  6. package/dist/drawing-generator.d.ts.map +1 -1
  7. package/dist/drawing-generator.js +13 -4
  8. package/dist/drawing-generator.js.map +1 -1
  9. package/dist/edge-extractor.d.ts +17 -0
  10. package/dist/edge-extractor.d.ts.map +1 -1
  11. package/dist/edge-extractor.js +95 -0
  12. package/dist/edge-extractor.js.map +1 -1
  13. package/dist/half-space-clip.d.ts +77 -0
  14. package/dist/half-space-clip.d.ts.map +1 -0
  15. package/dist/half-space-clip.js +257 -0
  16. package/dist/half-space-clip.js.map +1 -0
  17. package/dist/hidden-line-raster.d.ts +11 -2
  18. package/dist/hidden-line-raster.d.ts.map +1 -1
  19. package/dist/hidden-line-raster.js +7 -58
  20. package/dist/hidden-line-raster.js.map +1 -1
  21. package/dist/index.d.ts +11 -3
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +25 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/pdf-scale.d.ts +17 -0
  26. package/dist/pdf-scale.d.ts.map +1 -1
  27. package/dist/pdf-scale.js +38 -0
  28. package/dist/pdf-scale.js.map +1 -1
  29. package/dist/raster-core.d.ts +71 -0
  30. package/dist/raster-core.d.ts.map +1 -0
  31. package/dist/raster-core.js +89 -0
  32. package/dist/raster-core.js.map +1 -0
  33. package/dist/sheet/index.d.ts +2 -0
  34. package/dist/sheet/index.d.ts.map +1 -1
  35. package/dist/sheet/index.js +1 -0
  36. package/dist/sheet/index.js.map +1 -1
  37. package/dist/sheet/scale-stamp.d.ts +130 -0
  38. package/dist/sheet/scale-stamp.d.ts.map +1 -0
  39. package/dist/sheet/scale-stamp.js +277 -0
  40. package/dist/sheet/scale-stamp.js.map +1 -0
  41. package/dist/view-plane.d.ts +99 -0
  42. package/dist/view-plane.d.ts.map +1 -0
  43. package/dist/view-plane.js +183 -0
  44. package/dist/view-plane.js.map +1 -0
  45. package/dist/world-line-seeds.d.ts +41 -0
  46. package/dist/world-line-seeds.d.ts.map +1 -0
  47. package/dist/world-line-seeds.js +43 -0
  48. package/dist/world-line-seeds.js.map +1 -0
  49. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -56,7 +56,27 @@ export { SVGExporter, exportToSVG } from './svg-exporter.js';
56
56
  // Scaled PDF export (issue #2042): pure scale/extent arithmetic only —
57
57
  // the PDF is assembled by the viewer using jsPDF, which is not a
58
58
  // dependency of this package.
59
- export { computePdfScaleLayout, worldPointToPdfMm, worldLengthToPdfMm, flipBounds2D, formatScaleFactorLabel, } from './pdf-scale.js';
59
+ export { computePdfScaleLayout, worldPointToPdfMm, worldLengthToPdfMm, flipBounds2D, formatScaleFactorLabel,
60
+ // The ratio a sheet PRINTS: the same number as the filename, hedged with
61
+ // "about" when 2 decimals had to round it (#2042).
62
+ formatSheetScaleLabel, } from './pdf-scale.js';
63
+ // ═══════════════════════════════════════════════════════════════════════════
64
+ // TO-SCALE 3D-VIEW EXPORT (issue #2042)
65
+ // ═══════════════════════════════════════════════════════════════════════════
66
+ // Synthetic camera section plane (orthonormal basis, placed in front of the
67
+ // model) + the world bounds helper that folds `MeshData.origin`.
68
+ // `worldBoundsCorners` stays package-private: `buildCameraSectionPlane` does
69
+ // the corner work itself and no external consumer exists, so publishing it
70
+ // would only be permanent semver liability (PR #1871 review).
71
+ export { buildCameraSectionPlane, worldBoundsOfMeshes } from './view-plane.js';
72
+ // CPU half-space clip standing in for the GPU section clip.
73
+ export { clipMeshToHalfSpace, clipMeshesToHalfSpace } from './half-space-clip.js';
74
+ // World segments -> classified drawing lines (feeds `GeneratorOptions.extraLines`).
75
+ export { projectWorldLineSeeds } from './world-line-seeds.js';
76
+ // Flat-shaded RGBA underlay for the to-scale PDF: the surfaces the viewport
77
+ // shows, placed under the vector line work. `raster-core.ts` (the primitives
78
+ // this shares with the hidden-line depth raster) stays package-private.
79
+ export { buildColorRaster, fitRasterPixels, DEFAULT_SHADING_DPI, MAX_SHADING_PIXELS, MAX_SHADING_DIMENSION_PX, } from './color-raster.js';
60
80
  // ═══════════════════════════════════════════════════════════════════════════
61
81
  // DXF EXPORT (issue #1861)
62
82
  // ═══════════════════════════════════════════════════════════════════════════
@@ -135,6 +155,10 @@ DEFAULT_TITLE_BLOCK_FIELDS, TITLE_BLOCK_PRESETS, createTitleBlock, getDefaultTit
135
155
  DEFAULT_SCALE_BAR, DEFAULT_NORTH_ARROW, calculateOptimalScaleBarLength, calculateOptimalDivisions,
136
156
  // Sheet utilities
137
157
  calculateViewportBounds, calculateDrawingTransform,
158
+ // Scale stamp: the sheet's own record of the scale it was drawn at (#2042).
159
+ // Grows the page around an EXISTING to-scale layout and returns its
160
+ // transform untouched, unlike `calculateDrawingTransform`, which re-fits.
161
+ addScaleStamp,
138
162
  // Sheet renderers
139
163
  renderFrame, renderTitleBlock, renderScaleBar, renderNorthArrow, } from './sheet/index.js';
140
164
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -82,6 +82,23 @@ export declare function flipBounds2D(bounds: Bounds2D, flip: AxisFlip): Bounds2D
82
82
  * re-deriving (and potentially disagreeing on) its own.
83
83
  */
84
84
  export declare function formatScaleFactorLabel(factor: number): string;
85
+ /**
86
+ * The ratio a sheet prints for `factor`: `"1:100"` when the label IS the
87
+ * factor, `"about 1:87.35"` when {@link formatScaleFactorLabel} had to round it.
88
+ *
89
+ * WHY THE HEDGE EXISTS. A to-scale sheet is a promise that a distance measured
90
+ * off the paper converts back at the printed ratio. "As displayed" hands over
91
+ * whatever factor the viewport happens to sit at — 1:87.3456 — and printing a
92
+ * bare "1:87.35" would state a scale the drawing was not drawn at, which is the
93
+ * same defect as an unlabelled sheet wearing a different hat: a number an
94
+ * engineer would trust and should not. The word says the printed ratio is the
95
+ * nearest hundredth, and the drawn scale bar next to it carries the exact
96
+ * length regardless.
97
+ *
98
+ * The number itself is left at 2 decimals so the sheet and the export filename
99
+ * (which goes through the same formatter) can never quote different ratios.
100
+ */
101
+ export declare function formatSheetScaleLabel(factor: number): string;
85
102
  /** Map one world-space point (metres) to paper space (mm) via `transform`. */
86
103
  export declare function worldPointToPdfMm(point: Point2D, transform: PdfScaleTransform): Point2D;
87
104
  /** Convert a line weight / length already expressed in mm-on-paper terms
@@ -1 +1 @@
1
- {"version":3,"file":"pdf-scale.d.ts","sourceRoot":"","sources":["../src/pdf-scale.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEpD;;6DAE6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAK,GACZ,cAAc,CA6DhB;AAED;;2EAE2E;AAC3E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAWvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAKvF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAE7F"}
1
+ {"version":3,"file":"pdf-scale.d.ts","sourceRoot":"","sources":["../src/pdf-scale.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEpD;;6DAE6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAK,GACZ,cAAc,CA6DhB;AAED;;2EAE2E;AAC3E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAWvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG7D;AAkBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAKvF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAE7F"}
package/dist/pdf-scale.js CHANGED
@@ -102,6 +102,44 @@ export function formatScaleFactorLabel(factor) {
102
102
  const rounded = Math.round(factor * 100) / 100;
103
103
  return rounded % 1 === 0 ? rounded.toFixed(0) : rounded.toFixed(2).replace(/0+$/, '').replace(/\.$/, '');
104
104
  }
105
+ /**
106
+ * How close the 2-decimal label has to be to the real factor to call it exact.
107
+ *
108
+ * Deliberately an ULP-scale tolerance and not a loose relative one. "Exact"
109
+ * here means the printed digits ARE the factor, give or take the error of
110
+ * representing it as a double - so the only slack allowed is that
111
+ * representation error, which is what `Number.EPSILON` measures. A loose
112
+ * relative tolerance grows with the factor and quietly re-admits the very
113
+ * thing this label exists to disclose: at 1e-9 relative, a factor of
114
+ * 100000000.004 sits 0.004 from its printed 100000000 and 0.004 is inside a
115
+ * 0.1 tolerance, so a rounded ratio would print as "1:100000000" with no
116
+ * hedge. Four ULP leaves room for the divide-and-round round trip without
117
+ * ever spanning a real difference in the printed digits.
118
+ */
119
+ const LABEL_EXACTNESS_ULPS = 4;
120
+ /**
121
+ * The ratio a sheet prints for `factor`: `"1:100"` when the label IS the
122
+ * factor, `"about 1:87.35"` when {@link formatScaleFactorLabel} had to round it.
123
+ *
124
+ * WHY THE HEDGE EXISTS. A to-scale sheet is a promise that a distance measured
125
+ * off the paper converts back at the printed ratio. "As displayed" hands over
126
+ * whatever factor the viewport happens to sit at — 1:87.3456 — and printing a
127
+ * bare "1:87.35" would state a scale the drawing was not drawn at, which is the
128
+ * same defect as an unlabelled sheet wearing a different hat: a number an
129
+ * engineer would trust and should not. The word says the printed ratio is the
130
+ * nearest hundredth, and the drawn scale bar next to it carries the exact
131
+ * length regardless.
132
+ *
133
+ * The number itself is left at 2 decimals so the sheet and the export filename
134
+ * (which goes through the same formatter) can never quote different ratios.
135
+ */
136
+ export function formatSheetScaleLabel(factor) {
137
+ const label = formatScaleFactorLabel(factor);
138
+ const printed = Number(label);
139
+ const exact = Number.isFinite(printed) &&
140
+ Math.abs(printed - factor) <= Math.abs(factor) * Number.EPSILON * LABEL_EXACTNESS_ULPS;
141
+ return exact ? `1:${label}` : `about 1:${label}`;
142
+ }
105
143
  /** Map one world-space point (metres) to paper space (mm) via `transform`. */
106
144
  export function worldPointToPdfMm(point, transform) {
107
145
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"pdf-scale.js","sourceRoot":"","sources":["../src/pdf-scale.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pdf-scale.js","sourceRoot":"","sources":["../src/pdf-scale.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Shared software-rasterizer primitives.
3
+ *
4
+ * Two rasterizers run over the same meshes in the same 2D drawing frame:
5
+ * `hidden-line-raster.ts` (a per-pixel minimum VIEW DEPTH buffer used to
6
+ * classify lines hidden) and `color-raster.ts` (the shaded RGBA underlay for
7
+ * the to-scale PDF export). They write different buffers, so they keep their
8
+ * own inner scan loops, but they MUST agree on how a mesh vertex becomes a
9
+ * world point, how a pixel becomes barycentric weights, and how the projected
10
+ * extent of a mesh set is measured. Those three live here so a fix to one
11
+ * cannot leave the other behind.
12
+ *
13
+ * Projection and depth themselves are NOT re-derived here: callers use
14
+ * `projectPointForPlane` / `signedDepth` from `projection-bands.ts`, the same
15
+ * helpers every line producer uses, which is what makes the raster and the
16
+ * strokes share a frame by construction.
17
+ *
18
+ * Internal module: not exported from the package index.
19
+ */
20
+ import type { MeshData } from '@ifc-lite/geometry';
21
+ import type { Vec3, Bounds2D, SectionPlaneConfig } from './types.js';
22
+ /** A projected vertex in drawing 2D space, carrying its view depth. */
23
+ export interface RasterVertex {
24
+ x: number;
25
+ y: number;
26
+ depth: number;
27
+ }
28
+ /**
29
+ * World-space position of vertex `index`. Positions are stored in the
30
+ * element's local frame (`world = origin + local`) - see section-cutter.ts /
31
+ * edge-extractor.ts - so `origin` must be folded in for depth and projection.
32
+ */
33
+ export declare function getVertex(positions: Float32Array, index: number, origin?: [number, number, number]): Vec3;
34
+ /**
35
+ * 2D bounds of every vertex whose view depth lies in `[0, depthWindow]` (the
36
+ * kept half of the section), optionally grown by `marginFraction` of the
37
+ * larger side on all four sides. Empty (non-finite) when no vertex is in the
38
+ * window - callers must check before dividing by the extent.
39
+ *
40
+ * `marginFraction` exists because the two consumers want different things:
41
+ * the hidden-line raster grows the box slightly so geometry exactly on the
42
+ * edge still rasterizes cleanly, while the colour raster needs bounds that
43
+ * are EXACTLY the projected extent, because that rectangle is what gets
44
+ * placed on the PDF page at an exact millimetre size.
45
+ */
46
+ export declare function computeProjectedBounds(meshes: readonly MeshData[], plane: SectionPlaneConfig, depthWindow: number, marginFraction: number): Bounds2D;
47
+ /**
48
+ * Barycentric weights of `(px, py)` against a 2D triangle. All three weights
49
+ * are >= 0 exactly when the point is inside (or on) the triangle. Returns
50
+ * `{ u: -1, v: -1, w: -1 }` for a degenerate (zero-area) triangle, which no
51
+ * inside test accepts.
52
+ *
53
+ * Orientation-independent (the denominator is a Gram determinant, always
54
+ * positive for a non-degenerate triangle), so a caller may flip an axis when
55
+ * mapping to pixel space without inverting the inside test.
56
+ */
57
+ export declare function barycentricCoords(px: number, py: number, p0: {
58
+ x: number;
59
+ y: number;
60
+ }, p1: {
61
+ x: number;
62
+ y: number;
63
+ }, p2: {
64
+ x: number;
65
+ y: number;
66
+ }): {
67
+ u: number;
68
+ v: number;
69
+ w: number;
70
+ };
71
+ //# sourceMappingURL=raster-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raster-core.d.ts","sourceRoot":"","sources":["../src/raster-core.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrE,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,IAAI,CASN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,QAAQ,EAAE,EAC3B,KAAK,EAAE,kBAAkB,EACzB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,QAAQ,CA8BV;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAyBrC"}
@@ -0,0 +1,89 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { vec3, boundsEmpty, boundsExtendPoint } from './math.js';
5
+ import { signedDepth, projectPointForPlane } from './projection-bands.js';
6
+ /**
7
+ * World-space position of vertex `index`. Positions are stored in the
8
+ * element's local frame (`world = origin + local`) - see section-cutter.ts /
9
+ * edge-extractor.ts - so `origin` must be folded in for depth and projection.
10
+ */
11
+ export function getVertex(positions, index, origin) {
12
+ const base = index * 3;
13
+ return origin
14
+ ? vec3(positions[base] + origin[0], positions[base + 1] + origin[1], positions[base + 2] + origin[2])
15
+ : vec3(positions[base], positions[base + 1], positions[base + 2]);
16
+ }
17
+ /**
18
+ * 2D bounds of every vertex whose view depth lies in `[0, depthWindow]` (the
19
+ * kept half of the section), optionally grown by `marginFraction` of the
20
+ * larger side on all four sides. Empty (non-finite) when no vertex is in the
21
+ * window - callers must check before dividing by the extent.
22
+ *
23
+ * `marginFraction` exists because the two consumers want different things:
24
+ * the hidden-line raster grows the box slightly so geometry exactly on the
25
+ * edge still rasterizes cleanly, while the colour raster needs bounds that
26
+ * are EXACTLY the projected extent, because that rectangle is what gets
27
+ * placed on the PDF page at an exact millimetre size.
28
+ */
29
+ export function computeProjectedBounds(meshes, plane, depthWindow, marginFraction) {
30
+ let bounds = boundsEmpty();
31
+ for (const mesh of meshes) {
32
+ const { positions, origin } = mesh;
33
+ const vertexCount = positions.length / 3;
34
+ for (let i = 0; i < vertexCount; i++) {
35
+ const v = getVertex(positions, i, origin);
36
+ const viewDepth = -signedDepth(v, plane);
37
+ if (viewDepth >= 0 && viewDepth <= depthWindow) {
38
+ bounds = boundsExtendPoint(bounds, projectPointForPlane(v, plane));
39
+ }
40
+ }
41
+ }
42
+ const width = bounds.max.x - bounds.min.x;
43
+ const height = bounds.max.y - bounds.min.y;
44
+ if (!Number.isFinite(width) || !Number.isFinite(height)) {
45
+ return bounds; // empty: caller decides how to degrade
46
+ }
47
+ if (marginFraction > 0) {
48
+ const margin = Math.max(width, height) * marginFraction;
49
+ bounds.min.x -= margin;
50
+ bounds.min.y -= margin;
51
+ bounds.max.x += margin;
52
+ bounds.max.y += margin;
53
+ }
54
+ return bounds;
55
+ }
56
+ /**
57
+ * Barycentric weights of `(px, py)` against a 2D triangle. All three weights
58
+ * are >= 0 exactly when the point is inside (or on) the triangle. Returns
59
+ * `{ u: -1, v: -1, w: -1 }` for a degenerate (zero-area) triangle, which no
60
+ * inside test accepts.
61
+ *
62
+ * Orientation-independent (the denominator is a Gram determinant, always
63
+ * positive for a non-degenerate triangle), so a caller may flip an axis when
64
+ * mapping to pixel space without inverting the inside test.
65
+ */
66
+ export function barycentricCoords(px, py, p0, p1, p2) {
67
+ const v0x = p1.x - p0.x;
68
+ const v0y = p1.y - p0.y;
69
+ const v1x = p2.x - p0.x;
70
+ const v1y = p2.y - p0.y;
71
+ const v2x = px - p0.x;
72
+ const v2y = py - p0.y;
73
+ const dot00 = v0x * v0x + v0y * v0y;
74
+ const dot01 = v0x * v1x + v0y * v1y;
75
+ const dot02 = v0x * v2x + v0y * v2y;
76
+ const dot11 = v1x * v1x + v1y * v1y;
77
+ const dot12 = v1x * v2x + v1y * v2y;
78
+ const denom = dot00 * dot11 - dot01 * dot01;
79
+ // Handle degenerate triangles (zero area) by returning invalid coordinates
80
+ if (Math.abs(denom) < 1e-10) {
81
+ return { u: -1, v: -1, w: -1 };
82
+ }
83
+ const invDenom = 1 / denom;
84
+ const v = (dot11 * dot02 - dot01 * dot12) * invDenom;
85
+ const w = (dot00 * dot12 - dot01 * dot02) * invDenom;
86
+ const u = 1 - v - w;
87
+ return { u, v, w };
88
+ }
89
+ //# sourceMappingURL=raster-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raster-core.js","sourceRoot":"","sources":["../src/raster-core.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAwB/D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAS1E;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,SAAuB,EACvB,KAAa,EACb,MAAiC;IAEjC,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;IACvB,OAAO,MAAM;QACX,CAAC,CAAC,IAAI,CACF,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAC3B,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAC/B,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAChC;QACH,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAA2B,EAC3B,KAAyB,EACzB,WAAmB,EACnB,cAAsB;IAEtB,IAAI,MAAM,GAAG,WAAW,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACnC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;gBAC/C,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC,CAAC,uCAAuC;IACxD,CAAC;IAED,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC;QACxD,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAU,EACV,EAAU,EACV,EAA4B,EAC5B,EAA4B,EAC5B,EAA4B;IAE5B,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAEtB,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAEpC,MAAM,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5C,2EAA2E;IAC3E,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEpB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACrB,CAAC"}
@@ -15,6 +15,8 @@ export type { TitleBlockPosition, TitleBlockLayout, TitleBlockField, TitleBlockL
15
15
  export { DEFAULT_TITLE_BLOCK_FIELDS, TITLE_BLOCK_PRESETS, createTitleBlock, getDefaultTitleBlock, updateTitleBlockField, } from './title-block-types.js';
16
16
  export type { ScaleBarStyle, ScaleBarPosition, ScaleBarUnits, ScaleBarConfig, NorthArrowStyle, NorthArrowConfig, } from './scale-bar-types.js';
17
17
  export { DEFAULT_SCALE_BAR, DEFAULT_NORTH_ARROW, calculateOptimalScaleBarLength, calculateOptimalDivisions, } from './scale-bar-types.js';
18
+ export type { ScaleStampRect, ScaleStampText, ScaleStampBar, ScaleStamp, StampedSheetLayout, } from './scale-stamp.js';
19
+ export { addScaleStamp } from './scale-stamp.js';
18
20
  export type { ViewportBounds, DrawingSheet, SheetCreationOptions, } from './sheet-types.js';
19
21
  export { calculateViewportBounds, calculateDrawingTransform, } from './sheet-types.js';
20
22
  export type { FrameRenderResult, } from './frame-renderer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sheet/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAGH,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,YAAY,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sheet/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAGH,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAK9B,YAAY,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACb,UAAU,EACV,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,YAAY,EACV,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,YAAY,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -5,6 +5,7 @@ export { PAPER_SIZE_REGISTRY, getPaperSizesByCategory, getDefaultPaperSize, } fr
5
5
  export { FRAME_PRESETS, createFrame, getDefaultFrame, } from './frame-types.js';
6
6
  export { DEFAULT_TITLE_BLOCK_FIELDS, TITLE_BLOCK_PRESETS, createTitleBlock, getDefaultTitleBlock, updateTitleBlockField, } from './title-block-types.js';
7
7
  export { DEFAULT_SCALE_BAR, DEFAULT_NORTH_ARROW, calculateOptimalScaleBarLength, calculateOptimalDivisions, } from './scale-bar-types.js';
8
+ export { addScaleStamp } from './scale-stamp.js';
8
9
  export { calculateViewportBounds, calculateDrawingTransform, } from './sheet-types.js';
9
10
  export { renderFrame } from './frame-renderer.js';
10
11
  export { renderTitleBlock } from './title-block-renderer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sheet/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAkB/D,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAWhC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sheet/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAkB/D,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAWhC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQjD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The scale record a to-scale sheet carries on the paper itself: a drawn scale
3
+ * bar plus the "1:N" text, laid out in millimetres in a band below the drawing
4
+ * (issue #2042).
5
+ *
6
+ * WHY A SHEET WITHOUT THIS IS DANGEROUS. A to-scale PDF whose only record of
7
+ * its scale is its filename says nothing once it is printed. The whole promise
8
+ * of the export is "measurements taken off the print are correct", and a sheet
9
+ * that carries no scale invites someone to measure it at an assumed one. The
10
+ * printed ratio fixes that for the original; the BAR fixes it for every copy
11
+ * after, because a photocopier that shrinks a sheet to 94% shrinks the bar with
12
+ * it while the text "1:100" keeps claiming a scale the paper no longer has.
13
+ * Those are two different failures, so the sheet carries both.
14
+ *
15
+ * WHAT THIS FILE MUST NEVER DO — the reason it exists as layout maths and not
16
+ * as a sheet template. `sheet-types.ts`'s `calculateDrawingTransform` fits a
17
+ * drawing into a fixed viewport (`fitScale = min(scaleX, scaleY, 1)`), which
18
+ * silently shrinks it. Adding furniture through anything that re-fits would
19
+ * turn an exact sheet into a plausible-looking wrong one, which is the single
20
+ * defect this whole feature exists to prevent. So the band is added by GROWING
21
+ * the page down (and right, only if the stamp is wider than the drawing) and
22
+ * the drawing's `PdfScaleTransform` is passed through untouched — same
23
+ * `worldToMm`, same offsets, same object. Adding a scale bar cannot move a
24
+ * single millimetre of the drawing, by construction rather than by care.
25
+ *
26
+ * The emission is deliberately not here: these are plain rectangles and text
27
+ * runs in page millimetres, so the viewer can write them with jsPDF while the
28
+ * sibling renderers in this folder keep emitting SVG strings.
29
+ */
30
+ import { type PdfPage, type PdfScaleLayout, type PdfScaleTransform } from '../pdf-scale.js';
31
+ /** One rectangle of the bar, in page millimetres from the page's top-left. */
32
+ export interface ScaleStampRect {
33
+ xMm: number;
34
+ yMm: number;
35
+ widthMm: number;
36
+ heightMm: number;
37
+ /** Painted solid when true, outline only when false. Always stroked. */
38
+ filled: boolean;
39
+ }
40
+ /** One text run of the stamp, in page millimetres from the page's top-left. */
41
+ export interface ScaleStampText {
42
+ text: string;
43
+ xMm: number;
44
+ /** The text BASELINE, which is where PDF text origins sit. */
45
+ yMm: number;
46
+ align: 'left' | 'center';
47
+ /** Nominal text height (em size) in mm, for the writer to convert to points. */
48
+ heightMm: number;
49
+ /**
50
+ * The model distance this label marks, in metres, or `null` for free text
51
+ * such as the ratio. A consumer can multiply it by the transform's
52
+ * `worldToMm` and check that the label really sits there — which is what
53
+ * makes "the bar is drawn to scale" a measurable claim rather than a hope.
54
+ */
55
+ metres: number | null;
56
+ }
57
+ /** The bar itself, kept as numbers so callers can measure it. */
58
+ export interface ScaleStampBar {
59
+ xMm: number;
60
+ yMm: number;
61
+ widthMm: number;
62
+ heightMm: number;
63
+ divisions: number;
64
+ /** Model length of one division, in metres. */
65
+ divisionMetres: number;
66
+ /** Paper length of one division: exactly `divisionMetres * worldToMm`. */
67
+ divisionWidthMm: number;
68
+ }
69
+ export interface ScaleStamp {
70
+ bar: ScaleStampBar;
71
+ rects: readonly ScaleStampRect[];
72
+ texts: readonly ScaleStampText[];
73
+ /** Extent of the band from its origin, mm. */
74
+ widthMm: number;
75
+ heightMm: number;
76
+ /** The ratio as printed, e.g. "1:100". Never a rounded stand-in. */
77
+ scaleLabel: string;
78
+ }
79
+ export interface ScaleStampOptions {
80
+ /** Millimetres of paper per metre of world: `PdfScaleTransform.worldToMm`. */
81
+ worldToMm: number;
82
+ /** Paper the band may use before the page has to grow to hold it, mm. */
83
+ availableWidthMm: number;
84
+ /** Top-left corner of the band, in page millimetres. */
85
+ originXMm: number;
86
+ originYMm: number;
87
+ }
88
+ /** A drawing layout plus the scale band underneath it. */
89
+ export interface StampedSheetLayout {
90
+ page: PdfPage;
91
+ /**
92
+ * The drawing's transform, unchanged. The band is added below and to the
93
+ * right of everything the drawing occupies, so no offset is needed and none
94
+ * is applied: this is the same object `computePdfScaleLayout` returned.
95
+ */
96
+ transform: PdfScaleTransform;
97
+ stamp: ScaleStamp;
98
+ }
99
+ /** Height of the whole band. Independent of scale, bar length and page size. */
100
+ export declare const SCALE_STAMP_HEIGHT_MM: number;
101
+ /**
102
+ * Lay out a scale bar and its ratio text with their top-left corner at
103
+ * (`originXMm`, `originYMm`).
104
+ *
105
+ * Throws on a non-finite or non-positive `worldToMm` and on non-finite
106
+ * placement: a stamp is the sheet's statement about its own scale, so emitting
107
+ * one from numbers that do not describe a scale would be worse than emitting
108
+ * none at all.
109
+ */
110
+ export declare function buildScaleStamp(options: ScaleStampOptions): ScaleStamp;
111
+ /**
112
+ * Grow `base` by a scale band under the drawing.
113
+ *
114
+ * The page gains exactly `SCALE_STAMP_HEIGHT_MM` of height, and width only if
115
+ * the band is wider than the drawing. The transform is returned as it came in
116
+ * — see {@link StampedSheetLayout.transform}.
117
+ *
118
+ * PRECONDITION on `marginMm`: the bar's end tick labels are centred on their
119
+ * ticks, so roughly half a label hangs past each end of the bar. The margin has
120
+ * to absorb that. Zero (or a very small) margin is accepted by the guard below
121
+ * and lays the band out correctly, but the outermost label can then sit partly
122
+ * off the page. The export path passes `VIEW_PDF_MARGIN_MM` (10 mm), which is
123
+ * comfortably more than any label produced by the 1-2-5 division sequence.
124
+ * This is a cosmetic bound only: it does not move the bar, so a division still
125
+ * measures exactly its labelled world length whatever the margin.
126
+ */
127
+ export declare function addScaleStamp(base: PdfScaleLayout, options: {
128
+ marginMm: number;
129
+ }): StampedSheetLayout;
130
+ //# sourceMappingURL=scale-stamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale-stamp.d.ts","sourceRoot":"","sources":["../../src/sheet/scale-stamp.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAMzB,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,EAAE,UAAU,CAAC;CACnB;AAcD,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,QAOnB,CAAC;AA8BhB;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAyFtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5B,kBAAkB,CAgCpB"}