lineadraw 0.7.0 → 0.8.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.
- package/README.md +27 -5
- package/bin/lineadraw.mjs +20 -5
- package/dist/{chunk-NCNZ7A6M.js → chunk-VWED6V6F.js} +2695 -632
- package/dist/chunk-VWED6V6F.js.map +1 -0
- package/dist/exportDxf-2VU5475O.js +8 -0
- package/dist/{node-2RH2EKXG.js → node-PLO3I6OZ.js} +39 -1
- package/dist/node-PLO3I6OZ.js.map +1 -0
- package/dist/pkg/linea_dwg_bg.wasm +0 -0
- package/dist/sdk.d.ts +874 -363
- package/dist/sdk.js +3371 -1490
- package/dist/sdk.js.map +1 -1
- package/lineadraw.d.ts +396 -26
- package/package.json +1 -1
- package/dist/chunk-NCNZ7A6M.js.map +0 -1
- package/dist/exportDxf-2HC6UIBS.js +0 -8
- package/dist/node-2RH2EKXG.js.map +0 -1
- /package/dist/{exportDxf-2HC6UIBS.js.map → exportDxf-2VU5475O.js.map} +0 -0
|
@@ -2,21 +2,7 @@ import {
|
|
|
2
2
|
__export
|
|
3
3
|
} from "./chunk-PZ5AY32C.js";
|
|
4
4
|
|
|
5
|
-
// ../core/src/
|
|
6
|
-
import {
|
|
7
|
-
DxfWriter,
|
|
8
|
-
Units,
|
|
9
|
-
LayerFlags,
|
|
10
|
-
LWPolylineFlags,
|
|
11
|
-
TextHorizontalAlignment,
|
|
12
|
-
TextVerticalAlignment,
|
|
13
|
-
HatchBoundaryPaths,
|
|
14
|
-
HatchPolylineBoundary,
|
|
15
|
-
HatchPredefinedPatterns,
|
|
16
|
-
pattern
|
|
17
|
-
} from "@tarikjabiri/dxf";
|
|
18
|
-
|
|
19
|
-
// ../core/src/model/objects.ts
|
|
5
|
+
// ../core/src/model/hatchPatterns.ts
|
|
20
6
|
import { z as z2 } from "zod";
|
|
21
7
|
|
|
22
8
|
// ../core/src/model/common.ts
|
|
@@ -40,6 +26,716 @@ var ObjectBaseSchema = z.object({
|
|
|
40
26
|
opacity: z.number().min(0).max(1).optional()
|
|
41
27
|
});
|
|
42
28
|
|
|
29
|
+
// ../core/src/paint/sink.ts
|
|
30
|
+
var matIdentity = [1, 0, 0, 1, 0, 0];
|
|
31
|
+
var matMultiply = (m, n) => [
|
|
32
|
+
m[0] * n[0] + m[2] * n[1],
|
|
33
|
+
m[1] * n[0] + m[3] * n[1],
|
|
34
|
+
m[0] * n[2] + m[2] * n[3],
|
|
35
|
+
m[1] * n[2] + m[3] * n[3],
|
|
36
|
+
m[0] * n[4] + m[2] * n[5] + m[4],
|
|
37
|
+
m[1] * n[4] + m[3] * n[5] + m[5]
|
|
38
|
+
];
|
|
39
|
+
var matApply = (m, p) => ({
|
|
40
|
+
x: m[0] * p.x + m[2] * p.y + m[4],
|
|
41
|
+
y: m[1] * p.x + m[3] * p.y + m[5]
|
|
42
|
+
});
|
|
43
|
+
var signedArcSweep = (startAngle, endAngle, ccw) => {
|
|
44
|
+
const TAU = Math.PI * 2;
|
|
45
|
+
let sweep = ccw ? ((endAngle - startAngle) % TAU + TAU) % TAU : -(((startAngle - endAngle) % TAU + TAU) % TAU);
|
|
46
|
+
if (sweep === 0) sweep = ccw ? TAU : -TAU;
|
|
47
|
+
return sweep;
|
|
48
|
+
};
|
|
49
|
+
var arcToBeziers = (center, r, startAngle, sweep) => {
|
|
50
|
+
const n = Math.max(1, Math.ceil(Math.abs(sweep) / (Math.PI / 2)));
|
|
51
|
+
const step = sweep / n;
|
|
52
|
+
const k = 4 / 3 * Math.tan(step / 4);
|
|
53
|
+
const result = [];
|
|
54
|
+
for (let i = 0; i < n; i++) {
|
|
55
|
+
const a0 = startAngle + step * i;
|
|
56
|
+
const a1 = a0 + step;
|
|
57
|
+
const p0 = {
|
|
58
|
+
x: center.x + r * Math.cos(a0),
|
|
59
|
+
y: center.y + r * Math.sin(a0)
|
|
60
|
+
};
|
|
61
|
+
const p1 = {
|
|
62
|
+
x: center.x + r * Math.cos(a1),
|
|
63
|
+
y: center.y + r * Math.sin(a1)
|
|
64
|
+
};
|
|
65
|
+
result.push({
|
|
66
|
+
start: p0,
|
|
67
|
+
c1: { x: p0.x - r * k * Math.sin(a0), y: p0.y + r * k * Math.cos(a0) },
|
|
68
|
+
c2: { x: p1.x + r * k * Math.sin(a1), y: p1.y - r * k * Math.cos(a1) },
|
|
69
|
+
end: p1
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
};
|
|
74
|
+
var vExtent = (rings, v) => {
|
|
75
|
+
let min = Infinity;
|
|
76
|
+
let max = -Infinity;
|
|
77
|
+
for (const ring of rings) {
|
|
78
|
+
for (const p of ring) {
|
|
79
|
+
const dv = p.x * v.x + p.y * v.y;
|
|
80
|
+
if (dv < min) min = dv;
|
|
81
|
+
if (dv > max) max = dv;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Number.isFinite(min) ? { min, max } : null;
|
|
85
|
+
};
|
|
86
|
+
var scanlineCrossings = (rings, u, v, off) => {
|
|
87
|
+
const crossings = [];
|
|
88
|
+
for (const ring of rings) {
|
|
89
|
+
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
90
|
+
const a = ring[j];
|
|
91
|
+
const b = ring[i];
|
|
92
|
+
const va = a.x * v.x + a.y * v.y;
|
|
93
|
+
const vb = b.x * v.x + b.y * v.y;
|
|
94
|
+
if (va < off === vb < off) continue;
|
|
95
|
+
const t = (off - va) / (vb - va);
|
|
96
|
+
const px = a.x + (b.x - a.x) * t;
|
|
97
|
+
const py = a.y + (b.y - a.y) * t;
|
|
98
|
+
crossings.push(px * u.x + py * u.y);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
crossings.sort((x, y) => x - y);
|
|
102
|
+
return crossings;
|
|
103
|
+
};
|
|
104
|
+
var computeHatchLines = (rings, angle2, spacing) => spacing <= 0 ? [] : computeHatchFamily(rings, {
|
|
105
|
+
angle: angle2,
|
|
106
|
+
origin: { x: 0, y: 0 },
|
|
107
|
+
deltaAlong: 0,
|
|
108
|
+
deltaPerp: spacing
|
|
109
|
+
});
|
|
110
|
+
var DOT_LENGTH_MM = 0.35;
|
|
111
|
+
var splitByDashes = (a, b, u, dashes, along0, out) => {
|
|
112
|
+
const len3 = (b.x - a.x) * u.x + (b.y - a.y) * u.y;
|
|
113
|
+
if (len3 <= 1e-9) return;
|
|
114
|
+
const cycle = dashes.reduce((s, d) => s + Math.abs(d), 0);
|
|
115
|
+
if (cycle <= 1e-9) {
|
|
116
|
+
out.push({ a, b });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const pt = (d) => ({ x: a.x + u.x * d, y: a.y + u.y * d });
|
|
120
|
+
const base = a.x * u.x + a.y * u.y - along0;
|
|
121
|
+
let phase = (base % cycle + cycle) % cycle;
|
|
122
|
+
let idx = 0;
|
|
123
|
+
for (; idx < dashes.length; idx++) {
|
|
124
|
+
const w = Math.abs(dashes[idx]);
|
|
125
|
+
if (phase < w || w <= 1e-9) break;
|
|
126
|
+
phase -= w;
|
|
127
|
+
}
|
|
128
|
+
if (idx >= dashes.length) {
|
|
129
|
+
idx = 0;
|
|
130
|
+
phase = 0;
|
|
131
|
+
}
|
|
132
|
+
let remaining = Math.max(0, Math.abs(dashes[idx]) - phase);
|
|
133
|
+
let pos = 0;
|
|
134
|
+
let guard = 0;
|
|
135
|
+
while (pos < len3 - 1e-9 && guard++ < 1e5) {
|
|
136
|
+
const w = Math.abs(dashes[idx]);
|
|
137
|
+
const draw = dashes[idx] >= 0;
|
|
138
|
+
if (w <= 1e-9) {
|
|
139
|
+
if (draw) {
|
|
140
|
+
const s0 = Math.max(0, pos - DOT_LENGTH_MM / 2);
|
|
141
|
+
const s1 = Math.min(len3, pos + DOT_LENGTH_MM / 2);
|
|
142
|
+
if (s1 > s0) out.push({ a: pt(s0), b: pt(s1) });
|
|
143
|
+
}
|
|
144
|
+
idx = (idx + 1) % dashes.length;
|
|
145
|
+
remaining = Math.abs(dashes[idx]);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const step = Math.min(remaining, len3 - pos);
|
|
149
|
+
if (draw) out.push({ a: pt(pos), b: pt(pos + step) });
|
|
150
|
+
pos += step;
|
|
151
|
+
remaining -= step;
|
|
152
|
+
if (remaining <= 1e-9) {
|
|
153
|
+
idx = (idx + 1) % dashes.length;
|
|
154
|
+
remaining = Math.abs(dashes[idx]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var computeHatchFamily = (rings, family) => {
|
|
159
|
+
const { deltaPerp } = family;
|
|
160
|
+
if (rings.length === 0 || Math.abs(deltaPerp) <= 1e-9) return [];
|
|
161
|
+
const u = { x: Math.cos(family.angle), y: Math.sin(family.angle) };
|
|
162
|
+
const v = { x: -u.y, y: u.x };
|
|
163
|
+
const ext = vExtent(rings, v);
|
|
164
|
+
if (!ext) return [];
|
|
165
|
+
const oV = family.origin.x * v.x + family.origin.y * v.y;
|
|
166
|
+
const oU = family.origin.x * u.x + family.origin.y * u.y;
|
|
167
|
+
const iA = (ext.min - oV) / deltaPerp;
|
|
168
|
+
const iB = (ext.max - oV) / deltaPerp;
|
|
169
|
+
const iLo = Math.ceil(Math.min(iA, iB));
|
|
170
|
+
const iHi = Math.floor(Math.max(iA, iB));
|
|
171
|
+
const dashes = family.dashesMm && family.dashesMm.length ? family.dashesMm : null;
|
|
172
|
+
const out = [];
|
|
173
|
+
for (let i = iLo; i <= iHi; i++) {
|
|
174
|
+
const off = oV + i * deltaPerp;
|
|
175
|
+
const along0 = oU + i * family.deltaAlong;
|
|
176
|
+
const crossings = scanlineCrossings(rings, u, v, off);
|
|
177
|
+
for (let k = 0; k + 1 < crossings.length; k += 2) {
|
|
178
|
+
const c0 = crossings[k];
|
|
179
|
+
const c1 = crossings[k + 1];
|
|
180
|
+
if (c1 - c0 < 1e-9) continue;
|
|
181
|
+
const a = { x: u.x * c0 + v.x * off, y: u.y * c0 + v.y * off };
|
|
182
|
+
const b = { x: u.x * c1 + v.x * off, y: u.y * c1 + v.y * off };
|
|
183
|
+
if (dashes) splitByDashes(a, b, u, dashes, along0, out);
|
|
184
|
+
else out.push({ a, b });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
};
|
|
189
|
+
var ellipseArcToBeziers = (center, rx, ry, rotation, startAngle, sweep) => {
|
|
190
|
+
const cosR = Math.cos(rotation);
|
|
191
|
+
const sinR = Math.sin(rotation);
|
|
192
|
+
const map = (p) => ({
|
|
193
|
+
x: center.x + p.x * cosR - p.y * sinR,
|
|
194
|
+
y: center.y + p.x * sinR + p.y * cosR
|
|
195
|
+
});
|
|
196
|
+
return arcToBeziers({ x: 0, y: 0 }, 1, startAngle, sweep).map((b) => ({
|
|
197
|
+
start: map({ x: b.start.x * rx, y: b.start.y * ry }),
|
|
198
|
+
c1: map({ x: b.c1.x * rx, y: b.c1.y * ry }),
|
|
199
|
+
c2: map({ x: b.c2.x * rx, y: b.c2.y * ry }),
|
|
200
|
+
end: map({ x: b.end.x * rx, y: b.end.y * ry })
|
|
201
|
+
}));
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// ../core/src/model/builtinPat.ts
|
|
205
|
+
var BUILTIN_PAT = `;; Linea built-in hatch pattern library.
|
|
206
|
+
;;
|
|
207
|
+
;; Format: .pat syntax - a \`*NAME,description\` header followed by one line
|
|
208
|
+
;; family per row: \`angle, x-origin, y-origin, delta-x, delta-y [, dash...]\`
|
|
209
|
+
;; (angle in degrees CCW; delta-x shifts successive lines along their own
|
|
210
|
+
;; direction - dash phase - and delta-y is the perpendicular spacing;
|
|
211
|
+
;; dashes: >0 pen-down, <0 gap, 0 dot). All lengths are millimeters (ISO
|
|
212
|
+
;; scaling).
|
|
213
|
+
;;
|
|
214
|
+
;; The pattern geometry is functional interchange data, kept name- and
|
|
215
|
+
;; value-compatible with the predefined DXF HATCH patterns other CAD
|
|
216
|
+
;; applications resolve - ANSI/ISO/JIS/GOST section conventions plus common
|
|
217
|
+
;; architectural textures. Descriptions and organization are Linea's
|
|
218
|
+
;; own. There is no SOLID entry: solid fill is its own fill kind, not a
|
|
219
|
+
;; line-family pattern.
|
|
220
|
+
;;
|
|
221
|
+
;; After editing, regenerate the embedded TS mirror:
|
|
222
|
+
;; npm run gen:patterns -w @lineadraw/core
|
|
223
|
+
;;
|
|
224
|
+
|
|
225
|
+
;; Material and texture patterns.
|
|
226
|
+
|
|
227
|
+
*ANGLE,Steel angle framing
|
|
228
|
+
0, 0, 0, 0, 6.985, 5.08, -1.905
|
|
229
|
+
90, 0, 0, 0, 6.985, 5.08, -1.905
|
|
230
|
+
*ANSI31,Cast iron; general section (ANSI)
|
|
231
|
+
45, 0, 0, 0, 3.175
|
|
232
|
+
*ANSI32,Steel (ANSI)
|
|
233
|
+
45, 0, 0, 0, 9.525
|
|
234
|
+
45, 4.49013, 0, 0, 9.525
|
|
235
|
+
*ANSI33,Bronze, brass, copper (ANSI)
|
|
236
|
+
45, 0, 0, 0, 6.35
|
|
237
|
+
45, 4.49013, 0, 0, 6.35, 3.175, -1.5875
|
|
238
|
+
*ANSI34,Plastic, rubber (ANSI)
|
|
239
|
+
45, 0, 0, 0, 19.05
|
|
240
|
+
45, 4.49013, 0, 0, 19.05
|
|
241
|
+
45, 8.98026, 0, 0, 19.05
|
|
242
|
+
45, 13.4704, 0, 0, 19.05
|
|
243
|
+
*ANSI35,Fire brick, refractory (ANSI)
|
|
244
|
+
45, 0, 0, 0, 6.35
|
|
245
|
+
45, 4.49013, 0, 0, 6.35, 7.9375, -1.5875, 0, -1.5875
|
|
246
|
+
*ANSI36,Marble, slate, glass (ANSI)
|
|
247
|
+
45, 0, 0, 5.55625, 3.175, 7.9375, -1.5875, 0, -1.5875
|
|
248
|
+
*ANSI37,Lead, zinc, insulation (ANSI)
|
|
249
|
+
45, 0, 0, 0, 3.175
|
|
250
|
+
135, 0, 0, 0, 3.175
|
|
251
|
+
*ANSI38,Aluminum (ANSI)
|
|
252
|
+
45, 0, 0, 0, 3.175
|
|
253
|
+
135, 0, 0, 6.35, 3.175, 7.9375, -4.7625
|
|
254
|
+
*AR-B816,Block wall 8x16, running bond
|
|
255
|
+
0, 0, 0, 0, 203.2
|
|
256
|
+
90, 0, 0, 203.2, 203.2, 203.2, -203.2
|
|
257
|
+
*AR-B816C,Block wall 8x16 with mortar joints
|
|
258
|
+
0, 0, 0, 203.2, 203.2, 396.875, -9.525
|
|
259
|
+
0, -203.2, 9.525, 203.2, 203.2, 396.875, -9.525
|
|
260
|
+
90, 0, 0, 203.2, 203.2, -212.725, 193.675
|
|
261
|
+
90, -9.525, 0, 203.2, 203.2, -212.725, 193.675
|
|
262
|
+
*AR-B88,Block wall 8x8, running bond
|
|
263
|
+
0, 0, 0, 0, 203.2
|
|
264
|
+
90, 0, 0, 203.2, 101.6, 203.2, -203.2
|
|
265
|
+
*AR-BRELM,Brick wall, English bond, mortar joints
|
|
266
|
+
0, 0, 0, 0, 135.484, 193.675, -9.525
|
|
267
|
+
0, 0, 57.15, 0, 135.484, 193.675, -9.525
|
|
268
|
+
0, 50.8, 67.7418, 0, 135.484, 92.075, -9.525
|
|
269
|
+
0, 50.8, 124.892, 0, 135.484, 92.075, -9.525
|
|
270
|
+
90, 0, 0, 0, 203.2, 57.15, -78.334
|
|
271
|
+
90, -9.525, 0, 0, 203.2, 57.15, -78.334
|
|
272
|
+
90, 50.8, 67.7418, 0, 101.6, 57.15, -78.334
|
|
273
|
+
90, 41.275, 67.7418, 0, 101.6, 57.15, -78.334
|
|
274
|
+
*AR-BRSTD,Brick wall, running bond
|
|
275
|
+
0, 0, 0, 0, 67.7418
|
|
276
|
+
90, 0, 0, 67.7418, 101.6, 67.7418, -67.7418
|
|
277
|
+
*AR-CONC,Concrete, random aggregate
|
|
278
|
+
50, 0, 0, 104.896, -149.807, 19.05, -209.55
|
|
279
|
+
355, 0, 0, -51.76101082,187.25814969, 15.24, -167.64058417
|
|
280
|
+
100.4514447,15.182007,-1.3282535,145.5569059,-176.270089,16.1900088,-178.0902446
|
|
281
|
+
46.1842, 0, 50.8, 157.343, -224.71, 28.575, -314.325
|
|
282
|
+
96.63555761,22.5899,47.2965,218.33577212,-264.40480444,24.28502314,-267.13560816
|
|
283
|
+
351.18415117,0,50.8,196.67912063,280.88740361,22.85996707,-251.45973192
|
|
284
|
+
21, 25.4, 38.1, 104.89565868, -149.80652586, 19.05, -209.55
|
|
285
|
+
326, 25.4, 38.1, -51.7604, 187.258, 15.24, -167.64
|
|
286
|
+
71.451445,38.0345326,29.5779001,145.5567546,-176.2700748,16.1900088,-178.0899376
|
|
287
|
+
37.5, 0, 0, 53.9242, 65.2018, 0, -165.608, 0, -170.18, 0, -168.275
|
|
288
|
+
7.5, 0, 0, 79.3242, 90.6018, 0, -97.028, 0, -161.798, 0, -64.135
|
|
289
|
+
-32.5, -56.642, 0, 117.434, 68.0212, 0, -63.5, 0, -198.12, 0, -262.89
|
|
290
|
+
-42.5, -82.042, 0, 92.0344, 118.821, 0, -82.55, 0, -131.572, 0, -186.69
|
|
291
|
+
*AR-HBONE,Brick paving, herringbone at 45 deg
|
|
292
|
+
45, 0, 0, 101.6, 101.6, 304.8, -101.6
|
|
293
|
+
135, 71.842, 71.842, 101.6, -101.6, 304.8, -101.6
|
|
294
|
+
*AR-PARQ1,Parquet flooring, basket weave
|
|
295
|
+
90, 0, 0, 304.8, 304.8, 304.8, -304.8
|
|
296
|
+
90, 50.8, 0, 304.8, 304.8, 304.8, -304.8
|
|
297
|
+
90, 101.6, 0, 304.8, 304.8, 304.8, -304.8
|
|
298
|
+
90, 152.4, 0, 304.8, 304.8, 304.8, -304.8
|
|
299
|
+
90, 203.2, 0, 304.8, 304.8, 304.8, -304.8
|
|
300
|
+
90, 254, 0, 304.8, 304.8, 304.8, -304.8
|
|
301
|
+
90, 304.8, 0, 304.8, 304.8, 304.8, -304.8
|
|
302
|
+
0, 0, 304.8, 304.8, -304.8, 304.8, -304.8
|
|
303
|
+
0, 0, 355.6, 304.8, -304.8, 304.8, -304.8
|
|
304
|
+
0, 0, 406.4, 304.8, -304.8, 304.8, -304.8
|
|
305
|
+
0, 0, 457.2, 304.8, -304.8, 304.8, -304.8
|
|
306
|
+
0, 0, 508, 304.8, -304.8, 304.8, -304.8
|
|
307
|
+
0, 0, 558.8, 304.8, -304.8, 304.8, -304.8
|
|
308
|
+
0, 0, 609.6, 304.8, -304.8, 304.8, -304.8
|
|
309
|
+
*AR-RROOF,Roof shingles
|
|
310
|
+
0, 0, 0, 55.88, 25.4, 381, -50.8, 127, -25.4
|
|
311
|
+
0, 33.782, 12.7, -25.4, 33.782, 76.2, -8.382, 152.4, -19.05
|
|
312
|
+
0, 12.7, 21.59, 132.08, 17.018, 203.2, -35.56, 101.6, -25.4
|
|
313
|
+
*AR-RSHKE,Roof wood shakes
|
|
314
|
+
0, 0, 0, 647.7, 304.8, 152.4, -127, 177.8, -76.2, 228.6, -101.6
|
|
315
|
+
0, 152.4, 12.7, 647.7, 304.8, 127, -482.6, 101.6, -152.4
|
|
316
|
+
0, 457.2, -19.05, 647.7, 304.8, 76.2, -787.4
|
|
317
|
+
90, 0, 0, 304.8, 215.9, 292.1, -927.1
|
|
318
|
+
90, 152.4, 0, 304.8, 215.9, 285.75, -933.45
|
|
319
|
+
90, 279.4, 0, 304.8, 215.9, 266.7, -952.5
|
|
320
|
+
90, 457.2, -19.05, 304.8, 215.9, 292.1, -927.1
|
|
321
|
+
90, 533.4, -19.05, 304.8, 215.9, 292.1, -927.1
|
|
322
|
+
90, 762, 0, 304.8, 215.9, 279.4, -939.8
|
|
323
|
+
*AR-SAND,Sand stipple
|
|
324
|
+
37.5, 0, 0, 28.5242, 39.8018, 0, -38.608, 0, -43.18, 0, -41.275
|
|
325
|
+
7.5, 0, 0, 53.9242, 65.2018, 0, -20.828, 0, -34.798, 0, -13.335
|
|
326
|
+
-32.5, -31.242, 0, 66.6344, 42.6212, 0, -12.7, 0, -45.72, 0, -59.69
|
|
327
|
+
-42.5, -31.242, 0, 41.2344, 68.0212, 0, -6.35, 0, -29.972, 0, -34.29
|
|
328
|
+
*BOX,Interlocking box weave
|
|
329
|
+
90, 0, 0, 0, 25.4
|
|
330
|
+
90, 6.35, 0, 0, 25.4
|
|
331
|
+
0, 0, 0, 0, 25.4, -6.35, 6.35
|
|
332
|
+
0, 0, 6.35, 0, 25.4, -6.35, 6.35
|
|
333
|
+
0, 0, 12.7, 0, 25.4, 6.35, -6.35
|
|
334
|
+
0, 0, 19.05, 0, 25.4, 6.35, -6.35
|
|
335
|
+
90, 12.7, 0, 0, 25.4, 6.35, -6.35
|
|
336
|
+
90, 19.05, 0, 0, 25.4, 6.35, -6.35
|
|
337
|
+
*BRASS,Brass
|
|
338
|
+
0, 0, 0, 0, 6.35
|
|
339
|
+
0, 0, 3.175, 0, 6.35, 3.175, -1.5875
|
|
340
|
+
*BRICK,Brick coursing
|
|
341
|
+
0, 0, 0, 0, 6.35
|
|
342
|
+
90, 0, 0, 0, 12.7, 6.35, -6.35
|
|
343
|
+
90, 6.35, 0, 0, 12.7, -6.35, 6.35
|
|
344
|
+
*BRSTONE,Brick and stone mix
|
|
345
|
+
0, 0, 0, 0, 8.382
|
|
346
|
+
90, 22.86, 0, 8.382, 12.7, 8.382, -8.382
|
|
347
|
+
90, 20.32, 0, 8.382, 12.7, 8.382, -8.382
|
|
348
|
+
0, 22.86, 1.397, 12.7, 8.382, -22.86, 2.54
|
|
349
|
+
0, 22.86, 2.794, 12.7, 8.382, -22.86, 2.54
|
|
350
|
+
0, 22.86, 4.191, 12.7, 8.382, -22.86, 2.54
|
|
351
|
+
0, 22.86, 5.588, 12.7, 8.382, -22.86, 2.54
|
|
352
|
+
0, 22.86, 6.985, 12.7, 8.382, -22.86, 2.54
|
|
353
|
+
*CLAY,Clay
|
|
354
|
+
0, 0, 0, 0, 4.7625
|
|
355
|
+
0, 0, 0.79375, 0, 4.7625
|
|
356
|
+
0, 0, 1.5875, 0, 4.7625
|
|
357
|
+
0, 0, 3.175, 0, 4.7625, 4.7625, -3.175
|
|
358
|
+
*CORK,Cork
|
|
359
|
+
0, 0, 0, 0, 3.175
|
|
360
|
+
135, 1.5875, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
361
|
+
135, 2.38125, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
362
|
+
135, 3.175, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
363
|
+
*CROSS,Cross tiling
|
|
364
|
+
0, 0, 0, 6.35, 6.35, 3.175, -9.525
|
|
365
|
+
90, 1.5875, -1.5875, 6.35, 6.35, 3.175, -9.525
|
|
366
|
+
*DASH,Staggered dashes
|
|
367
|
+
0, 0, 0, 3.175, 3.175, 3.175, -3.175
|
|
368
|
+
*DOLMIT,Layered rock (dolomite)
|
|
369
|
+
0, 0, 0, 0, 6.35
|
|
370
|
+
45, 0, 0, 0, 17.9605,8.98025612106915355989072339,-17.9605122421383071197814467
|
|
371
|
+
*DOTS,Dot screen
|
|
372
|
+
0, 0, 0, 0.79375, 1.5875, 0, -1.5875
|
|
373
|
+
*EARTH,Earth (section)
|
|
374
|
+
0, 0, 0, 6.35, 6.35, 6.35, -6.35
|
|
375
|
+
0, 0, 2.38125, 6.35, 6.35, 6.35, -6.35
|
|
376
|
+
0, 0, 4.7625, 6.35, 6.35, 6.35, -6.35
|
|
377
|
+
90, 0.79375, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
378
|
+
90, 3.175, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
379
|
+
90, 5.55625, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
380
|
+
*ESCHER,Isometric cube tiling
|
|
381
|
+
60, 0, 0, -15.24, 26.3964542936, 27.94, -2.54
|
|
382
|
+
180, 0, 0, -15.24, 26.3964542936, 27.94, -2.54
|
|
383
|
+
300, 0, 0, 15.24, 26.3964542936, 27.94, -2.54
|
|
384
|
+
60, 2.54, 0, -15.24, 26.3964542936, 5.08, -25.4
|
|
385
|
+
300, 2.54, 0, 15.24, 26.3964542936, 5.08, -25.4
|
|
386
|
+
60, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
387
|
+
180, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
388
|
+
300, -1.27, -2.199704516, 15.24, 26.3964542936, 5.08, -25.4
|
|
389
|
+
180, -1.27, -2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
390
|
+
60, -10.16, 0, -15.24, 26.3964542936, 5.08, -25.4
|
|
391
|
+
300, -10.16, 0, 15.24, 26.3964542936, 5.08, -25.4
|
|
392
|
+
60, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
393
|
+
180, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
394
|
+
300, 5.08, 8.7988180894, 15.24, 26.3964542936, 5.08, -25.4
|
|
395
|
+
180, 5.08, 8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
396
|
+
0, 5.08, 4.3994090574, -15.24, 26.3964542936, 17.78, -12.7
|
|
397
|
+
0, 5.08, -4.3994090574, -15.24, 26.3964542936, 17.78, -12.7
|
|
398
|
+
120, 1.27, 6.5991135734, 15.24, 26.3964542936, 17.78, -12.7
|
|
399
|
+
120, -6.35, 2.199704516, 15.24, 26.3964542936, 17.78, -12.7
|
|
400
|
+
240, -6.35, -2.199704516, 15.24, 26.3964542936, 17.78, -12.7
|
|
401
|
+
240, 1.27, -6.5991135734, 15.24, 26.3964542936, 17.78, -12.7
|
|
402
|
+
*FLEX,Flexible material
|
|
403
|
+
0, 0, 0, 0, 6.35, 6.35, -6.35
|
|
404
|
+
45,6.35,0,4.490128053,4.490128053,1.5875,-5.8052561314,1.5875,-8.9802561314
|
|
405
|
+
*GOST_GLASS,Glass (GOST)
|
|
406
|
+
45, 0, 0, 6, -6, 5, -7
|
|
407
|
+
45, 2.121320, 0, 6, -6, 2, -10
|
|
408
|
+
45, 0, 2.121320, 6, -6, 2, -10
|
|
409
|
+
*GOST_GROUND,Ground (GOST)
|
|
410
|
+
45, 0, 0, 10, -10, 20
|
|
411
|
+
45, 3, 0, 10, -10, 20
|
|
412
|
+
45, 6, 0, 10, -10, 20
|
|
413
|
+
*GOST_WOOD,Wood (GOST)
|
|
414
|
+
90, 0, 0, 0, -6, 10, -2
|
|
415
|
+
90, 2, -2, 0, -6, 6, -1.5, 3, -1.5
|
|
416
|
+
90, 4, -5, 0, -6, 10, -2
|
|
417
|
+
*GRASS,Grass
|
|
418
|
+
90, 0, 0, 17.96051224, 17.96051224, 4.7625, -31.15852448
|
|
419
|
+
45, 0, 0, 0, 25.4, 4.7625, -20.6375
|
|
420
|
+
135, 0, 0, 0, 25.4, 4.7625, -20.6375
|
|
421
|
+
*GRATE,Grating
|
|
422
|
+
0, 0, 0, 0, 0.79375
|
|
423
|
+
90, 0, 0, 0, 3.175
|
|
424
|
+
*GRAVEL,Gravel, random cobbles
|
|
425
|
+
228.0127875,18.288,25.4,305.85067529778,1.88796713245,3.4172144,-338.30483639565
|
|
426
|
+
184.969741,16.002,22.86,-305.8545235377,1.10019612724,5.8640472,-580.54048893524
|
|
427
|
+
132.5104471,10.16,22.352,-377.59492241548,1.56030959675,4.1348152,-409.347227941
|
|
428
|
+
267.273689,.254,16.002,-508.63316875916,1.20815479432,5.3400452,-528.66437425738
|
|
429
|
+
292.83365418,0.0,10.668,-330.19770134945,1.23208097566,5.236337,-518.39807745344
|
|
430
|
+
357.273689,2.032,5.842,-508.63316875916,1.20815479432,5.3400452,-528.66437425738
|
|
431
|
+
37.69424047,7.366,5.588,-416.58997273292,.91357450169,7.0619366,-699.13115314247
|
|
432
|
+
72.25532837,12.954,9.906,586.40373773403,.96766293399,6.6671952,-660.05256601905
|
|
433
|
+
121.42956562,14.986,16.256,387.71230339293,1.2040754753,5.35813,-530.45545698712
|
|
434
|
+
175.2363583,12.192,20.828,-280.5442400419,2.10935518695,6.1171328,-299.7393695
|
|
435
|
+
222.3974378,6.096,21.336,413.48123885686,.81554484621,7.9107792,-783.16772512177
|
|
436
|
+
138.81407483,25.4,15.748,234.164238558,2.38943100688,2.7000454,-267.30565824344
|
|
437
|
+
171.4692344,23.368,17.526,-334.082478726,1.25594916784,5.1368198,-508.5463899704
|
|
438
|
+
225.00000,18.288,18.288,17.96051224214,17.96051224214,3.5920934,-32.32893108428
|
|
439
|
+
203.19859051,16.51,21.336,-136.74251918,3.33518339548,1.9344132,-191.50622368894
|
|
440
|
+
291.80140949,14.732,20.574,-80.18324702488,4.71666158921,2.7356562,-134.0475299
|
|
441
|
+
30.96375653,15.748,18.034,91.47734531502,4.35606406258,4.4431966,-143.6629815291
|
|
442
|
+
161.56505118,19.558,20.32,-56.2252967978,8.03218525675,3.2128714,-77.10898116828
|
|
443
|
+
16.389540334,0.0,20.574,265.17991128726,1.43340492604,4.50088,-445.58826672539
|
|
444
|
+
70.34617594,4.318,21.844,-297.29446803469,1.70858889651,3.7759894,-373.822156782
|
|
445
|
+
293.19859051,19.558,25.4,-136.7425191801,3.33518339548,3.868801,-189.57183588894
|
|
446
|
+
343.61045967,21.082,21.844,-265.17991128725,1.433404926,4.50088,-445.5882667254
|
|
447
|
+
339.44395478,0.0,4.826,-136.75087638398,2.97284513779,4.340352,-212.67734313106
|
|
448
|
+
294.7751406,4.064,3.302,-306.90424056705,1.77401295215,3.6367212,-360.0359338072
|
|
449
|
+
66.80140949,19.812,0.0,136.74251918012,3.33518339452,3.868801,-189.57183588894
|
|
450
|
+
17.35402464,21.336,3.556,-345.47402804977,1.51523696536,4.2578274,-421.523759802
|
|
451
|
+
69.44395478,7.366,0.0,-136.75087638396,2.97284513874,2.170176,-214.84751913106
|
|
452
|
+
101.309932474,18.288,0.0,104.60834648271,4.98134983255,1.295146,-128.21994964526
|
|
453
|
+
165.963756532,18.034,1.27,-80.085263387,6.16040487582,5.236337,-99.49054589069
|
|
454
|
+
186.00900596,12.954,2.54,-255.26337856879,1.32949676118,4.85267,-480.41364863337
|
|
455
|
+
303.69006753,15.748,15.748,-56.35753993648,7.0446924921,3.6632388,-87.9177635968
|
|
456
|
+
353.15722659,17.78,12.7,434.77679606606,1.0087628707,6.3955676,-633.16009065031
|
|
457
|
+
60.9453959,24.13,11.938,-204.76648550216,2.46706609031,2.6150824,-258.8939231811
|
|
458
|
+
90.0000000,25.4,14.224,25.4,25.4,1.524,-23.876
|
|
459
|
+
120.25643716,12.446,3.302,-204.77318477297,1.8283320086,3.5286696,-349.339407732
|
|
460
|
+
48.01278750,10.668,6.35,305.85067529778,1.88796713138,6.8344288,-334.88762199565
|
|
461
|
+
0.000000000,15.24,11.43,25.4,25.4,6.604,-18.796
|
|
462
|
+
325.3048465,21.844,11.43,310.04235091354,-1.6064370526,4.0160956,-397.5931672414
|
|
463
|
+
254.0546041,25.146,9.144,104.6687497289,3.48895832444,3.6982908,-181.21650038772
|
|
464
|
+
207.64597536,24.13,5.588,545.36007557253,1.07143433066,6.021451,-596.12464422938
|
|
465
|
+
175.42607874,18.796,2.794,331.1739336186,1.01276432357,6.3702946,-630.6584645624
|
|
466
|
+
*HEX,Hexagonal mesh
|
|
467
|
+
0, 0, 0, 0, 5.4992613154, 3.175, -6.35
|
|
468
|
+
120, 0, 0, 0, 5.4992613154, 3.175, -6.35
|
|
469
|
+
60, 3.175, 0, 0, 5.4992613154, 3.175, -6.35
|
|
470
|
+
*HONEY,Honeycomb
|
|
471
|
+
0, 0, 0, 4.7625, 2.749630645, 3.175, -6.35
|
|
472
|
+
120, 0, 0, 4.7625, 2.749630645, 3.175, -6.35
|
|
473
|
+
60, 0, 0, 4.7625, 2.749630645, -6.35, 3.175
|
|
474
|
+
*HOUND,Houndstooth
|
|
475
|
+
0, 0, 0, 6.35, 1.5875, 25.4, -12.7
|
|
476
|
+
90, 0, 0, -6.35, 1.5875, 25.4, -12.7
|
|
477
|
+
*INSUL,Insulation batt
|
|
478
|
+
0, 0, 0, 0, 9.525
|
|
479
|
+
0, 0, 3.175, 0, 9.525, 3.175, -3.175
|
|
480
|
+
0, 0, 6.35, 0, 9.525, 3.175, -3.175
|
|
481
|
+
*LINE,Horizontal lines
|
|
482
|
+
0, 0, 0, 0, 3.175
|
|
483
|
+
*MUDST,Mud / sand (geological)
|
|
484
|
+
0, 0, 0, 12.7, 6.35, 6.35, -6.35, 0, -6.35, 0, -6.35
|
|
485
|
+
*NET,Square grid
|
|
486
|
+
0, 0, 0, 0, 3.175
|
|
487
|
+
90, 0, 0, 0, 3.175
|
|
488
|
+
*NET3,Triangular grid
|
|
489
|
+
0, 0, 0, 0, 3.175
|
|
490
|
+
60, 0, 0, 0, 3.175
|
|
491
|
+
120, 0, 0, 0, 3.175
|
|
492
|
+
*PLAST,Plastic
|
|
493
|
+
0, 0, 0, 0, 6.35
|
|
494
|
+
0, 0, 0.79375, 0, 6.35
|
|
495
|
+
0, 0, 1.5875, 0, 6.35
|
|
496
|
+
*PLASTI,Plastic, dense
|
|
497
|
+
0, 0, 0, 0, 6.35
|
|
498
|
+
0, 0, 0.79375, 0, 6.35
|
|
499
|
+
0, 0, 1.5875, 0, 6.35
|
|
500
|
+
0, 0, 3.96875, 0, 6.35
|
|
501
|
+
*SACNCR,Concrete, dotted diagonal
|
|
502
|
+
45, 0, 0, 0, 2.38125
|
|
503
|
+
45, 1.6838, 0, 0, 2.38125, 0, -2.38125
|
|
504
|
+
*SQUARE,Dashed square lattice
|
|
505
|
+
0, 0, 0, 0, 3.175, 3.175, -3.175
|
|
506
|
+
90, 0, 0, 0, 3.175, 3.175, -3.175
|
|
507
|
+
*STARS,Six-pointed star lattice
|
|
508
|
+
0, 0, 0, 0, 5.4992613154, 3.175, -3.175
|
|
509
|
+
60, 0, 0, 0, 5.4992613154, 3.175, -3.175
|
|
510
|
+
120, 1.5875, 2.7496306704, 0, 5.4992613154, 3.175, -3.175
|
|
511
|
+
*STEEL,Steel, paired lines
|
|
512
|
+
45, 0, 0, 0, 3.175
|
|
513
|
+
45, 0, 1.5875, 0, 3.175
|
|
514
|
+
*SWAMP,Swamp / marsh
|
|
515
|
+
0, 0, 0, 12.7, 21.9970452362, 3.175, -22.225
|
|
516
|
+
90, 1.5875, 0, 21.9970452362, 12.7, 1.5875, -42.4065904724
|
|
517
|
+
90, 1.984375, 0, 21.9970452362, 12.7, 1.27, -42.7240904724
|
|
518
|
+
90, 1.190625, 0, 21.9970452362, 12.7, 1.27, -42.7240904724
|
|
519
|
+
60, 2.38125, 0, 12.7, 21.9970452362, 1.016, -24.384
|
|
520
|
+
120, 0.79375, 0, 12.7, 21.9970452362, 1.016, -24.384
|
|
521
|
+
*TRANS,Heat-transfer surface
|
|
522
|
+
0, 0, 0, 0, 6.35
|
|
523
|
+
0, 0, 3.175, 0, 6.35, 3.175, -3.175
|
|
524
|
+
*TRIANG,Triangle tiling
|
|
525
|
+
60, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
526
|
+
120, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
527
|
+
0, -2.38125, 4.1244459802, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
528
|
+
*ZIGZAG,Stair-step zigzag
|
|
529
|
+
0, 0, 0, 3.175, 3.175, 3.175, -3.175
|
|
530
|
+
90, 3.175, 0, 3.175, 3.175, 3.175, -3.175
|
|
531
|
+
|
|
532
|
+
;; Hatch companions to the ISO 128 line types (1 mm pen base).
|
|
533
|
+
|
|
534
|
+
*ACAD_ISO02W100,ISO dashed
|
|
535
|
+
0, 0,0, 0,5, 12,-3
|
|
536
|
+
*ACAD_ISO03W100,ISO dashed, wide gaps
|
|
537
|
+
0, 0,0, 0,5, 12,-18
|
|
538
|
+
*ACAD_ISO04W100,ISO long-dash dot
|
|
539
|
+
0, 0,0, 0,5, 24,-3,.5,-3
|
|
540
|
+
*ACAD_ISO05W100,ISO long-dash double-dot
|
|
541
|
+
0, 0,0, 0,5, 24,-3,.5,-3,.5,-3
|
|
542
|
+
*ACAD_ISO06W100,ISO long-dash triple-dot
|
|
543
|
+
0, 0,0, 0,5, 24,-3,.5,-3,.5,-6.5
|
|
544
|
+
0, 0,0, 0,5, -34,.5,-3
|
|
545
|
+
*ACAD_ISO07W100,ISO dotted
|
|
546
|
+
0, 0,0, 0,5, .5,-3
|
|
547
|
+
*ACAD_ISO08W100,ISO long-dash short-dash
|
|
548
|
+
0, 0,0, 0,5, 24,-3,6,-3
|
|
549
|
+
*ACAD_ISO09W100,ISO long-dash double short-dash
|
|
550
|
+
0, 0,0, 0,5, 24,-3,6,-3,6,-3
|
|
551
|
+
*ACAD_ISO10W100,ISO dash dot
|
|
552
|
+
0, 0,0, 0,5, 12,-3,.5,-3
|
|
553
|
+
*ACAD_ISO11W100,ISO double-dash dot
|
|
554
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-3
|
|
555
|
+
*ACAD_ISO12W100,ISO dash double-dot
|
|
556
|
+
0, 0,0, 0,5, 12,-3,.5,-3,.5,-3
|
|
557
|
+
*ACAD_ISO13W100,ISO double-dash double-dot
|
|
558
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-6.5
|
|
559
|
+
0, 0,0, 0,5, -33.5,.5,-3
|
|
560
|
+
*ACAD_ISO14W100,ISO dash triple-dot
|
|
561
|
+
0, 0,0, 0,5, 12,-3,.5,-3,.5,-6.5
|
|
562
|
+
0, 0,0, 0,5, -22,.5,-3
|
|
563
|
+
*ACAD_ISO15W100,ISO double-dash triple-dot
|
|
564
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-10
|
|
565
|
+
0, 0,0, 0,5, -33.5,.5,-3,.5,-3
|
|
566
|
+
|
|
567
|
+
;; JIS A 0150 section patterns.
|
|
568
|
+
|
|
569
|
+
*JIS_LC_20,Lightweight concrete, 20 mm (JIS)
|
|
570
|
+
45,0,0,0,20
|
|
571
|
+
45,.4,0,0,20
|
|
572
|
+
*JIS_LC_20A,Lightweight concrete, 20 mm wide (JIS)
|
|
573
|
+
45,0,0,0,20
|
|
574
|
+
45,1,0,0,20
|
|
575
|
+
*JIS_LC_8,Lightweight concrete, 8 mm (JIS)
|
|
576
|
+
45,0,0,0,7.8
|
|
577
|
+
45,.4,0,0,7.8
|
|
578
|
+
*JIS_LC_8A,Lightweight concrete, 8 mm wide (JIS)
|
|
579
|
+
45,0,0,0,7.8
|
|
580
|
+
45,1,0,0,7.8
|
|
581
|
+
*JIS_RC_10,Reinforced concrete, 10 mm (JIS)
|
|
582
|
+
45,0,0,0,10
|
|
583
|
+
45,.725,0,0,10
|
|
584
|
+
45,1.45,0,0,10
|
|
585
|
+
*JIS_RC_15,Reinforced concrete, 15 mm (JIS)
|
|
586
|
+
45,0,0,0,15
|
|
587
|
+
45,.725,0,0,15
|
|
588
|
+
45,1.45,0,0,15
|
|
589
|
+
*JIS_RC_18,Reinforced concrete, 18 mm (JIS)
|
|
590
|
+
45,0,0,0,18
|
|
591
|
+
45,1,0,0,18
|
|
592
|
+
45,2,0,0,18
|
|
593
|
+
*JIS_RC_30,Reinforced concrete, 30 mm (JIS)
|
|
594
|
+
45,0,0,0,30
|
|
595
|
+
45,1,0,0,30
|
|
596
|
+
45,2,0,0,30
|
|
597
|
+
*JIS_STN_1E,Stone, 1 mm (JIS)
|
|
598
|
+
45, 0, 0, 0, 1
|
|
599
|
+
45, .705, 0, 0,1, 1, -.5
|
|
600
|
+
*JIS_STN_2.5,Stone, 2.5 mm (JIS)
|
|
601
|
+
45, 0, 0, 0, 2.5
|
|
602
|
+
45, 1.765, 0, 0,2.5, 1.2, -.5
|
|
603
|
+
*JIS_WOOD,Wood (JIS)
|
|
604
|
+
45,0,0,0,.70710678
|
|
605
|
+
`;
|
|
606
|
+
|
|
607
|
+
// ../core/src/model/hatchPatterns.ts
|
|
608
|
+
var parsePatternDefinitions = (text, unitScale = 25.4) => {
|
|
609
|
+
const DEG2RAD = Math.PI / 180;
|
|
610
|
+
const patterns = [];
|
|
611
|
+
let current = null;
|
|
612
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
613
|
+
const line = raw.trim();
|
|
614
|
+
if (!line || line.startsWith(";")) continue;
|
|
615
|
+
if (line.startsWith("*")) {
|
|
616
|
+
const [name, ...desc] = line.slice(1).split(",");
|
|
617
|
+
current = { name: name.trim(), lines: [] };
|
|
618
|
+
const d = desc.join(",").trim();
|
|
619
|
+
if (d) current.description = d;
|
|
620
|
+
patterns.push(current);
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
if (!current) continue;
|
|
624
|
+
const n = line.split(",").map((s) => Number(s.trim()));
|
|
625
|
+
if (n.length < 5 || n.some((v) => Number.isNaN(v))) continue;
|
|
626
|
+
const [angle2, x, y, dx, dy, ...dashes] = n;
|
|
627
|
+
current.lines.push({
|
|
628
|
+
angle: angle2 * DEG2RAD,
|
|
629
|
+
origin: { x: x * unitScale, y: y * unitScale },
|
|
630
|
+
deltaX: dx * unitScale,
|
|
631
|
+
deltaY: dy * unitScale,
|
|
632
|
+
dashesMm: dashes.length ? dashes.map((v) => v * unitScale) : void 0
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
return patterns.filter((p) => p.lines.length > 0);
|
|
636
|
+
};
|
|
637
|
+
var BUILT_IN_PATTERNS = parsePatternDefinitions(
|
|
638
|
+
BUILTIN_PAT,
|
|
639
|
+
1
|
|
640
|
+
).filter((p) => p.name.toUpperCase() !== "SOLID");
|
|
641
|
+
var normalizeName = (name) => name.trim().toUpperCase().replace(/[\s.-]+/g, "_");
|
|
642
|
+
var BUILT_IN_BY_NAME = new Map(
|
|
643
|
+
BUILT_IN_PATTERNS.map((p) => [normalizeName(p.name), p])
|
|
644
|
+
);
|
|
645
|
+
var HATCH_PATTERN_NAMES = BUILT_IN_PATTERNS.map(
|
|
646
|
+
(p) => p.name
|
|
647
|
+
);
|
|
648
|
+
var getHatchPattern = (name) => BUILT_IN_BY_NAME.get(normalizeName(name));
|
|
649
|
+
var MAX_HATCH_SEGMENTS = 1e5;
|
|
650
|
+
var estimatePatternSegments = (rings, pattern2, scale3) => {
|
|
651
|
+
if (scale3 <= 0) return 0;
|
|
652
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
653
|
+
for (const ring of rings)
|
|
654
|
+
for (const p of ring) {
|
|
655
|
+
if (p.x < minX) minX = p.x;
|
|
656
|
+
if (p.x > maxX) maxX = p.x;
|
|
657
|
+
if (p.y < minY) minY = p.y;
|
|
658
|
+
if (p.y > maxY) maxY = p.y;
|
|
659
|
+
}
|
|
660
|
+
if (minX > maxX) return 0;
|
|
661
|
+
const diag = Math.hypot(maxX - minX, maxY - minY);
|
|
662
|
+
let count = 0;
|
|
663
|
+
for (const fam of pattern2.lines) {
|
|
664
|
+
const perp2 = Math.abs(fam.deltaY) * scale3;
|
|
665
|
+
if (perp2 <= 1e-9) continue;
|
|
666
|
+
const lines = diag / perp2 + 1;
|
|
667
|
+
const period = (fam.dashesMm?.reduce((a, b) => a + Math.abs(b), 0) ?? 0) * scale3;
|
|
668
|
+
const perLine = period > 1e-9 ? diag / period + 1 : 1;
|
|
669
|
+
count += lines * perLine;
|
|
670
|
+
}
|
|
671
|
+
return count;
|
|
672
|
+
};
|
|
673
|
+
var computePatternGeometry = (rings, pattern2, angle2, scale3, origin = { x: 0, y: 0 }) => {
|
|
674
|
+
const out = [];
|
|
675
|
+
if (scale3 <= 0) return out;
|
|
676
|
+
const c = Math.cos(angle2);
|
|
677
|
+
const s = Math.sin(angle2);
|
|
678
|
+
for (const fam of pattern2.lines) {
|
|
679
|
+
if (Math.abs(fam.deltaY) * scale3 <= 1e-9) continue;
|
|
680
|
+
const ox = fam.origin.x * scale3;
|
|
681
|
+
const oy = fam.origin.y * scale3;
|
|
682
|
+
const segs = computeHatchFamily(rings, {
|
|
683
|
+
angle: angle2 + fam.angle,
|
|
684
|
+
origin: { x: ox * c - oy * s + origin.x, y: ox * s + oy * c + origin.y },
|
|
685
|
+
deltaAlong: fam.deltaX * scale3,
|
|
686
|
+
deltaPerp: fam.deltaY * scale3,
|
|
687
|
+
dashesMm: fam.dashesMm?.map((d) => d * scale3)
|
|
688
|
+
});
|
|
689
|
+
for (const seg of segs) out.push(seg);
|
|
690
|
+
}
|
|
691
|
+
return out;
|
|
692
|
+
};
|
|
693
|
+
var PatternLineSchema = z2.object({
|
|
694
|
+
/** Radians CCW, in the pattern's own frame. */
|
|
695
|
+
angle: z2.number(),
|
|
696
|
+
/** Base point, mm. */
|
|
697
|
+
origin: Vec2Schema,
|
|
698
|
+
/** Shift ALONG the line between successive lines (dash phase), mm. */
|
|
699
|
+
deltaX: z2.number(),
|
|
700
|
+
/** Perpendicular spacing between successive lines, mm. */
|
|
701
|
+
deltaY: z2.number().positive(),
|
|
702
|
+
/** Dash cycle along the line: >0 dash, <0 gap, 0 dot; absent = solid. */
|
|
703
|
+
dashesMm: z2.array(z2.number()).optional()
|
|
704
|
+
});
|
|
705
|
+
var HatchPatternSchema = z2.object({
|
|
706
|
+
/** Stored on fills as `fill.name`; case-insensitive, unique per document. */
|
|
707
|
+
name: z2.string().min(1),
|
|
708
|
+
description: z2.string().optional(),
|
|
709
|
+
lines: z2.array(PatternLineSchema).min(1)
|
|
710
|
+
});
|
|
711
|
+
var hatchPatternKey = (name) => normalizeName(name);
|
|
712
|
+
var resolveHatchPattern = (name, hatchPatterns) => {
|
|
713
|
+
if (!name) return void 0;
|
|
714
|
+
if (hatchPatterns && hatchPatterns.length > 0) {
|
|
715
|
+
const key = normalizeName(name);
|
|
716
|
+
const own = hatchPatterns.find((p) => normalizeName(p.name) === key);
|
|
717
|
+
if (own) return own;
|
|
718
|
+
}
|
|
719
|
+
return getHatchPattern(name);
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
// ../core/src/export/dxf/exportDxf.ts
|
|
723
|
+
import {
|
|
724
|
+
DxfWriter,
|
|
725
|
+
Units,
|
|
726
|
+
LayerFlags,
|
|
727
|
+
LWPolylineFlags,
|
|
728
|
+
TextHorizontalAlignment,
|
|
729
|
+
TextVerticalAlignment,
|
|
730
|
+
HatchBoundaryPaths,
|
|
731
|
+
HatchPolylineBoundary,
|
|
732
|
+
HatchPredefinedPatterns,
|
|
733
|
+
pattern
|
|
734
|
+
} from "@tarikjabiri/dxf";
|
|
735
|
+
|
|
736
|
+
// ../core/src/model/objects.ts
|
|
737
|
+
import { z as z3 } from "zod";
|
|
738
|
+
|
|
43
739
|
// ../core/src/model/fonts.ts
|
|
44
740
|
var DEFAULT_FONT = "arial";
|
|
45
741
|
var FONTS = {
|
|
@@ -172,102 +868,185 @@ var fontTypeface = (def) => def.cssStack.split(",")[0].replace(/["']/g, "").trim
|
|
|
172
868
|
var FONT_OPTIONS = Object.values(
|
|
173
869
|
FONTS
|
|
174
870
|
).filter((f) => f.id !== "osifont-italic").map((f) => ({ value: f.id, label: f.label }));
|
|
871
|
+
var SHX_STEMS = /* @__PURE__ */ new Set([
|
|
872
|
+
"txt",
|
|
873
|
+
"monotxt",
|
|
874
|
+
"simplex",
|
|
875
|
+
"complex",
|
|
876
|
+
"romans",
|
|
877
|
+
"romand",
|
|
878
|
+
"romanc",
|
|
879
|
+
"romant",
|
|
880
|
+
"italic",
|
|
881
|
+
"italicc",
|
|
882
|
+
"italict",
|
|
883
|
+
"scripts",
|
|
884
|
+
"scriptc",
|
|
885
|
+
"gothice",
|
|
886
|
+
"gothicg",
|
|
887
|
+
"gothici",
|
|
888
|
+
"greeks",
|
|
889
|
+
"greekc",
|
|
890
|
+
"isocp",
|
|
891
|
+
"isocp2",
|
|
892
|
+
"isocp3",
|
|
893
|
+
"isoct",
|
|
894
|
+
"isoct2",
|
|
895
|
+
"isoct3",
|
|
896
|
+
"iso",
|
|
897
|
+
"amgdt",
|
|
898
|
+
"gdt",
|
|
899
|
+
"symap",
|
|
900
|
+
"syastro",
|
|
901
|
+
"symath",
|
|
902
|
+
"symeteo",
|
|
903
|
+
"symusic",
|
|
904
|
+
"bigfont",
|
|
905
|
+
"ltypeshp",
|
|
906
|
+
"swiss",
|
|
907
|
+
"swissb",
|
|
908
|
+
"swissi",
|
|
909
|
+
"swissbi",
|
|
910
|
+
"sansserif",
|
|
911
|
+
"sanss",
|
|
912
|
+
"sansserifb",
|
|
913
|
+
"sanssb",
|
|
914
|
+
"arc",
|
|
915
|
+
"ic-romans",
|
|
916
|
+
"ic-simplex",
|
|
917
|
+
"txtalt"
|
|
918
|
+
]);
|
|
919
|
+
var fontFromDxfStyle = (fontFile, typeface) => {
|
|
920
|
+
const file = (fontFile ?? "").trim();
|
|
921
|
+
const stem = file.replace(/\.[a-z0-9]+$/i, "").toLowerCase();
|
|
922
|
+
const family = (typeface ?? "").trim();
|
|
923
|
+
const familyLower = family.toLowerCase();
|
|
924
|
+
for (const def of Object.values(FONTS)) {
|
|
925
|
+
if (file && def.dxfFontFile.toLowerCase() === file.toLowerCase() || familyLower && fontTypeface(def).toLowerCase() === familyLower)
|
|
926
|
+
return def.id === "osifont-italic" ? { font: "osifont", italic: true } : { font: def.id };
|
|
927
|
+
}
|
|
928
|
+
const arialFace = /^arial(bd|bi|i)$/.exec(stem);
|
|
929
|
+
if (arialFace)
|
|
930
|
+
return {
|
|
931
|
+
font: "arial",
|
|
932
|
+
...arialFace[1].includes("b") ? { bold: true } : {},
|
|
933
|
+
...arialFace[1].includes("i") ? { italic: true } : {}
|
|
934
|
+
};
|
|
935
|
+
const key = `${familyLower} ${stem}`;
|
|
936
|
+
if (/narrow|condensed|arialn/.test(key)) return { font: "roboto-condensed" };
|
|
937
|
+
if (/mono|courier|\bcour\b|consola|lucon|menlo/.test(key))
|
|
938
|
+
return { font: "jetbrains-mono" };
|
|
939
|
+
if (/times|georgia|cambria|garamond|serif|\bbook/.test(key))
|
|
940
|
+
return { font: "source-serif" };
|
|
941
|
+
if (/comic/.test(key)) return { font: "comic-neue" };
|
|
942
|
+
if (/\.shx$/i.test(file) || !file && !family || SHX_STEMS.has(stem))
|
|
943
|
+
return {
|
|
944
|
+
font: "osifont",
|
|
945
|
+
.../italic/.test(stem) ? { italic: true } : {}
|
|
946
|
+
};
|
|
947
|
+
return { font: family || stem };
|
|
948
|
+
};
|
|
175
949
|
|
|
176
950
|
// ../core/src/model/objects.ts
|
|
177
951
|
var PointSchema = ObjectBaseSchema.extend({
|
|
178
|
-
type:
|
|
952
|
+
type: z3.literal("point"),
|
|
179
953
|
p: Vec2Schema
|
|
180
954
|
});
|
|
181
955
|
var LineSchema = ObjectBaseSchema.extend({
|
|
182
|
-
type:
|
|
956
|
+
type: z3.literal("line"),
|
|
183
957
|
a: Vec2Schema,
|
|
184
958
|
b: Vec2Schema
|
|
185
959
|
});
|
|
186
|
-
var PolylineVertexSchema =
|
|
960
|
+
var PolylineVertexSchema = z3.preprocess(
|
|
187
961
|
(v) => Array.isArray(v) && v.length >= 2 ? { x: v[0], y: v[1], bulge: v[2] ?? 0 } : v,
|
|
188
|
-
|
|
962
|
+
z3.object({ x: z3.number(), y: z3.number(), bulge: z3.number().default(0) })
|
|
189
963
|
);
|
|
190
964
|
var PolylineSchema = ObjectBaseSchema.extend({
|
|
191
|
-
type:
|
|
192
|
-
points:
|
|
193
|
-
closed:
|
|
965
|
+
type: z3.literal("polyline"),
|
|
966
|
+
points: z3.array(PolylineVertexSchema).min(2),
|
|
967
|
+
closed: z3.boolean().default(false)
|
|
194
968
|
});
|
|
195
969
|
var CircleSchema = ObjectBaseSchema.extend({
|
|
196
|
-
type:
|
|
970
|
+
type: z3.literal("circle"),
|
|
197
971
|
center: Vec2Schema,
|
|
198
|
-
radius:
|
|
972
|
+
radius: z3.number().positive()
|
|
199
973
|
});
|
|
200
974
|
var ArcSchema = ObjectBaseSchema.extend({
|
|
201
|
-
type:
|
|
975
|
+
type: z3.literal("arc"),
|
|
202
976
|
center: Vec2Schema,
|
|
203
|
-
radius:
|
|
204
|
-
startAngle:
|
|
205
|
-
endAngle:
|
|
977
|
+
radius: z3.number().positive(),
|
|
978
|
+
startAngle: z3.number(),
|
|
979
|
+
endAngle: z3.number()
|
|
206
980
|
});
|
|
207
981
|
var EllipseSchema = ObjectBaseSchema.extend({
|
|
208
|
-
type:
|
|
982
|
+
type: z3.literal("ellipse"),
|
|
209
983
|
center: Vec2Schema,
|
|
210
984
|
majorAxis: Vec2Schema,
|
|
211
|
-
ratio:
|
|
212
|
-
startAngle:
|
|
213
|
-
endAngle:
|
|
985
|
+
ratio: z3.number().gt(0).max(1),
|
|
986
|
+
startAngle: z3.number().default(0),
|
|
987
|
+
endAngle: z3.number().default(Math.PI * 2)
|
|
214
988
|
});
|
|
215
|
-
var HatchLoopSchema =
|
|
216
|
-
points:
|
|
989
|
+
var HatchLoopSchema = z3.object({
|
|
990
|
+
points: z3.array(PolylineVertexSchema).min(3)
|
|
217
991
|
});
|
|
218
|
-
var HatchFillSchema =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
kind:
|
|
222
|
-
name:
|
|
223
|
-
angle:
|
|
224
|
-
scale:
|
|
992
|
+
var HatchFillSchema = z3.discriminatedUnion("kind", [
|
|
993
|
+
z3.object({ kind: z3.literal("solid") }),
|
|
994
|
+
z3.object({
|
|
995
|
+
kind: z3.literal("pattern"),
|
|
996
|
+
name: z3.string(),
|
|
997
|
+
angle: z3.number(),
|
|
998
|
+
scale: z3.number().positive(),
|
|
999
|
+
/** Where the pattern frame is anchored, world mm (absent = the drawing
|
|
1000
|
+
* origin, like a hatch drawn here). Set by import for hatches that came
|
|
1001
|
+
* out of blocks — AutoCAD anchors a block's hatch to the block, so the
|
|
1002
|
+
* pattern phase follows the insertion — and carried by the transforms. */
|
|
1003
|
+
origin: Vec2Schema.optional()
|
|
225
1004
|
}),
|
|
226
|
-
|
|
227
|
-
kind:
|
|
228
|
-
angle:
|
|
229
|
-
spacing:
|
|
1005
|
+
z3.object({
|
|
1006
|
+
kind: z3.literal("lines"),
|
|
1007
|
+
angle: z3.number(),
|
|
1008
|
+
spacing: z3.number().positive()
|
|
230
1009
|
}),
|
|
231
|
-
|
|
232
|
-
kind:
|
|
1010
|
+
z3.object({
|
|
1011
|
+
kind: z3.literal("gradient"),
|
|
233
1012
|
/** linear = color1→color2 along `angle`; radial = color1 at the
|
|
234
1013
|
* boundary's center fading to color2 at its edge. */
|
|
235
|
-
shape:
|
|
236
|
-
color1:
|
|
237
|
-
color2:
|
|
1014
|
+
shape: z3.enum(["linear", "radial"]).default("linear"),
|
|
1015
|
+
color1: z3.string().default("#808080"),
|
|
1016
|
+
color2: z3.string().default("#2d2d2d"),
|
|
238
1017
|
/** Direction, radians CCW: 0 = color1 on the left (linear only). */
|
|
239
|
-
angle:
|
|
1018
|
+
angle: z3.number().default(0)
|
|
240
1019
|
})
|
|
241
1020
|
]);
|
|
242
1021
|
var HatchSchema = ObjectBaseSchema.extend({
|
|
243
|
-
type:
|
|
244
|
-
loops:
|
|
1022
|
+
type: z3.literal("hatch"),
|
|
1023
|
+
loops: z3.array(HatchLoopSchema).min(1),
|
|
245
1024
|
fill: HatchFillSchema.default({
|
|
246
1025
|
kind: "lines",
|
|
247
1026
|
angle: Math.PI / 4,
|
|
248
1027
|
spacing: 5
|
|
249
1028
|
}),
|
|
250
1029
|
/** Pattern spacing multiplier (same idea as DimStyle.scale). */
|
|
251
|
-
scale:
|
|
1030
|
+
scale: z3.number().positive().default(1)
|
|
252
1031
|
});
|
|
253
|
-
var ArrowTypeSchema =
|
|
254
|
-
var TextStyleSchema =
|
|
255
|
-
id:
|
|
256
|
-
name:
|
|
1032
|
+
var ArrowTypeSchema = z3.enum(["filled", "open", "tick", "dot", "none"]);
|
|
1033
|
+
var TextStyleSchema = z3.object({
|
|
1034
|
+
id: z3.string().default(() => crypto.randomUUID()),
|
|
1035
|
+
name: z3.string().default("Standard"),
|
|
257
1036
|
/** Font id (model/fonts.ts). */
|
|
258
|
-
font:
|
|
1037
|
+
font: z3.string().default("arial"),
|
|
259
1038
|
/** AutoCAD-style width factor: horizontal glyph scale. */
|
|
260
|
-
widthFactor:
|
|
1039
|
+
widthFactor: z3.number().positive().default(1),
|
|
261
1040
|
/** Bold / italic face (bundled outlines where the font has them, else
|
|
262
1041
|
* synthesized — model/fonts.ts `fontFace`). Absent = regular. */
|
|
263
|
-
bold:
|
|
264
|
-
italic:
|
|
1042
|
+
bold: z3.boolean().optional(),
|
|
1043
|
+
italic: z3.boolean().optional(),
|
|
265
1044
|
/** Cap height in mm (world), before the object's `scale`. */
|
|
266
|
-
textHeight:
|
|
1045
|
+
textHeight: z3.number().positive().default(2.5),
|
|
267
1046
|
/** Leader arrowhead style. */
|
|
268
1047
|
arrowType: ArrowTypeSchema.default("filled"),
|
|
269
1048
|
/** Leader arrowhead size (mm), before the object's `scale`. */
|
|
270
|
-
arrowSize:
|
|
1049
|
+
arrowSize: z3.number().positive().default(2.5)
|
|
271
1050
|
});
|
|
272
1051
|
var DEFAULT_TEXT_STYLE = {
|
|
273
1052
|
id: "standard",
|
|
@@ -278,14 +1057,14 @@ var DEFAULT_TEXT_STYLE = {
|
|
|
278
1057
|
arrowType: "filled",
|
|
279
1058
|
arrowSize: 2.5
|
|
280
1059
|
};
|
|
281
|
-
var TextStyleOverrideSchema =
|
|
282
|
-
font:
|
|
283
|
-
widthFactor:
|
|
284
|
-
bold:
|
|
285
|
-
italic:
|
|
286
|
-
textHeight:
|
|
1060
|
+
var TextStyleOverrideSchema = z3.object({
|
|
1061
|
+
font: z3.string().optional(),
|
|
1062
|
+
widthFactor: z3.number().positive().optional(),
|
|
1063
|
+
bold: z3.boolean().optional(),
|
|
1064
|
+
italic: z3.boolean().optional(),
|
|
1065
|
+
textHeight: z3.number().positive().optional(),
|
|
287
1066
|
arrowType: ArrowTypeSchema.optional(),
|
|
288
|
-
arrowSize:
|
|
1067
|
+
arrowSize: z3.number().positive().optional()
|
|
289
1068
|
});
|
|
290
1069
|
var textStyleFor = (obj, styles) => styles.find((s) => s.id === obj.styleId) ?? styles[0] ?? DEFAULT_TEXT_STYLE;
|
|
291
1070
|
var resolveTextStyle = (obj, styles) => ({ ...textStyleFor(obj, styles), ...obj.styleOverride });
|
|
@@ -301,62 +1080,79 @@ var effectiveTextFont = (obj, styles) => {
|
|
|
301
1080
|
widthFactor: o?.widthFactor ?? base.widthFactor
|
|
302
1081
|
};
|
|
303
1082
|
};
|
|
1083
|
+
var TextSpanSchema = z3.object({
|
|
1084
|
+
start: z3.number().int().min(0),
|
|
1085
|
+
end: z3.number().int().min(0),
|
|
1086
|
+
/** Font id (model/fonts.ts). */
|
|
1087
|
+
font: z3.string().optional(),
|
|
1088
|
+
bold: z3.boolean().optional(),
|
|
1089
|
+
italic: z3.boolean().optional(),
|
|
1090
|
+
underline: z3.boolean().optional(),
|
|
1091
|
+
/** Literal colour; absent = the text's own (possibly ByLayer) colour. */
|
|
1092
|
+
color: ColorSchema.optional(),
|
|
1093
|
+
/** × the text's cap height. */
|
|
1094
|
+
height: z3.number().positive().optional(),
|
|
1095
|
+
script: z3.enum(["sub", "super"]).optional()
|
|
1096
|
+
});
|
|
304
1097
|
var TextSchema = ObjectBaseSchema.extend({
|
|
305
|
-
type:
|
|
1098
|
+
type: z3.literal("text"),
|
|
306
1099
|
position: Vec2Schema,
|
|
307
|
-
content:
|
|
1100
|
+
content: z3.string(),
|
|
1101
|
+
/** Character formatting over `content`; absent = all plain. Replacing
|
|
1102
|
+
* `content` without new spans drops them (offsets would be stale). */
|
|
1103
|
+
spans: z3.array(TextSpanSchema).optional(),
|
|
308
1104
|
/** Arrow polylines pointing at this text (arrowhead at [0]). */
|
|
309
|
-
leaderLines:
|
|
1105
|
+
leaderLines: z3.array(z3.array(Vec2Schema).min(2)).default([]),
|
|
310
1106
|
/**
|
|
311
1107
|
* Max text box width in mm (before `scale`) — the word-wrap boundary and the
|
|
312
1108
|
* frame width. Undefined = no wrapping (lines break only on explicit
|
|
313
1109
|
* newlines). Maps to the DXF MTEXT reference rectangle width.
|
|
314
1110
|
*/
|
|
315
|
-
width:
|
|
316
|
-
hAlign:
|
|
317
|
-
vAlign:
|
|
1111
|
+
width: z3.number().positive().optional(),
|
|
1112
|
+
hAlign: z3.enum(["left", "center", "right"]).default("center"),
|
|
1113
|
+
vAlign: z3.enum(["bottom", "center", "top"]).default("center"),
|
|
318
1114
|
/** Border drawn around the text: a rectangle, a circle, a slot (rounded
|
|
319
1115
|
* ends), a line under the text or under its first line. */
|
|
320
|
-
frame:
|
|
1116
|
+
frame: z3.enum(["none", "rectangle", "circle", "slot", "bottom", "firstLine"]).optional(),
|
|
321
1117
|
/** The document text style this text follows (absent/dangling = the
|
|
322
1118
|
* document's first style). */
|
|
323
|
-
styleId:
|
|
1119
|
+
styleId: z3.string().optional(),
|
|
324
1120
|
/** Style keys the user set on THIS text (font, height, arrows, …);
|
|
325
1121
|
* absent = inherit the referenced style. */
|
|
326
1122
|
styleOverride: TextStyleOverrideSchema.optional(),
|
|
327
|
-
rotation:
|
|
1123
|
+
rotation: z3.number().default(0),
|
|
328
1124
|
/** Size multiplier for height + arrow size (same idea as
|
|
329
1125
|
* Dimension.scale). */
|
|
330
|
-
scale:
|
|
1126
|
+
scale: z3.number().positive().default(1)
|
|
331
1127
|
});
|
|
332
|
-
var DimensionKindSchema =
|
|
1128
|
+
var DimensionKindSchema = z3.enum([
|
|
333
1129
|
"linear",
|
|
334
1130
|
"angular",
|
|
335
1131
|
"radial",
|
|
336
1132
|
"diameter"
|
|
337
1133
|
]);
|
|
338
|
-
var DimStyleSchema =
|
|
339
|
-
id:
|
|
340
|
-
name:
|
|
1134
|
+
var DimStyleSchema = z3.object({
|
|
1135
|
+
id: z3.string().default(() => crypto.randomUUID()),
|
|
1136
|
+
name: z3.string().default("Standard"),
|
|
341
1137
|
/** Font id for dimension text (model/fonts.ts). */
|
|
342
|
-
font:
|
|
1138
|
+
font: z3.string().default("arial"),
|
|
343
1139
|
/** Horizontal glyph scale for dimension text. */
|
|
344
|
-
widthFactor:
|
|
1140
|
+
widthFactor: z3.number().positive().default(1),
|
|
345
1141
|
/** Bold / italic dimension text (same faces as TextStyle). */
|
|
346
|
-
bold:
|
|
347
|
-
italic:
|
|
348
|
-
textHeight:
|
|
1142
|
+
bold: z3.boolean().optional(),
|
|
1143
|
+
italic: z3.boolean().optional(),
|
|
1144
|
+
textHeight: z3.number().positive().default(2.5),
|
|
349
1145
|
/** Dimension line → text center distance (mm, × scale; DXF DIMGAP-ish). */
|
|
350
|
-
textOffset:
|
|
1146
|
+
textOffset: z3.number().default(1.8),
|
|
351
1147
|
arrowType: ArrowTypeSchema.default("tick"),
|
|
352
|
-
arrowSize:
|
|
1148
|
+
arrowSize: z3.number().positive().default(2.5),
|
|
353
1149
|
/** "long" runs each extension line from the measured point to the
|
|
354
1150
|
* dimension line; "short" draws only a 2×overshoot tick across it. */
|
|
355
|
-
extensionType:
|
|
356
|
-
extensionOffset:
|
|
357
|
-
extensionOvershoot:
|
|
1151
|
+
extensionType: z3.enum(["long", "short"]).default("long"),
|
|
1152
|
+
extensionOffset: z3.number().default(1),
|
|
1153
|
+
extensionOvershoot: z3.number().default(1.25),
|
|
358
1154
|
/** Decimal places for the measurement text. */
|
|
359
|
-
precision:
|
|
1155
|
+
precision: z3.number().int().min(0).max(6).default(1)
|
|
360
1156
|
});
|
|
361
1157
|
var DEFAULT_DIM_STYLE = {
|
|
362
1158
|
id: "standard",
|
|
@@ -372,19 +1168,19 @@ var DEFAULT_DIM_STYLE = {
|
|
|
372
1168
|
extensionOvershoot: 1,
|
|
373
1169
|
precision: 1
|
|
374
1170
|
};
|
|
375
|
-
var DimStyleOverrideSchema =
|
|
376
|
-
font:
|
|
377
|
-
widthFactor:
|
|
378
|
-
bold:
|
|
379
|
-
italic:
|
|
380
|
-
textHeight:
|
|
381
|
-
textOffset:
|
|
1171
|
+
var DimStyleOverrideSchema = z3.object({
|
|
1172
|
+
font: z3.string().optional(),
|
|
1173
|
+
widthFactor: z3.number().positive().optional(),
|
|
1174
|
+
bold: z3.boolean().optional(),
|
|
1175
|
+
italic: z3.boolean().optional(),
|
|
1176
|
+
textHeight: z3.number().positive().optional(),
|
|
1177
|
+
textOffset: z3.number().optional(),
|
|
382
1178
|
arrowType: ArrowTypeSchema.optional(),
|
|
383
|
-
arrowSize:
|
|
384
|
-
extensionType:
|
|
385
|
-
extensionOffset:
|
|
386
|
-
extensionOvershoot:
|
|
387
|
-
precision:
|
|
1179
|
+
arrowSize: z3.number().positive().optional(),
|
|
1180
|
+
extensionType: z3.enum(["long", "short"]).optional(),
|
|
1181
|
+
extensionOffset: z3.number().optional(),
|
|
1182
|
+
extensionOvershoot: z3.number().optional(),
|
|
1183
|
+
precision: z3.number().int().min(0).max(6).optional()
|
|
388
1184
|
});
|
|
389
1185
|
var unknownStyleOverrideKeys = (input) => {
|
|
390
1186
|
const so = input.styleOverride;
|
|
@@ -403,48 +1199,114 @@ var assertKnownStyleOverrideKeys = (input, where) => {
|
|
|
403
1199
|
};
|
|
404
1200
|
var dimStyleFor = (obj, styles) => styles.find((s) => s.id === obj.styleId) ?? styles[0] ?? DEFAULT_DIM_STYLE;
|
|
405
1201
|
var dimFontFace = (style) => fontFace(style.font, style.bold, style.italic);
|
|
406
|
-
var
|
|
407
|
-
|
|
1202
|
+
var DIM_VALUE_TOKEN = "{value}";
|
|
1203
|
+
var DimLabelSchema = z3.object({
|
|
1204
|
+
/** mm along the dimension line from the segment's origin (linear: the
|
|
1205
|
+
* foot of the segment's first point; angular: where ray a meets the arc,
|
|
1206
|
+
* as arc length; radial/diameter: the center). Undefined = automatic
|
|
1207
|
+
* placement: centered when the text fits, else outside. */
|
|
1208
|
+
along: z3.number().optional(),
|
|
1209
|
+
/** mm perpendicular to the dimension line, positive on the side the
|
|
1210
|
+
* dimension line is on (linear/angular) or to the left of `along`
|
|
1211
|
+
* (radial/diameter). Undefined or 0 = on the line; otherwise the text
|
|
1212
|
+
* floats, with a leader when it no longer overlaps its segment. */
|
|
1213
|
+
across: z3.number().optional(),
|
|
1214
|
+
/** Text; `{value}` is replaced by the formatted measurement. Undefined =
|
|
1215
|
+
* the kind's default template ("{value}", "{value}°", "R{value}",
|
|
1216
|
+
* "Ø{value}"). */
|
|
1217
|
+
content: z3.string().optional(),
|
|
1218
|
+
/** Character formatting over `content` (the TEMPLATE: a span covering
|
|
1219
|
+
* `{value}` formats the measurement). Needs `content` set. */
|
|
1220
|
+
spans: z3.array(TextSpanSchema).optional()
|
|
1221
|
+
});
|
|
1222
|
+
var DimensionShapeSchema = ObjectBaseSchema.extend({
|
|
1223
|
+
type: z3.literal("dimension"),
|
|
408
1224
|
kind: DimensionKindSchema.default("linear"),
|
|
409
1225
|
/**
|
|
410
|
-
* Measured points.
|
|
411
|
-
*
|
|
412
|
-
*
|
|
1226
|
+
* Measured points. linear: 2+ (more than two render as a CHAIN — one
|
|
1227
|
+
* measurement per consecutive pair sharing the dimension line);
|
|
1228
|
+
* angular: [vertex, a, b]; radial: [center, curve point]; diameter:
|
|
1229
|
+
* [p1, p2] opposite on the curve.
|
|
1230
|
+
*/
|
|
1231
|
+
points: z3.array(Vec2Schema).min(2),
|
|
1232
|
+
/**
|
|
1233
|
+
* linear only: the measuring direction, radians CCW from +X (DXF's
|
|
1234
|
+
* "rotated" dimension, code 50). Undefined = aligned to
|
|
1235
|
+
* points[0] → points[last] (DXF "aligned"), so dragging a point turns the
|
|
1236
|
+
* dimension; set, the direction is locked and a point drag only changes
|
|
1237
|
+
* the measurement.
|
|
413
1238
|
*/
|
|
414
|
-
|
|
1239
|
+
rotation: z3.number().optional(),
|
|
415
1240
|
/**
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
1241
|
+
* linear: signed distance of the dimension line from points[0] along the
|
|
1242
|
+
* LEFT perpendicular of the measuring direction. angular: the arc radius,
|
|
1243
|
+
* positive for the arc running CCW from a to b, negative for the
|
|
1244
|
+
* complementary arc. radial/diameter: absent — the line's direction comes
|
|
1245
|
+
* from the points and the text position is labels[0].along.
|
|
421
1246
|
*/
|
|
422
|
-
offset:
|
|
423
|
-
|
|
1247
|
+
offset: z3.number().optional(),
|
|
1248
|
+
/** One label per measured segment (linear chain: points.length − 1,
|
|
1249
|
+
* every other kind: 1). Missing or short = automatic. */
|
|
1250
|
+
labels: z3.array(DimLabelSchema).default([]),
|
|
424
1251
|
/** The document dimension style this dimension follows (absent/dangling =
|
|
425
1252
|
* the document's first style). */
|
|
426
|
-
styleId:
|
|
1253
|
+
styleId: z3.string().optional(),
|
|
427
1254
|
styleOverride: DimStyleOverrideSchema.optional(),
|
|
428
1255
|
/** Annotation size multiplier (text/arrows/offsets — same idea as
|
|
429
1256
|
* Text.scale; rides as DIMSCALE in DXF). */
|
|
430
|
-
scale:
|
|
1257
|
+
scale: z3.number().positive().default(1)
|
|
431
1258
|
});
|
|
1259
|
+
var dimensionRefinement = (d, ctx) => {
|
|
1260
|
+
const need = d.kind === "angular" ? 3 : 2;
|
|
1261
|
+
if (d.points.length < need)
|
|
1262
|
+
ctx.addIssue({
|
|
1263
|
+
code: "custom",
|
|
1264
|
+
path: ["points"],
|
|
1265
|
+
message: `a ${d.kind} dimension needs at least ${need} points`
|
|
1266
|
+
});
|
|
1267
|
+
if (d.kind !== "linear" && d.kind !== "angular") {
|
|
1268
|
+
if (d.offset !== void 0)
|
|
1269
|
+
ctx.addIssue({
|
|
1270
|
+
code: "custom",
|
|
1271
|
+
path: ["offset"],
|
|
1272
|
+
message: `offset does not apply to a ${d.kind} dimension (the text position is labels[0].along)`
|
|
1273
|
+
});
|
|
1274
|
+
} else if (d.offset === void 0)
|
|
1275
|
+
ctx.addIssue({
|
|
1276
|
+
code: "custom",
|
|
1277
|
+
path: ["offset"],
|
|
1278
|
+
message: `a ${d.kind} dimension needs offset`
|
|
1279
|
+
});
|
|
1280
|
+
if (d.kind !== "linear" && d.rotation !== void 0)
|
|
1281
|
+
ctx.addIssue({
|
|
1282
|
+
code: "custom",
|
|
1283
|
+
path: ["rotation"],
|
|
1284
|
+
message: "rotation applies to linear dimensions only"
|
|
1285
|
+
});
|
|
1286
|
+
};
|
|
1287
|
+
var DimensionSchema = DimensionShapeSchema.superRefine(dimensionRefinement);
|
|
1288
|
+
var DIM_DEFAULT_CONTENT = {
|
|
1289
|
+
linear: DIM_VALUE_TOKEN,
|
|
1290
|
+
angular: `${DIM_VALUE_TOKEN}\xB0`,
|
|
1291
|
+
radial: `R${DIM_VALUE_TOKEN}`,
|
|
1292
|
+
diameter: `\xD8${DIM_VALUE_TOKEN}`
|
|
1293
|
+
};
|
|
432
1294
|
var BlockSchema = ObjectBaseSchema.extend({
|
|
433
|
-
type:
|
|
434
|
-
definitionId:
|
|
1295
|
+
type: z3.literal("block"),
|
|
1296
|
+
definitionId: z3.string(),
|
|
435
1297
|
/** Applied LAST, about the pivot (the first point input). */
|
|
436
|
-
rotation:
|
|
437
|
-
scale:
|
|
1298
|
+
rotation: z3.number().default(0),
|
|
1299
|
+
scale: z3.number().positive().default(1),
|
|
438
1300
|
/** Per-instance parameter values (merged over the definition defaults). */
|
|
439
|
-
params:
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
1301
|
+
params: z3.record(
|
|
1302
|
+
z3.string(),
|
|
1303
|
+
z3.union([
|
|
1304
|
+
z3.number(),
|
|
1305
|
+
z3.string(),
|
|
1306
|
+
z3.boolean(),
|
|
445
1307
|
// numberList / stringList parameters.
|
|
446
|
-
|
|
447
|
-
|
|
1308
|
+
z3.array(z3.number()),
|
|
1309
|
+
z3.array(z3.string())
|
|
448
1310
|
])
|
|
449
1311
|
).default({}),
|
|
450
1312
|
/**
|
|
@@ -456,63 +1318,73 @@ var BlockSchema = ObjectBaseSchema.extend({
|
|
|
456
1318
|
* Transforms map the points and the script recomputes, which is what
|
|
457
1319
|
* makes mirror correct for script-derived geometry.
|
|
458
1320
|
*/
|
|
459
|
-
inputs:
|
|
1321
|
+
inputs: z3.array(z3.union([Vec2Schema, z3.string()])).default([])
|
|
460
1322
|
});
|
|
461
1323
|
var CommentSchema = ObjectBaseSchema.extend({
|
|
462
|
-
type:
|
|
1324
|
+
type: z3.literal("comment"),
|
|
463
1325
|
/** Tail tip of the bubble (world/sheet mm). */
|
|
464
1326
|
position: Vec2Schema,
|
|
465
|
-
text:
|
|
466
|
-
tags:
|
|
1327
|
+
text: z3.string().default(""),
|
|
1328
|
+
tags: z3.array(z3.string()).default([])
|
|
467
1329
|
});
|
|
468
|
-
var
|
|
469
|
-
|
|
470
|
-
text
|
|
1330
|
+
var cellInput = (v) => {
|
|
1331
|
+
if (typeof v === "string") return { content: v };
|
|
1332
|
+
if (v && typeof v === "object" && "text" in v && !("content" in v)) {
|
|
1333
|
+
const { text, ...rest } = v;
|
|
1334
|
+
return { ...rest, content: text };
|
|
1335
|
+
}
|
|
1336
|
+
return v;
|
|
1337
|
+
};
|
|
1338
|
+
var TableCellSchema = z3.object({
|
|
1339
|
+
/** Plain text; "\n" = line break. Long lines wrap at the cell width.
|
|
1340
|
+
* (Named `text` before document v22 — still read, see `cellInput`.) */
|
|
1341
|
+
content: z3.string().default(""),
|
|
1342
|
+
/** Character formatting over `content` (core/table.ts `cellWithContent`
|
|
1343
|
+
* keeps it consistent when the content changes). */
|
|
1344
|
+
spans: z3.array(TextSpanSchema).optional(),
|
|
471
1345
|
/** Merge, set on the ANCHOR (top-left) cell. Covered cells stay in the
|
|
472
1346
|
* grid with their content ignored — AutoCAD's model. */
|
|
473
|
-
span:
|
|
474
|
-
cols:
|
|
475
|
-
rows:
|
|
1347
|
+
span: z3.object({
|
|
1348
|
+
cols: z3.number().int().min(1),
|
|
1349
|
+
rows: z3.number().int().min(1)
|
|
476
1350
|
}).optional(),
|
|
477
1351
|
/** Where the text sits in the cell; absent = left / center. */
|
|
478
|
-
hAlign:
|
|
479
|
-
vAlign:
|
|
480
|
-
styleId:
|
|
1352
|
+
hAlign: z3.enum(["left", "center", "right"]).optional(),
|
|
1353
|
+
vAlign: z3.enum(["top", "center", "bottom"]).optional(),
|
|
1354
|
+
styleId: z3.string().optional(),
|
|
481
1355
|
styleOverride: TextStyleOverrideSchema.optional(),
|
|
482
1356
|
/** Text color; absent = the table's. */
|
|
483
1357
|
color: ColorSchema.optional()
|
|
484
1358
|
});
|
|
485
|
-
var
|
|
486
|
-
type:
|
|
1359
|
+
var TableShapeSchema = ObjectBaseSchema.extend({
|
|
1360
|
+
type: z3.literal("table"),
|
|
487
1361
|
position: Vec2Schema,
|
|
488
|
-
rotation:
|
|
489
|
-
scale:
|
|
1362
|
+
rotation: z3.number().default(0),
|
|
1363
|
+
scale: z3.number().positive().default(1),
|
|
490
1364
|
/** Column widths (mm). */
|
|
491
|
-
columns:
|
|
1365
|
+
columns: z3.array(z3.number().positive()).min(1),
|
|
492
1366
|
/** Per-row settings. Input may give a row COUNT (all auto-height). */
|
|
493
|
-
rows:
|
|
1367
|
+
rows: z3.preprocess(
|
|
494
1368
|
(v) => typeof v === "number" ? Array.from({ length: v }, () => ({})) : v,
|
|
495
|
-
|
|
1369
|
+
z3.array(z3.object({ minHeight: z3.number().positive().optional() })).min(1)
|
|
496
1370
|
),
|
|
497
1371
|
/** Row-major: `cells[row][column]`, exactly rows × columns. Input may
|
|
498
1372
|
* give a cell as a plain string (= `{ text }`). */
|
|
499
|
-
cells:
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
(v) => typeof v === "string" ? { text: v } : v,
|
|
503
|
-
TableCellSchema
|
|
504
|
-
)
|
|
1373
|
+
cells: z3.array(
|
|
1374
|
+
z3.array(
|
|
1375
|
+
z3.preprocess(cellInput, TableCellSchema)
|
|
505
1376
|
)
|
|
506
1377
|
),
|
|
507
1378
|
/** Rows above the heavier header rule. */
|
|
508
|
-
headerRows:
|
|
1379
|
+
headerRows: z3.number().int().min(0).default(0),
|
|
509
1380
|
/** Text inset from the cell edges (mm). */
|
|
510
|
-
cellMargin:
|
|
511
|
-
borders:
|
|
1381
|
+
cellMargin: z3.number().min(0).default(1),
|
|
1382
|
+
borders: z3.enum(["all", "outer", "rows", "none"]).default("all"),
|
|
512
1383
|
/** Document text style for every cell (cells may override). */
|
|
513
|
-
styleId:
|
|
1384
|
+
styleId: z3.string().optional(),
|
|
514
1385
|
styleOverride: TextStyleOverrideSchema.optional()
|
|
515
|
-
})
|
|
1386
|
+
});
|
|
1387
|
+
var tableRefinement = (t, ctx) => {
|
|
516
1388
|
const issue = (message) => ctx.addIssue({ code: "custom", message });
|
|
517
1389
|
const nr = t.rows.length;
|
|
518
1390
|
const nc = t.columns.length;
|
|
@@ -536,38 +1408,39 @@ var TableSchema = ObjectBaseSchema.extend({
|
|
|
536
1408
|
}
|
|
537
1409
|
})
|
|
538
1410
|
);
|
|
539
|
-
}
|
|
1411
|
+
};
|
|
1412
|
+
var TableSchema = TableShapeSchema.superRefine(tableRefinement);
|
|
540
1413
|
var blockPivot = (b) => {
|
|
541
1414
|
for (const v of b.inputs) if (typeof v !== "string") return v;
|
|
542
1415
|
return { x: 0, y: 0 };
|
|
543
1416
|
};
|
|
544
1417
|
var ViewportSchema = ObjectBaseSchema.extend({
|
|
545
|
-
type:
|
|
1418
|
+
type: z3.literal("viewport"),
|
|
546
1419
|
/** Placement on the sheet, mm, origin bottom-left of sheet. */
|
|
547
|
-
rect:
|
|
548
|
-
x:
|
|
549
|
-
y:
|
|
550
|
-
w:
|
|
551
|
-
h:
|
|
1420
|
+
rect: z3.object({
|
|
1421
|
+
x: z3.number(),
|
|
1422
|
+
y: z3.number(),
|
|
1423
|
+
w: z3.number().positive(),
|
|
1424
|
+
h: z3.number().positive()
|
|
552
1425
|
}),
|
|
553
1426
|
/** World point shown at the center of the rect. */
|
|
554
1427
|
modelCenter: Vec2Schema.default({ x: 0, y: 0 }),
|
|
555
1428
|
/** Drawing-scale denominator (model mm per paper mm); 1:50 => 50. */
|
|
556
|
-
scale:
|
|
1429
|
+
scale: z3.number().positive().default(1),
|
|
557
1430
|
/** Pinned: no pan/zoom-through, no move/resize grips. */
|
|
558
|
-
locked:
|
|
559
|
-
hiddenLayerIds:
|
|
1431
|
+
locked: z3.boolean().default(false),
|
|
1432
|
+
hiddenLayerIds: z3.array(z3.string()).default([])
|
|
560
1433
|
});
|
|
561
1434
|
var ImageSchema = ObjectBaseSchema.extend({
|
|
562
|
-
type:
|
|
1435
|
+
type: z3.literal("image"),
|
|
563
1436
|
/** Key into `document.assets`. */
|
|
564
|
-
assetId:
|
|
1437
|
+
assetId: z3.string(),
|
|
565
1438
|
/** Bottom-left corner (world/sheet mm) — rotation pivots here. */
|
|
566
1439
|
origin: Vec2Schema,
|
|
567
|
-
width:
|
|
568
|
-
height:
|
|
1440
|
+
width: z3.number().positive(),
|
|
1441
|
+
height: z3.number().positive(),
|
|
569
1442
|
/** Radians CCW about `origin`. */
|
|
570
|
-
rotation:
|
|
1443
|
+
rotation: z3.number().default(0)
|
|
571
1444
|
// (opacity moved to ObjectBaseSchema — every object paints with it now;
|
|
572
1445
|
// documents that stored it per-image parse unchanged.)
|
|
573
1446
|
});
|
|
@@ -579,54 +1452,54 @@ var REFERENCE_FORMATS = [
|
|
|
579
1452
|
"png",
|
|
580
1453
|
"jpg"
|
|
581
1454
|
];
|
|
582
|
-
var ReferenceSourceSchema =
|
|
583
|
-
|
|
584
|
-
kind:
|
|
585
|
-
path:
|
|
586
|
-
cacheKey:
|
|
1455
|
+
var ReferenceSourceSchema = z3.discriminatedUnion("kind", [
|
|
1456
|
+
z3.object({
|
|
1457
|
+
kind: z3.literal("path"),
|
|
1458
|
+
path: z3.string().min(1),
|
|
1459
|
+
cacheKey: z3.string().min(1).optional()
|
|
587
1460
|
}),
|
|
588
|
-
|
|
1461
|
+
z3.object({ kind: z3.literal("url"), url: z3.string().url() })
|
|
589
1462
|
]);
|
|
590
1463
|
var ReferenceSchema = ObjectBaseSchema.extend({
|
|
591
|
-
type:
|
|
592
|
-
format:
|
|
593
|
-
name:
|
|
1464
|
+
type: z3.literal("reference"),
|
|
1465
|
+
format: z3.enum(REFERENCE_FORMATS),
|
|
1466
|
+
name: z3.string().min(1),
|
|
594
1467
|
source: ReferenceSourceSchema,
|
|
595
1468
|
position: Vec2Schema,
|
|
596
1469
|
/** Radians CCW about `position`. */
|
|
597
|
-
rotation:
|
|
598
|
-
scale:
|
|
599
|
-
mirrored:
|
|
1470
|
+
rotation: z3.number().default(0),
|
|
1471
|
+
scale: z3.number().positive().default(1),
|
|
1472
|
+
mirrored: z3.boolean().optional(),
|
|
600
1473
|
/** PDF: the 1-based page drawn, and how (vector lines + text / raster). */
|
|
601
|
-
pdfPage:
|
|
602
|
-
pdfMode:
|
|
1474
|
+
pdfPage: z3.number().int().positive().optional(),
|
|
1475
|
+
pdfMode: z3.enum(["vector", "raster"]).optional(),
|
|
603
1476
|
/** The FILE's layers not drawn, by name (stable across reloads). */
|
|
604
|
-
hiddenLayers:
|
|
1477
|
+
hiddenLayers: z3.array(z3.string()).default([]),
|
|
605
1478
|
/** Switched off in the References panel: not drawn, picked or snapped. */
|
|
606
|
-
hidden:
|
|
1479
|
+
hidden: z3.boolean().optional(),
|
|
607
1480
|
/** Locked in the References panel: drawn and snapped, but never hovered
|
|
608
1481
|
* or picked on the canvas — select it from the panel instead. */
|
|
609
|
-
locked:
|
|
1482
|
+
locked: z3.boolean().optional(),
|
|
610
1483
|
/** Crop rectangle in FILE coordinates: only content inside is drawn and
|
|
611
1484
|
* snapped (AutoCAD's XCLIP, rectangular). */
|
|
612
|
-
clip:
|
|
613
|
-
minX:
|
|
614
|
-
minY:
|
|
615
|
-
maxX:
|
|
616
|
-
maxY:
|
|
1485
|
+
clip: z3.object({
|
|
1486
|
+
minX: z3.number(),
|
|
1487
|
+
minY: z3.number(),
|
|
1488
|
+
maxX: z3.number(),
|
|
1489
|
+
maxY: z3.number()
|
|
617
1490
|
}).optional(),
|
|
618
1491
|
/**
|
|
619
1492
|
* The content's bounds in file coordinates, recorded on each successful
|
|
620
1493
|
* load: a missing file still has a frame to draw, pick and snap to.
|
|
621
1494
|
*/
|
|
622
|
-
extent:
|
|
623
|
-
minX:
|
|
624
|
-
minY:
|
|
625
|
-
maxX:
|
|
626
|
-
maxY:
|
|
1495
|
+
extent: z3.object({
|
|
1496
|
+
minX: z3.number(),
|
|
1497
|
+
minY: z3.number(),
|
|
1498
|
+
maxX: z3.number(),
|
|
1499
|
+
maxY: z3.number()
|
|
627
1500
|
}).optional()
|
|
628
1501
|
});
|
|
629
|
-
var ModelObjectSchema =
|
|
1502
|
+
var ModelObjectSchema = z3.discriminatedUnion("type", [
|
|
630
1503
|
PointSchema,
|
|
631
1504
|
LineSchema,
|
|
632
1505
|
PolylineSchema,
|
|
@@ -644,6 +1517,9 @@ var ModelObjectSchema = z2.discriminatedUnion("type", [
|
|
|
644
1517
|
ReferenceSchema
|
|
645
1518
|
]);
|
|
646
1519
|
|
|
1520
|
+
// ../core/src/model/lineTypes.ts
|
|
1521
|
+
import { z as z4 } from "zod";
|
|
1522
|
+
|
|
647
1523
|
// ../core/src/model/builtinLin.ts
|
|
648
1524
|
var BUILTIN_LIN = `;; Linea built-in line type library.
|
|
649
1525
|
;;
|
|
@@ -799,7 +1675,7 @@ var CURATED = [
|
|
|
799
1675
|
dxfName: "DIVIDE"
|
|
800
1676
|
}
|
|
801
1677
|
];
|
|
802
|
-
var
|
|
1678
|
+
var normalizeName2 = (name) => name.trim().toUpperCase().replace(/[\s.-]+/g, "_");
|
|
803
1679
|
var asciiPreview = (dashesMm) => {
|
|
804
1680
|
const WIDTH = 15;
|
|
805
1681
|
if (!dashesMm.length) return "_".repeat(WIDTH * 0.8);
|
|
@@ -820,9 +1696,9 @@ var withPreview = (p) => {
|
|
|
820
1696
|
return { ...p, label: `${p.label} ${asciiPreview(p.dashesMm)}` };
|
|
821
1697
|
};
|
|
822
1698
|
var BUILT_IN = CURATED.map(withPreview);
|
|
823
|
-
var BY_NAME = new Map(BUILT_IN.map((p) => [
|
|
1699
|
+
var BY_NAME = new Map(BUILT_IN.map((p) => [normalizeName2(p.name), p]));
|
|
824
1700
|
for (const p of parseLinDefinitions(BUILTIN_LIN)) {
|
|
825
|
-
const key =
|
|
1701
|
+
const key = normalizeName2(p.name);
|
|
826
1702
|
if (BY_NAME.has(key)) continue;
|
|
827
1703
|
const pattern2 = withPreview({
|
|
828
1704
|
name: p.name,
|
|
@@ -840,15 +1716,40 @@ var scaleVariantBase = (name) => {
|
|
|
840
1716
|
};
|
|
841
1717
|
for (const p of BUILT_IN) {
|
|
842
1718
|
const base = scaleVariantBase(p.name);
|
|
843
|
-
const target = base ? BY_NAME.get(
|
|
1719
|
+
const target = base ? BY_NAME.get(normalizeName2(base)) : void 0;
|
|
844
1720
|
if (target && target !== p) p.hidden = true;
|
|
845
1721
|
}
|
|
846
1722
|
var LINE_TYPE_NAMES = BUILT_IN.filter((p) => !p.hidden).map(
|
|
847
1723
|
(p) => p.name
|
|
848
1724
|
);
|
|
849
1725
|
var LINE_TYPE_DEFS = BUILT_IN;
|
|
850
|
-
var getLineType = (name) => BY_NAME.get(
|
|
1726
|
+
var getLineType = (name) => BY_NAME.get(normalizeName2(name));
|
|
851
1727
|
var renderDashes = (pattern2) => pattern2.dashesMm.length ? pattern2.dashesMm.map((v) => v === 0 ? 0.1 : Math.abs(v)) : void 0;
|
|
1728
|
+
var LineTypeSchema = z4.object({
|
|
1729
|
+
/** Stored on objects/layers as `lineType`; case-insensitive, unique per
|
|
1730
|
+
* document. */
|
|
1731
|
+
name: z4.string().min(1),
|
|
1732
|
+
description: z4.string().optional(),
|
|
1733
|
+
/** Signed dash cycle, mm per 1 mm of line width: >0 dash, <0 gap, 0 dot.
|
|
1734
|
+
* Empty = continuous. */
|
|
1735
|
+
dashesMm: z4.array(z4.number())
|
|
1736
|
+
});
|
|
1737
|
+
var lineTypeKey = (name) => normalizeName2(name);
|
|
1738
|
+
var lineTypeAsPattern = (t) => ({
|
|
1739
|
+
name: t.name,
|
|
1740
|
+
label: t.description ?? t.name,
|
|
1741
|
+
dashesMm: t.dashesMm,
|
|
1742
|
+
dxfName: t.name.toUpperCase()
|
|
1743
|
+
});
|
|
1744
|
+
var resolveLineType = (name, lineTypes) => {
|
|
1745
|
+
if (!name) return void 0;
|
|
1746
|
+
if (lineTypes && lineTypes.length > 0) {
|
|
1747
|
+
const key = normalizeName2(name);
|
|
1748
|
+
const own = lineTypes.find((t) => normalizeName2(t.name) === key);
|
|
1749
|
+
if (own) return lineTypeAsPattern(own);
|
|
1750
|
+
}
|
|
1751
|
+
return getLineType(name);
|
|
1752
|
+
};
|
|
852
1753
|
|
|
853
1754
|
// ../core/src/geometry/vec2.ts
|
|
854
1755
|
var add = (a, b) => ({ x: a.x + b.x, y: a.y + b.y });
|
|
@@ -939,105 +1840,105 @@ var readListParam = (type, value) => {
|
|
|
939
1840
|
};
|
|
940
1841
|
|
|
941
1842
|
// ../core/src/model/blockDefinition.ts
|
|
942
|
-
import { z as
|
|
1843
|
+
import { z as z5 } from "zod";
|
|
943
1844
|
var paramBase = {
|
|
944
|
-
name:
|
|
945
|
-
label:
|
|
1845
|
+
name: z5.string().regex(/^[a-zA-Z_]\w*$/),
|
|
1846
|
+
label: z5.string().optional(),
|
|
946
1847
|
/** What the parameter means: the label's tooltip in the panel. */
|
|
947
|
-
hint:
|
|
1848
|
+
hint: z5.string().optional()
|
|
948
1849
|
};
|
|
949
1850
|
var HEX_COLOR = /^#[0-9a-f]{6}$/i;
|
|
950
|
-
var EnumOptionSchema =
|
|
1851
|
+
var EnumOptionSchema = z5.preprocess(
|
|
951
1852
|
(raw) => typeof raw === "string" ? { value: raw } : raw,
|
|
952
|
-
|
|
953
|
-
value:
|
|
954
|
-
label:
|
|
1853
|
+
z5.object({
|
|
1854
|
+
value: z5.string(),
|
|
1855
|
+
label: z5.string().optional(),
|
|
955
1856
|
/** A `#rrggbb` color square before the option's label. */
|
|
956
|
-
swatch:
|
|
1857
|
+
swatch: z5.string().regex(HEX_COLOR).optional()
|
|
957
1858
|
})
|
|
958
1859
|
);
|
|
959
|
-
var NumberParam =
|
|
1860
|
+
var NumberParam = z5.object({
|
|
960
1861
|
...paramBase,
|
|
961
|
-
type:
|
|
962
|
-
default:
|
|
963
|
-
min:
|
|
964
|
-
max:
|
|
1862
|
+
type: z5.literal("number"),
|
|
1863
|
+
default: z5.number(),
|
|
1864
|
+
min: z5.number().optional(),
|
|
1865
|
+
max: z5.number().optional(),
|
|
965
1866
|
/** Whole numbers only. */
|
|
966
|
-
integer:
|
|
1867
|
+
integer: z5.boolean().optional(),
|
|
967
1868
|
/** ArrowUp / ArrowDown increment in the panel (default 1). */
|
|
968
|
-
step:
|
|
1869
|
+
step: z5.number().positive().optional(),
|
|
969
1870
|
/** Shown inside the field before / after the value ("1:", "mm"). */
|
|
970
|
-
prefix:
|
|
971
|
-
suffix:
|
|
1871
|
+
prefix: z5.string().optional(),
|
|
1872
|
+
suffix: z5.string().optional(),
|
|
972
1873
|
/** Standard values offered in the field's dropdown; typing stays free. */
|
|
973
|
-
presets:
|
|
1874
|
+
presets: z5.array(z5.number()).optional()
|
|
974
1875
|
});
|
|
975
|
-
var StringParam =
|
|
1876
|
+
var StringParam = z5.object({
|
|
976
1877
|
...paramBase,
|
|
977
|
-
type:
|
|
978
|
-
default:
|
|
979
|
-
placeholder:
|
|
1878
|
+
type: z5.literal("string"),
|
|
1879
|
+
default: z5.string(),
|
|
1880
|
+
placeholder: z5.string().optional(),
|
|
980
1881
|
/** A textarea; Shift+Enter starts a new line. */
|
|
981
|
-
multiline:
|
|
982
|
-
presets:
|
|
1882
|
+
multiline: z5.boolean().optional(),
|
|
1883
|
+
presets: z5.array(z5.string()).optional()
|
|
983
1884
|
});
|
|
984
|
-
var BooleanParam =
|
|
1885
|
+
var BooleanParam = z5.object({
|
|
985
1886
|
...paramBase,
|
|
986
|
-
type:
|
|
987
|
-
default:
|
|
1887
|
+
type: z5.literal("boolean"),
|
|
1888
|
+
default: z5.boolean(),
|
|
988
1889
|
/** "toggle": a toggle button showing the label (compact, e.g. in a row
|
|
989
1890
|
* beside a picker) instead of a switch. */
|
|
990
|
-
display:
|
|
1891
|
+
display: z5.enum(["switch", "toggle"]).optional()
|
|
991
1892
|
});
|
|
992
|
-
var NumberListParam =
|
|
1893
|
+
var NumberListParam = z5.object({
|
|
993
1894
|
...paramBase,
|
|
994
|
-
type:
|
|
995
|
-
default:
|
|
1895
|
+
type: z5.literal("numberList"),
|
|
1896
|
+
default: z5.array(z5.number()),
|
|
996
1897
|
/** Shown while the list is empty. */
|
|
997
|
-
placeholder:
|
|
998
|
-
min:
|
|
999
|
-
max:
|
|
1000
|
-
presets:
|
|
1898
|
+
placeholder: z5.string().optional(),
|
|
1899
|
+
min: z5.number().optional(),
|
|
1900
|
+
max: z5.number().optional(),
|
|
1901
|
+
presets: z5.array(z5.array(z5.number())).optional()
|
|
1001
1902
|
});
|
|
1002
|
-
var StringListParam =
|
|
1903
|
+
var StringListParam = z5.object({
|
|
1003
1904
|
...paramBase,
|
|
1004
|
-
type:
|
|
1005
|
-
default:
|
|
1905
|
+
type: z5.literal("stringList"),
|
|
1906
|
+
default: z5.array(z5.string()),
|
|
1006
1907
|
/** Shown while the list is empty. */
|
|
1007
|
-
placeholder:
|
|
1008
|
-
presets:
|
|
1908
|
+
placeholder: z5.string().optional(),
|
|
1909
|
+
presets: z5.array(z5.array(z5.string())).optional()
|
|
1009
1910
|
});
|
|
1010
|
-
var ColorParam =
|
|
1911
|
+
var ColorParam = z5.object({
|
|
1011
1912
|
...paramBase,
|
|
1012
|
-
type:
|
|
1013
|
-
default:
|
|
1014
|
-
presets:
|
|
1913
|
+
type: z5.literal("color"),
|
|
1914
|
+
default: z5.string().regex(HEX_COLOR),
|
|
1915
|
+
presets: z5.array(z5.string().regex(HEX_COLOR)).optional()
|
|
1015
1916
|
});
|
|
1016
|
-
var EnumParam =
|
|
1917
|
+
var EnumParam = z5.object({
|
|
1017
1918
|
...paramBase,
|
|
1018
|
-
type:
|
|
1019
|
-
default:
|
|
1020
|
-
options:
|
|
1919
|
+
type: z5.literal("enum"),
|
|
1920
|
+
default: z5.string(),
|
|
1921
|
+
options: z5.array(EnumOptionSchema).min(1),
|
|
1021
1922
|
/** "buttons": a segmented toggle group of the options (short choices);
|
|
1022
1923
|
* the panel falls back to the dropdown when they don't fit. */
|
|
1023
|
-
display:
|
|
1924
|
+
display: z5.enum(["dropdown", "buttons"]).optional()
|
|
1024
1925
|
});
|
|
1025
|
-
var resourceParam = (type, fallback) =>
|
|
1926
|
+
var resourceParam = (type, fallback) => z5.object({
|
|
1026
1927
|
...paramBase,
|
|
1027
|
-
type:
|
|
1028
|
-
default:
|
|
1928
|
+
type: z5.literal(type),
|
|
1929
|
+
default: z5.string().default(fallback)
|
|
1029
1930
|
});
|
|
1030
1931
|
var TextStyleParam = resourceParam("textStyle", "");
|
|
1031
1932
|
var DimStyleParam = resourceParam("dimStyle", "");
|
|
1032
1933
|
var FontParam = resourceParam("font", "arial");
|
|
1033
1934
|
var LineTypeParam = resourceParam("lineType", "continuous");
|
|
1034
1935
|
var HatchPatternParam = resourceParam("hatchPattern", "ANSI31");
|
|
1035
|
-
var LabelParam =
|
|
1936
|
+
var LabelParam = z5.object({ ...paramBase, type: z5.literal("label") });
|
|
1036
1937
|
var enumDefaultIsAnOption = (p) => p.type !== "enum" || p.options.some(
|
|
1037
1938
|
(o) => o.value === p.default
|
|
1038
1939
|
);
|
|
1039
1940
|
var ENUM_DEFAULT = { message: "enum default must be one of its options" };
|
|
1040
|
-
var RowItemSchema =
|
|
1941
|
+
var RowItemSchema = z5.discriminatedUnion("type", [
|
|
1041
1942
|
NumberParam,
|
|
1042
1943
|
StringParam,
|
|
1043
1944
|
BooleanParam,
|
|
@@ -1049,12 +1950,12 @@ var RowItemSchema = z3.discriminatedUnion("type", [
|
|
|
1049
1950
|
LineTypeParam,
|
|
1050
1951
|
HatchPatternParam
|
|
1051
1952
|
]).refine(enumDefaultIsAnOption, ENUM_DEFAULT);
|
|
1052
|
-
var RowParam =
|
|
1953
|
+
var RowParam = z5.object({
|
|
1053
1954
|
...paramBase,
|
|
1054
|
-
type:
|
|
1055
|
-
items:
|
|
1955
|
+
type: z5.literal("row"),
|
|
1956
|
+
items: z5.array(RowItemSchema).min(2).max(3)
|
|
1056
1957
|
});
|
|
1057
|
-
var BlockParamSchema =
|
|
1958
|
+
var BlockParamSchema = z5.discriminatedUnion("type", [
|
|
1058
1959
|
NumberParam,
|
|
1059
1960
|
StringParam,
|
|
1060
1961
|
BooleanParam,
|
|
@@ -1075,7 +1976,7 @@ var valueParams = (defs) => defs.flatMap(
|
|
|
1075
1976
|
);
|
|
1076
1977
|
|
|
1077
1978
|
// ../core/src/extensions/evalBlock.ts
|
|
1078
|
-
import { z as
|
|
1979
|
+
import { z as z7 } from "zod";
|
|
1079
1980
|
|
|
1080
1981
|
// ../core/src/geometry/line.ts
|
|
1081
1982
|
var projectParam = (p, a, b) => {
|
|
@@ -1133,6 +2034,8 @@ var mapObjectPoints = (obj, fn) => {
|
|
|
1133
2034
|
case "hatch":
|
|
1134
2035
|
return {
|
|
1135
2036
|
...obj,
|
|
2037
|
+
// An anchored pattern frame moves with its region.
|
|
2038
|
+
fill: obj.fill.kind === "pattern" && obj.fill.origin ? { ...obj.fill, origin: fn(obj.fill.origin) } : obj.fill,
|
|
1136
2039
|
loops: obj.loops.map((loop) => ({
|
|
1137
2040
|
points: loop.points.map((v) => ({ ...v, ...fn(v) }))
|
|
1138
2041
|
}))
|
|
@@ -1178,6 +2081,7 @@ var moveViewportCenter = (obj, map) => {
|
|
|
1178
2081
|
const nc = map(c);
|
|
1179
2082
|
return translateObject(obj, sub(nc, c));
|
|
1180
2083
|
};
|
|
2084
|
+
var turnFill = (fill, f) => fill.kind === "pattern" || fill.kind === "lines" ? { ...fill, angle: f(fill.angle) } : fill;
|
|
1181
2085
|
var rotateObject = (obj, center, ang) => {
|
|
1182
2086
|
const r = (p) => rotAround(p, center, ang);
|
|
1183
2087
|
const mapped = mapObjectPoints(obj, r);
|
|
@@ -1194,7 +2098,7 @@ var rotateObject = (obj, center, ang) => {
|
|
|
1194
2098
|
case "table":
|
|
1195
2099
|
return { ...mapped, rotation: mapped.rotation + ang };
|
|
1196
2100
|
case "dimension":
|
|
1197
|
-
return { ...mapped,
|
|
2101
|
+
return mapped.rotation === void 0 ? mapped : { ...mapped, rotation: mapped.rotation + ang };
|
|
1198
2102
|
case "block":
|
|
1199
2103
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, rotation: mapped.rotation + ang };
|
|
1200
2104
|
case "viewport":
|
|
@@ -1202,11 +2106,12 @@ var rotateObject = (obj, center, ang) => {
|
|
|
1202
2106
|
case "image":
|
|
1203
2107
|
case "reference":
|
|
1204
2108
|
return { ...mapped, rotation: normAngle(mapped.rotation + ang) };
|
|
2109
|
+
case "hatch":
|
|
2110
|
+
return { ...mapped, fill: turnFill(mapped.fill, (a) => a + ang) };
|
|
1205
2111
|
case "line":
|
|
1206
2112
|
case "point":
|
|
1207
2113
|
case "polyline":
|
|
1208
2114
|
case "circle":
|
|
1209
|
-
case "hatch":
|
|
1210
2115
|
case "comment":
|
|
1211
2116
|
return mapped;
|
|
1212
2117
|
default:
|
|
@@ -1231,7 +2136,16 @@ var scaleObjectUniform = (obj, s) => {
|
|
|
1231
2136
|
case "table":
|
|
1232
2137
|
return { ...mapped, scale: mapped.scale * s };
|
|
1233
2138
|
case "dimension":
|
|
1234
|
-
return {
|
|
2139
|
+
return {
|
|
2140
|
+
...mapped,
|
|
2141
|
+
...mapped.offset === void 0 ? {} : { offset: mapped.offset * s },
|
|
2142
|
+
labels: mapped.labels.map((l) => ({
|
|
2143
|
+
...l,
|
|
2144
|
+
...l.along === void 0 ? {} : { along: l.along * s },
|
|
2145
|
+
...l.across === void 0 ? {} : { across: l.across * s }
|
|
2146
|
+
})),
|
|
2147
|
+
scale: mapped.scale * s
|
|
2148
|
+
};
|
|
1235
2149
|
case "block":
|
|
1236
2150
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, scale: mapped.scale * s };
|
|
1237
2151
|
case "viewport":
|
|
@@ -1317,6 +2231,7 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1317
2231
|
case "hatch":
|
|
1318
2232
|
return {
|
|
1319
2233
|
...mapped,
|
|
2234
|
+
fill: turnFill(mapped.fill, mirrorAngle),
|
|
1320
2235
|
loops: mapped.loops.map((loop) => ({
|
|
1321
2236
|
points: loop.points.map((v) => ({ ...v, bulge: -v.bulge }))
|
|
1322
2237
|
}))
|
|
@@ -1331,8 +2246,17 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1331
2246
|
hAlign: readable ? mapped.hAlign : swap[mapped.hAlign]
|
|
1332
2247
|
};
|
|
1333
2248
|
}
|
|
1334
|
-
case "dimension":
|
|
1335
|
-
|
|
2249
|
+
case "dimension": {
|
|
2250
|
+
const handed = mapped.kind === "radial" || mapped.kind === "diameter";
|
|
2251
|
+
return {
|
|
2252
|
+
...mapped,
|
|
2253
|
+
...mapped.rotation === void 0 ? {} : { rotation: mirrorAngle(mapped.rotation) },
|
|
2254
|
+
...mapped.offset === void 0 ? {} : { offset: -mapped.offset },
|
|
2255
|
+
labels: handed ? mapped.labels.map(
|
|
2256
|
+
(l) => l.across === void 0 ? l : { ...l, across: -l.across }
|
|
2257
|
+
) : mapped.labels
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
1336
2260
|
case "block":
|
|
1337
2261
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, rotation: mirrorAngle(mapped.rotation) };
|
|
1338
2262
|
case "viewport":
|
|
@@ -1354,7 +2278,7 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1354
2278
|
};
|
|
1355
2279
|
|
|
1356
2280
|
// ../core/src/extensions/blockDtos.ts
|
|
1357
|
-
import { z as
|
|
2281
|
+
import { z as z6 } from "zod";
|
|
1358
2282
|
|
|
1359
2283
|
// ../core/src/extensions/jsLiteral.ts
|
|
1360
2284
|
var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
@@ -1386,7 +2310,7 @@ ${indent}}`;
|
|
|
1386
2310
|
};
|
|
1387
2311
|
|
|
1388
2312
|
// ../core/src/model/migrations.ts
|
|
1389
|
-
var CURRENT_DOCUMENT_VERSION =
|
|
2313
|
+
var CURRENT_DOCUMENT_VERSION = 22;
|
|
1390
2314
|
var leaderRawToText = (raw) => {
|
|
1391
2315
|
const points = Array.isArray(raw.points) ? raw.points : [];
|
|
1392
2316
|
const extraLines = Array.isArray(raw.extraLines) ? raw.extraLines : [];
|
|
@@ -1888,6 +2812,92 @@ var migrateV18toV19 = (doc) => {
|
|
|
1888
2812
|
};
|
|
1889
2813
|
};
|
|
1890
2814
|
var migrateV19toV20 = (doc) => ({ ...swapTextAlignments(doc), version: 20 });
|
|
2815
|
+
var dimensionPointCount = (kind) => kind === "angular" ? 3 : 2;
|
|
2816
|
+
var wrapAngle = (a) => {
|
|
2817
|
+
const twoPi = 2 * Math.PI;
|
|
2818
|
+
const r = a % twoPi;
|
|
2819
|
+
return r < 0 ? r + twoPi : r;
|
|
2820
|
+
};
|
|
2821
|
+
var dimensionRawToLabels = (raw) => {
|
|
2822
|
+
if (raw.type !== "dimension") return raw;
|
|
2823
|
+
const legacyOffset = Array.isArray(raw.offset) ? { x: Number(raw.offset[0]), y: Number(raw.offset[1]) } : raw.offset !== null && typeof raw.offset === "object" ? raw.offset : null;
|
|
2824
|
+
if (legacyOffset === null && !("textOverride" in raw)) return raw;
|
|
2825
|
+
const kind = typeof raw.kind === "string" ? raw.kind : "linear";
|
|
2826
|
+
const points = Array.isArray(raw.points) ? raw.points : [];
|
|
2827
|
+
const tooFew = points.length < dimensionPointCount(kind);
|
|
2828
|
+
const out = { ...raw };
|
|
2829
|
+
delete out.textOverride;
|
|
2830
|
+
const labels = Array.isArray(raw.labels) ? raw.labels.map((l) => ({ ...l })) : [];
|
|
2831
|
+
const label = (i) => labels[i] ??= {};
|
|
2832
|
+
if (legacyOffset) {
|
|
2833
|
+
const v = legacyOffset;
|
|
2834
|
+
const vLen = Math.hypot(v.x, v.y);
|
|
2835
|
+
if (kind === "linear") {
|
|
2836
|
+
delete out.rotation;
|
|
2837
|
+
if (vLen < 1e-9 || tooFew) out.offset = 0;
|
|
2838
|
+
else {
|
|
2839
|
+
let ux = -v.y / vLen;
|
|
2840
|
+
let uy = v.x / vLen;
|
|
2841
|
+
if (ux < 0 || ux === 0 && uy < 0) {
|
|
2842
|
+
ux = -ux;
|
|
2843
|
+
uy = -uy;
|
|
2844
|
+
}
|
|
2845
|
+
out.rotation = Math.atan2(uy, ux);
|
|
2846
|
+
out.offset = v.x * -uy + v.y * ux;
|
|
2847
|
+
}
|
|
2848
|
+
} else if (kind === "angular") {
|
|
2849
|
+
if (tooFew) out.offset = vLen;
|
|
2850
|
+
else {
|
|
2851
|
+
const [vertex, a, b] = points;
|
|
2852
|
+
const angA = Math.atan2(a.y - vertex.y, a.x - vertex.x);
|
|
2853
|
+
const angB = Math.atan2(b.y - vertex.y, b.x - vertex.x);
|
|
2854
|
+
const angL = Math.atan2(v.y, v.x);
|
|
2855
|
+
const inAB = wrapAngle(angL - angA) <= wrapAngle(angB - angA);
|
|
2856
|
+
out.offset = inAB ? vLen : -vLen;
|
|
2857
|
+
}
|
|
2858
|
+
} else {
|
|
2859
|
+
delete out.offset;
|
|
2860
|
+
const [p0, p1] = points;
|
|
2861
|
+
const d = tooFew ? 0 : Math.hypot(p1.x - p0.x, p1.y - p0.y);
|
|
2862
|
+
if (d > 1e-9) {
|
|
2863
|
+
const ux = (p1.x - p0.x) / d;
|
|
2864
|
+
const uy = (p1.y - p0.y) / d;
|
|
2865
|
+
label(0).along = v.x * ux + v.y * uy;
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
if (typeof raw.textOverride === "string") {
|
|
2870
|
+
const template = {
|
|
2871
|
+
linear: "{value}",
|
|
2872
|
+
angular: "{value}\xB0",
|
|
2873
|
+
radial: "R{value}",
|
|
2874
|
+
diameter: "\xD8{value}"
|
|
2875
|
+
};
|
|
2876
|
+
const content = raw.textOverride.replaceAll(
|
|
2877
|
+
"<>",
|
|
2878
|
+
template[kind] ?? "{value}"
|
|
2879
|
+
);
|
|
2880
|
+
const segments = kind === "linear" ? Math.max(1, points.length - 1) : 1;
|
|
2881
|
+
for (let i = 0; i < segments; i++) label(i).content = content;
|
|
2882
|
+
}
|
|
2883
|
+
if (labels.length > 0) out.labels = labels;
|
|
2884
|
+
return out;
|
|
2885
|
+
};
|
|
2886
|
+
var migrateV20toV21 = (doc) => {
|
|
2887
|
+
const degenerate = (raw) => raw.type === "dimension" && (Array.isArray(raw.points) ? raw.points.length : 0) < dimensionPointCount(typeof raw.kind === "string" ? raw.kind : "linear");
|
|
2888
|
+
const mapObjects = (list) => Array.isArray(list) ? list.filter(
|
|
2889
|
+
(raw) => raw === null || typeof raw !== "object" || !degenerate(raw)
|
|
2890
|
+
).map(
|
|
2891
|
+
(raw) => raw !== null && typeof raw === "object" ? dimensionRawToLabels(raw) : raw
|
|
2892
|
+
) : list;
|
|
2893
|
+
const layouts = Array.isArray(doc.layouts) ? doc.layouts.map((raw) => {
|
|
2894
|
+
if (raw === null || typeof raw !== "object") return raw;
|
|
2895
|
+
const layout = raw;
|
|
2896
|
+
return { ...layout, objects: mapObjects(layout.objects) };
|
|
2897
|
+
}) : doc.layouts;
|
|
2898
|
+
return { ...doc, objects: mapObjects(doc.objects), layouts, version: 21 };
|
|
2899
|
+
};
|
|
2900
|
+
var migrateV21toV22 = (doc) => ({ ...doc, version: 22 });
|
|
1891
2901
|
var MIGRATION_STEPS = [
|
|
1892
2902
|
migrateV1toV2,
|
|
1893
2903
|
migrateV2toV3,
|
|
@@ -1907,7 +2917,9 @@ var MIGRATION_STEPS = [
|
|
|
1907
2917
|
migrateV16toV17,
|
|
1908
2918
|
migrateV17toV18,
|
|
1909
2919
|
migrateV18toV19,
|
|
1910
|
-
migrateV19toV20
|
|
2920
|
+
migrateV19toV20,
|
|
2921
|
+
migrateV20toV21,
|
|
2922
|
+
migrateV21toV22
|
|
1911
2923
|
];
|
|
1912
2924
|
function migrateDocument(raw) {
|
|
1913
2925
|
if (raw === null || typeof raw !== "object") return raw;
|
|
@@ -1926,7 +2938,8 @@ function migrateDocument(raw) {
|
|
|
1926
2938
|
|
|
1927
2939
|
// ../core/src/extensions/blockDtos.ts
|
|
1928
2940
|
var CHILD_OMIT = { id: true, layerId: true };
|
|
1929
|
-
var
|
|
2941
|
+
var CHILD_LAYER = { layerId: z6.string().optional() };
|
|
2942
|
+
var BlockChildSchema = z6.preprocess(
|
|
1930
2943
|
// Back-compat: scripts written before document v6 may still emit "leader"
|
|
1931
2944
|
// children (→ text with leaderLines), pre-v9 scripts may emit dimensions
|
|
1932
2945
|
// in the linePoint/rotation shape (→ offset), pre-v17 scripts may put
|
|
@@ -1939,27 +2952,29 @@ var BlockChildSchema = z4.preprocess(
|
|
|
1939
2952
|
let obj = raw;
|
|
1940
2953
|
if (obj.type === "leader") obj = leaderRawToText(obj);
|
|
1941
2954
|
if (obj.type === "dimension")
|
|
1942
|
-
return
|
|
2955
|
+
return dimensionRawToLabels(
|
|
2956
|
+
dimRawScaleToField(dimensionRawToOffset(obj))
|
|
2957
|
+
);
|
|
1943
2958
|
if (obj.type === "text") return textRawStyleToOverride(obj);
|
|
1944
2959
|
return obj;
|
|
1945
2960
|
},
|
|
1946
|
-
|
|
1947
|
-
LineSchema.omit(CHILD_OMIT),
|
|
1948
|
-
PointSchema.omit(CHILD_OMIT),
|
|
1949
|
-
PolylineSchema.omit(CHILD_OMIT),
|
|
1950
|
-
CircleSchema.omit(CHILD_OMIT),
|
|
1951
|
-
ArcSchema.omit(CHILD_OMIT),
|
|
1952
|
-
EllipseSchema.omit(CHILD_OMIT),
|
|
1953
|
-
HatchSchema.omit(CHILD_OMIT),
|
|
1954
|
-
TextSchema.omit(CHILD_OMIT),
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
)
|
|
2961
|
+
z6.discriminatedUnion("type", [
|
|
2962
|
+
LineSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2963
|
+
PointSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2964
|
+
PolylineSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2965
|
+
CircleSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2966
|
+
ArcSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2967
|
+
EllipseSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2968
|
+
HatchSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2969
|
+
TextSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
2970
|
+
TableShapeSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).superRefine(tableRefinement),
|
|
2971
|
+
DimensionShapeSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).superRefine(dimensionRefinement),
|
|
2972
|
+
BlockSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).refine((b) => b.inputs.every((v) => typeof v !== "string"), {
|
|
2973
|
+
message: "nested block instances may not carry object references"
|
|
2974
|
+
})
|
|
1960
2975
|
])
|
|
1961
2976
|
);
|
|
1962
|
-
var BlockScriptResultSchema =
|
|
2977
|
+
var BlockScriptResultSchema = z6.array(BlockChildSchema);
|
|
1963
2978
|
|
|
1964
2979
|
// ../core/src/extensions/scriptHelpers.ts
|
|
1965
2980
|
var scriptHelpers_exports = {};
|
|
@@ -2146,13 +3161,13 @@ var toBlockModule = (mod) => {
|
|
|
2146
3161
|
);
|
|
2147
3162
|
return { ...mod, draw, place };
|
|
2148
3163
|
};
|
|
2149
|
-
var ParamsExportSchema =
|
|
2150
|
-
var OptionalBlockMetaSchema =
|
|
2151
|
-
description:
|
|
2152
|
-
version:
|
|
2153
|
-
authors:
|
|
2154
|
-
tags:
|
|
2155
|
-
dependencies:
|
|
3164
|
+
var ParamsExportSchema = z7.array(BlockParamSchema);
|
|
3165
|
+
var OptionalBlockMetaSchema = z7.object({
|
|
3166
|
+
description: z7.string().optional(),
|
|
3167
|
+
version: z7.string().optional(),
|
|
3168
|
+
authors: z7.array(z7.string()).optional(),
|
|
3169
|
+
tags: z7.array(z7.string()).optional(),
|
|
3170
|
+
dependencies: z7.array(z7.string()).optional()
|
|
2156
3171
|
});
|
|
2157
3172
|
var parseParamsExport = (paramsExport) => {
|
|
2158
3173
|
if (typeof paramsExport === "function") {
|
|
@@ -2288,7 +3303,7 @@ var stylesSig = (s) => {
|
|
|
2288
3303
|
};
|
|
2289
3304
|
return `${sig(s.textStyles)}.${sig(s.dimStyles)}`;
|
|
2290
3305
|
};
|
|
2291
|
-
var ParamVisibilityResultSchema =
|
|
3306
|
+
var ParamVisibilityResultSchema = z7.record(z7.string(), z7.boolean());
|
|
2292
3307
|
var paramsKey = (params) => JSON.stringify(Object.entries(params).sort(([a], [b]) => a.localeCompare(b)));
|
|
2293
3308
|
var r6 = (v) => Math.round(v * 1e6) / 1e6;
|
|
2294
3309
|
var sigOf = (v) => typeof v === "string" ? `#${v}` : `${r6(v.x)},${r6(v.y)}`;
|
|
@@ -2314,7 +3329,7 @@ var resolveInputs = (inputs, pivot, resolve) => {
|
|
|
2314
3329
|
return obj ? translateObject(obj, neg) : null;
|
|
2315
3330
|
});
|
|
2316
3331
|
};
|
|
2317
|
-
var BlockInputsSchema =
|
|
3332
|
+
var BlockInputsSchema = z7.array(z7.union([Vec2Schema, z7.string()]));
|
|
2318
3333
|
var acquireBlockInputs = async (script, pickers) => {
|
|
2319
3334
|
const { mod, meta } = compileBlock(script);
|
|
2320
3335
|
if (!mod.place) return [await pickers.pickPoint("Insertion point")];
|
|
@@ -2418,7 +3433,7 @@ var childToObject = (child, instance, index) => {
|
|
|
2418
3433
|
lineWidth: instance.lineWidth,
|
|
2419
3434
|
...child,
|
|
2420
3435
|
id: `${instance.id}:${index}`,
|
|
2421
|
-
layerId: instance.layerId
|
|
3436
|
+
layerId: child.layerId ?? instance.layerId
|
|
2422
3437
|
};
|
|
2423
3438
|
};
|
|
2424
3439
|
var evaluating = /* @__PURE__ */ new Set();
|
|
@@ -2516,259 +3531,42 @@ var indexOf = (doc) => {
|
|
|
2516
3531
|
var resolveDocumentObject = (doc, id) => indexOf(doc).get(id);
|
|
2517
3532
|
var documentObjectResolver = (doc) => (id) => resolveDocumentObject(doc, id);
|
|
2518
3533
|
|
|
2519
|
-
// ../core/src/paint/
|
|
2520
|
-
var
|
|
2521
|
-
var
|
|
2522
|
-
|
|
2523
|
-
|
|
3534
|
+
// ../core/src/paint/textMetrics.ts
|
|
3535
|
+
var LINE_HEIGHT_FACTOR = 1.66;
|
|
3536
|
+
var TAB_SIZE_FACTOR = 4;
|
|
3537
|
+
var boundMeasurer = (measure, font, widthFactor) => font === void 0 && widthFactor === void 0 ? measure : {
|
|
3538
|
+
measureTextWidth: (text, heightMm) => measure.measureTextWidth(text, heightMm, font, widthFactor)
|
|
2524
3539
|
};
|
|
2525
|
-
var
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
3540
|
+
var lineSegments = (line, heightMm, measure) => {
|
|
3541
|
+
if (!line.includes(" ")) return [{ text: line, x: 0 }];
|
|
3542
|
+
const tab = heightMm * TAB_SIZE_FACTOR;
|
|
3543
|
+
const out = [];
|
|
3544
|
+
let x = 0;
|
|
3545
|
+
const parts = line.split(" ");
|
|
3546
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3547
|
+
if (i > 0) x = (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
3548
|
+
out.push({ text: parts[i], x });
|
|
3549
|
+
x += measure.measureTextWidth(parts[i], heightMm);
|
|
3550
|
+
}
|
|
3551
|
+
return out;
|
|
2534
3552
|
};
|
|
2535
|
-
var
|
|
2536
|
-
const
|
|
2537
|
-
const
|
|
2538
|
-
return
|
|
2539
|
-
content,
|
|
2540
|
-
anchor: add(at, scale(textUp, style.textOffset * style.scale)),
|
|
2541
|
-
rotation,
|
|
2542
|
-
height: style.textHeight * style.scale,
|
|
2543
|
-
font: dimFontFace(style),
|
|
2544
|
-
widthFactor: style.widthFactor
|
|
2545
|
-
};
|
|
3553
|
+
var lineWidthWithTabs = (line, heightMm, measure) => {
|
|
3554
|
+
const segs = lineSegments(line, heightMm, measure);
|
|
3555
|
+
const last = segs[segs.length - 1];
|
|
3556
|
+
return last.x + measure.measureTextWidth(last.text, heightMm);
|
|
2546
3557
|
};
|
|
2547
|
-
var
|
|
2548
|
-
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2551
|
-
const
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
points.forEach((p, i) => {
|
|
2560
|
-
const f = feet[i];
|
|
2561
|
-
const gap = dist(p, f);
|
|
2562
|
-
if (gap < 1e-9) return;
|
|
2563
|
-
const w = norm(sub(f, p));
|
|
2564
|
-
extensionLines.push({
|
|
2565
|
-
a: style.extensionType === "short" ? sub(f, scale(w, style.extensionOvershoot * s)) : add(p, scale(w, Math.min(style.extensionOffset * s, gap))),
|
|
2566
|
-
b: add(f, scale(w, style.extensionOvershoot * s))
|
|
2567
|
-
});
|
|
2568
|
-
});
|
|
2569
|
-
const dimLines = [];
|
|
2570
|
-
const arrows = [];
|
|
2571
|
-
const texts = [];
|
|
2572
|
-
for (let i = 0; i + 1 < feet.length; i++) {
|
|
2573
|
-
const a = feet[i];
|
|
2574
|
-
const b = feet[i + 1];
|
|
2575
|
-
const value = dist(a, b);
|
|
2576
|
-
if (value < 1e-9) continue;
|
|
2577
|
-
dimLines.push({ a, b });
|
|
2578
|
-
arrows.push(
|
|
2579
|
-
{ tip: a, toward: b, size: style.arrowSize * s },
|
|
2580
|
-
{ tip: b, toward: a, size: style.arrowSize * s }
|
|
2581
|
-
);
|
|
2582
|
-
texts.push(
|
|
2583
|
-
textFor(
|
|
2584
|
-
obj.textOverride ?? formatDimValue(value, style.precision),
|
|
2585
|
-
mid(a, b),
|
|
2586
|
-
u,
|
|
2587
|
-
style
|
|
2588
|
-
)
|
|
2589
|
-
);
|
|
2590
|
-
}
|
|
2591
|
-
if (dimLines.length === 0) return null;
|
|
2592
|
-
return {
|
|
2593
|
-
extensionLines,
|
|
2594
|
-
dimLines,
|
|
2595
|
-
dimArc: null,
|
|
2596
|
-
arrows,
|
|
2597
|
-
arrowType: style.arrowType,
|
|
2598
|
-
texts,
|
|
2599
|
-
value: dist(feet[0], feet[feet.length - 1])
|
|
2600
|
-
};
|
|
2601
|
-
};
|
|
2602
|
-
var angularGeometry = (obj, style) => {
|
|
2603
|
-
if (obj.points.length < 3) return null;
|
|
2604
|
-
const s = style.scale;
|
|
2605
|
-
const [vertex, a, b] = obj.points;
|
|
2606
|
-
const radius = len(obj.offset);
|
|
2607
|
-
const da = dist(vertex, a);
|
|
2608
|
-
const db = dist(vertex, b);
|
|
2609
|
-
if (radius < 1e-9 || da < 1e-9 || db < 1e-9) return null;
|
|
2610
|
-
const angA = angle(sub(a, vertex));
|
|
2611
|
-
const angB = angle(sub(b, vertex));
|
|
2612
|
-
const angL = angle(obj.offset);
|
|
2613
|
-
const sweepAB = normAngle(angB - angA);
|
|
2614
|
-
const inAB = normAngle(angL - angA) <= sweepAB;
|
|
2615
|
-
const start = inAB ? angA : angB;
|
|
2616
|
-
const sweep = inAB ? sweepAB : normAngle(angA - angB);
|
|
2617
|
-
if (sweep < 1e-9) return null;
|
|
2618
|
-
const at = (t) => add(vertex, scale(fromAngle(start + t), radius));
|
|
2619
|
-
const extensionLines = [];
|
|
2620
|
-
for (const [p, d] of [
|
|
2621
|
-
[a, da],
|
|
2622
|
-
[b, db]
|
|
2623
|
-
]) {
|
|
2624
|
-
const w = norm(sub(p, vertex));
|
|
2625
|
-
const inner = style.extensionType === "short" ? radius - style.extensionOvershoot * s : Math.min(d + style.extensionOffset * s, radius);
|
|
2626
|
-
const outer = radius + style.extensionOvershoot * s;
|
|
2627
|
-
if (outer - inner > 1e-9)
|
|
2628
|
-
extensionLines.push({
|
|
2629
|
-
a: add(vertex, scale(w, inner)),
|
|
2630
|
-
b: add(vertex, scale(w, outer))
|
|
2631
|
-
});
|
|
2632
|
-
}
|
|
2633
|
-
const tangentStep = Math.min(sweep / 3, style.arrowSize * s * 2 / radius);
|
|
2634
|
-
const valueDeg = sweep * RAD2DEG;
|
|
2635
|
-
const midPoint = at(sweep / 2);
|
|
2636
|
-
const midTangent = perp(norm(sub(midPoint, vertex)));
|
|
2637
|
-
return {
|
|
2638
|
-
extensionLines,
|
|
2639
|
-
dimLines: [],
|
|
2640
|
-
dimArc: {
|
|
2641
|
-
center: vertex,
|
|
2642
|
-
radius,
|
|
2643
|
-
startAngle: start,
|
|
2644
|
-
endAngle: start + sweep
|
|
2645
|
-
},
|
|
2646
|
-
arrows: [
|
|
2647
|
-
{ tip: at(0), toward: at(tangentStep), size: style.arrowSize * s },
|
|
2648
|
-
{
|
|
2649
|
-
tip: at(sweep),
|
|
2650
|
-
toward: at(sweep - tangentStep),
|
|
2651
|
-
size: style.arrowSize * s
|
|
2652
|
-
}
|
|
2653
|
-
],
|
|
2654
|
-
arrowType: style.arrowType,
|
|
2655
|
-
texts: [
|
|
2656
|
-
textFor(
|
|
2657
|
-
obj.textOverride ?? `${formatDimValue(valueDeg, style.precision)}\xB0`,
|
|
2658
|
-
midPoint,
|
|
2659
|
-
midTangent,
|
|
2660
|
-
style
|
|
2661
|
-
)
|
|
2662
|
-
],
|
|
2663
|
-
value: sweep
|
|
2664
|
-
};
|
|
2665
|
-
};
|
|
2666
|
-
var radialGeometry = (obj, style) => {
|
|
2667
|
-
if (obj.points.length < 2) return null;
|
|
2668
|
-
const s = style.scale;
|
|
2669
|
-
const [center, p] = obj.points;
|
|
2670
|
-
const r = dist(center, p);
|
|
2671
|
-
if (r < 1e-9) return null;
|
|
2672
|
-
const u = norm(sub(p, center));
|
|
2673
|
-
const t = Math.max(dot(obj.offset, u), r * 0.2);
|
|
2674
|
-
const textAt = add(center, scale(u, t));
|
|
2675
|
-
return {
|
|
2676
|
-
extensionLines: [],
|
|
2677
|
-
// The line runs center → text position (through the curve point).
|
|
2678
|
-
dimLines: [{ a: center, b: t > r ? textAt : p }],
|
|
2679
|
-
dimArc: null,
|
|
2680
|
-
arrows: [{ tip: p, toward: center, size: style.arrowSize * s }],
|
|
2681
|
-
arrowType: style.arrowType,
|
|
2682
|
-
texts: [
|
|
2683
|
-
textFor(
|
|
2684
|
-
obj.textOverride ?? `R${formatDimValue(r, style.precision)}`,
|
|
2685
|
-
textAt,
|
|
2686
|
-
u,
|
|
2687
|
-
style
|
|
2688
|
-
)
|
|
2689
|
-
],
|
|
2690
|
-
value: r
|
|
2691
|
-
};
|
|
2692
|
-
};
|
|
2693
|
-
var diameterGeometry = (obj, style) => {
|
|
2694
|
-
if (obj.points.length < 2) return null;
|
|
2695
|
-
const s = style.scale;
|
|
2696
|
-
const [p1, p2] = obj.points;
|
|
2697
|
-
const d = dist(p1, p2);
|
|
2698
|
-
if (d < 1e-9) return null;
|
|
2699
|
-
const u = norm(sub(p2, p1));
|
|
2700
|
-
const t = dot(sub(add(mid(p1, p2), obj.offset), p1), u);
|
|
2701
|
-
const textAt = add(p1, scale(u, Math.min(Math.max(t, d * 0.15), d * 0.85)));
|
|
2702
|
-
return {
|
|
2703
|
-
extensionLines: [],
|
|
2704
|
-
dimLines: [{ a: p1, b: p2 }],
|
|
2705
|
-
dimArc: null,
|
|
2706
|
-
arrows: [
|
|
2707
|
-
{ tip: p1, toward: p2, size: style.arrowSize * s },
|
|
2708
|
-
{ tip: p2, toward: p1, size: style.arrowSize * s }
|
|
2709
|
-
],
|
|
2710
|
-
arrowType: style.arrowType,
|
|
2711
|
-
texts: [
|
|
2712
|
-
textFor(
|
|
2713
|
-
obj.textOverride ?? `\xD8${formatDimValue(d, style.precision)}`,
|
|
2714
|
-
textAt,
|
|
2715
|
-
u,
|
|
2716
|
-
style
|
|
2717
|
-
)
|
|
2718
|
-
],
|
|
2719
|
-
value: d
|
|
2720
|
-
};
|
|
2721
|
-
};
|
|
2722
|
-
var dimensionGeometry = (obj, styles) => {
|
|
2723
|
-
const style = resolveDimStyle(obj, styles);
|
|
2724
|
-
switch (obj.kind) {
|
|
2725
|
-
case "angular":
|
|
2726
|
-
return angularGeometry(obj, style);
|
|
2727
|
-
case "radial":
|
|
2728
|
-
return radialGeometry(obj, style);
|
|
2729
|
-
case "diameter":
|
|
2730
|
-
return diameterGeometry(obj, style);
|
|
2731
|
-
case "linear":
|
|
2732
|
-
return linearGeometry(obj, style);
|
|
2733
|
-
}
|
|
2734
|
-
};
|
|
2735
|
-
|
|
2736
|
-
// ../core/src/paint/textMetrics.ts
|
|
2737
|
-
var LINE_HEIGHT_FACTOR = 1.66;
|
|
2738
|
-
var TAB_SIZE_FACTOR = 4;
|
|
2739
|
-
var boundMeasurer = (measure, font, widthFactor) => font === void 0 && widthFactor === void 0 ? measure : {
|
|
2740
|
-
measureTextWidth: (text, heightMm) => measure.measureTextWidth(text, heightMm, font, widthFactor)
|
|
2741
|
-
};
|
|
2742
|
-
var lineSegments = (line, heightMm, measure) => {
|
|
2743
|
-
if (!line.includes(" ")) return [{ text: line, x: 0 }];
|
|
2744
|
-
const tab = heightMm * TAB_SIZE_FACTOR;
|
|
2745
|
-
const out = [];
|
|
2746
|
-
let x = 0;
|
|
2747
|
-
const parts = line.split(" ");
|
|
2748
|
-
for (let i = 0; i < parts.length; i++) {
|
|
2749
|
-
if (i > 0) x = (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
2750
|
-
out.push({ text: parts[i], x });
|
|
2751
|
-
x += measure.measureTextWidth(parts[i], heightMm);
|
|
2752
|
-
}
|
|
2753
|
-
return out;
|
|
2754
|
-
};
|
|
2755
|
-
var lineWidthWithTabs = (line, heightMm, measure) => {
|
|
2756
|
-
const segs = lineSegments(line, heightMm, measure);
|
|
2757
|
-
const last = segs[segs.length - 1];
|
|
2758
|
-
return last.x + measure.measureTextWidth(last.text, heightMm);
|
|
2759
|
-
};
|
|
2760
|
-
var wrapWords = (line, heightMm, measure, maxWidthMm) => {
|
|
2761
|
-
const words = line.split(" ");
|
|
2762
|
-
const out = [];
|
|
2763
|
-
let cur = "";
|
|
2764
|
-
for (const w of words) {
|
|
2765
|
-
const trial = cur ? `${cur} ${w}` : w;
|
|
2766
|
-
if (cur && measure.measureTextWidth(trial, heightMm) > maxWidthMm) {
|
|
2767
|
-
out.push(cur);
|
|
2768
|
-
cur = w;
|
|
2769
|
-
} else {
|
|
2770
|
-
cur = trial;
|
|
2771
|
-
}
|
|
3558
|
+
var wrapWords = (line, heightMm, measure, maxWidthMm) => {
|
|
3559
|
+
const words = line.split(" ");
|
|
3560
|
+
const out = [];
|
|
3561
|
+
let cur = "";
|
|
3562
|
+
for (const w of words) {
|
|
3563
|
+
const trial = cur ? `${cur} ${w}` : w;
|
|
3564
|
+
if (cur && measure.measureTextWidth(trial, heightMm) > maxWidthMm) {
|
|
3565
|
+
out.push(cur);
|
|
3566
|
+
cur = w;
|
|
3567
|
+
} else {
|
|
3568
|
+
cur = trial;
|
|
3569
|
+
}
|
|
2772
3570
|
}
|
|
2773
3571
|
out.push(cur);
|
|
2774
3572
|
return out;
|
|
@@ -2802,6 +3600,203 @@ var textBlock = (content, heightMm, measure, maxWidthMm) => {
|
|
|
2802
3600
|
};
|
|
2803
3601
|
};
|
|
2804
3602
|
|
|
3603
|
+
// ../core/src/paint/richText.ts
|
|
3604
|
+
var ATTR_KEYS = [
|
|
3605
|
+
"font",
|
|
3606
|
+
"bold",
|
|
3607
|
+
"italic",
|
|
3608
|
+
"underline",
|
|
3609
|
+
"color",
|
|
3610
|
+
"height",
|
|
3611
|
+
"script"
|
|
3612
|
+
];
|
|
3613
|
+
var SCRIPT_SCALE = 0.6;
|
|
3614
|
+
var SUPER_RISE = 0.45;
|
|
3615
|
+
var SUB_DROP = 0.2;
|
|
3616
|
+
var attrsOf = (s) => {
|
|
3617
|
+
const out = {};
|
|
3618
|
+
for (const k of ATTR_KEYS) if (s[k] !== void 0) out[k] = s[k];
|
|
3619
|
+
return out;
|
|
3620
|
+
};
|
|
3621
|
+
var sameAttrs = (a, b) => ATTR_KEYS.every((k) => a[k] === b[k]);
|
|
3622
|
+
var isEmpty = (a) => ATTR_KEYS.every((k) => a[k] === void 0);
|
|
3623
|
+
var snap = (i, content) => {
|
|
3624
|
+
const c = Math.max(0, Math.min(content.length, Math.round(i)));
|
|
3625
|
+
const code = content.charCodeAt(c);
|
|
3626
|
+
return c > 0 && code >= 56320 && code <= 57343 ? c - 1 : c;
|
|
3627
|
+
};
|
|
3628
|
+
var toIntervals = (spans, content, extra = []) => {
|
|
3629
|
+
const cuts = /* @__PURE__ */ new Set([0, content.length]);
|
|
3630
|
+
for (const s of spans ?? []) {
|
|
3631
|
+
cuts.add(snap(s.start, content));
|
|
3632
|
+
cuts.add(snap(s.end, content));
|
|
3633
|
+
}
|
|
3634
|
+
for (const c of extra) cuts.add(snap(c, content));
|
|
3635
|
+
const sorted = [...cuts].sort((a, b) => a - b);
|
|
3636
|
+
const out = [];
|
|
3637
|
+
for (let i = 0; i + 1 < sorted.length; i++) {
|
|
3638
|
+
const start = sorted[i];
|
|
3639
|
+
const end = sorted[i + 1];
|
|
3640
|
+
let attrs = {};
|
|
3641
|
+
for (const s of spans ?? [])
|
|
3642
|
+
if (snap(s.start, content) <= start && snap(s.end, content) >= end)
|
|
3643
|
+
attrs = { ...attrs, ...attrsOf(s) };
|
|
3644
|
+
out.push({ start, end, attrs });
|
|
3645
|
+
}
|
|
3646
|
+
return out;
|
|
3647
|
+
};
|
|
3648
|
+
var fromIntervals = (intervals) => {
|
|
3649
|
+
const out = [];
|
|
3650
|
+
for (const iv of intervals) {
|
|
3651
|
+
if (iv.end <= iv.start || isEmpty(iv.attrs)) continue;
|
|
3652
|
+
const last = out[out.length - 1];
|
|
3653
|
+
if (last && last.end === iv.start && sameAttrs(attrsOf(last), iv.attrs))
|
|
3654
|
+
last.end = iv.end;
|
|
3655
|
+
else out.push({ start: iv.start, end: iv.end, ...iv.attrs });
|
|
3656
|
+
}
|
|
3657
|
+
return out;
|
|
3658
|
+
};
|
|
3659
|
+
var normalizeSpans = (spans, content) => fromIntervals(toIntervals(spans, content));
|
|
3660
|
+
var sliceSpans = (spans, start, end, to = 0) => (spans ?? []).filter((s) => s.end > start && s.start < end).map((s) => ({
|
|
3661
|
+
...s,
|
|
3662
|
+
start: Math.max(s.start, start) - start + to,
|
|
3663
|
+
end: Math.min(s.end, end) - start + to
|
|
3664
|
+
}));
|
|
3665
|
+
var richTextBlock = (content, spans, base, measure, tabMeasure, maxWidthMm) => {
|
|
3666
|
+
const h = base.heightMm;
|
|
3667
|
+
const baseFace = parseFontFace(base.face);
|
|
3668
|
+
const runs = toIntervals(spans, content).map((iv) => {
|
|
3669
|
+
const a = iv.attrs;
|
|
3670
|
+
const cap = h * (a.height ?? 1);
|
|
3671
|
+
return {
|
|
3672
|
+
...iv,
|
|
3673
|
+
face: fontFace(
|
|
3674
|
+
a.font ?? baseFace.font,
|
|
3675
|
+
a.bold ?? baseFace.bold,
|
|
3676
|
+
a.italic ?? baseFace.italic
|
|
3677
|
+
),
|
|
3678
|
+
cap,
|
|
3679
|
+
glyph: a.script ? cap * SCRIPT_SCALE : cap,
|
|
3680
|
+
dy: a.script === "super" ? cap * SUPER_RISE : a.script === "sub" ? -cap * SUB_DROP : 0
|
|
3681
|
+
};
|
|
3682
|
+
});
|
|
3683
|
+
const runsIn = (a, b) => runs.filter((r) => r.end > a && r.start < b);
|
|
3684
|
+
const widthOf = (a, b, m) => runsIn(a, b).reduce(
|
|
3685
|
+
(w, r) => w + m.measureTextWidth(
|
|
3686
|
+
content.slice(Math.max(a, r.start), Math.min(b, r.end)),
|
|
3687
|
+
r.glyph,
|
|
3688
|
+
r.face,
|
|
3689
|
+
base.widthFactor
|
|
3690
|
+
),
|
|
3691
|
+
0
|
|
3692
|
+
);
|
|
3693
|
+
const tab = h * TAB_SIZE_FACTOR;
|
|
3694
|
+
const nextStop = (x) => (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
3695
|
+
const segments = (a, b) => {
|
|
3696
|
+
const out = [];
|
|
3697
|
+
let x = 0;
|
|
3698
|
+
let s = a;
|
|
3699
|
+
for (let i = a; i <= b; i++) {
|
|
3700
|
+
if (i < b && content[i] !== " ") continue;
|
|
3701
|
+
out.push({ start: s, end: i, x });
|
|
3702
|
+
x = nextStop(x + widthOf(s, i, tabMeasure));
|
|
3703
|
+
s = i + 1;
|
|
3704
|
+
}
|
|
3705
|
+
return out;
|
|
3706
|
+
};
|
|
3707
|
+
const wrapWords2 = (a, b, max) => {
|
|
3708
|
+
const out = [];
|
|
3709
|
+
let lineStart = a;
|
|
3710
|
+
let cur = -1;
|
|
3711
|
+
for (let i = a; i <= b; i++) {
|
|
3712
|
+
if (i < b && content[i] !== " ") continue;
|
|
3713
|
+
if (cur >= 0 && widthOf(lineStart, i, measure) > max) {
|
|
3714
|
+
out.push([lineStart, cur]);
|
|
3715
|
+
lineStart = cur + 1;
|
|
3716
|
+
}
|
|
3717
|
+
cur = i;
|
|
3718
|
+
}
|
|
3719
|
+
out.push([lineStart, b]);
|
|
3720
|
+
return out;
|
|
3721
|
+
};
|
|
3722
|
+
const raw = [];
|
|
3723
|
+
let p0 = 0;
|
|
3724
|
+
for (const para of content.split("\n")) {
|
|
3725
|
+
const p1 = p0 + para.length;
|
|
3726
|
+
const tabbed = para.includes(" ");
|
|
3727
|
+
const wrap = maxWidthMm !== void 0 && maxWidthMm > 0;
|
|
3728
|
+
if (!wrap) raw.push({ start: p0, end: p1, tabbed });
|
|
3729
|
+
else if (!tabbed)
|
|
3730
|
+
for (const [s, e] of wrapWords2(p0, p1, maxWidthMm))
|
|
3731
|
+
raw.push({ start: s, end: e, tabbed });
|
|
3732
|
+
else {
|
|
3733
|
+
const segs = segments(p0, p1);
|
|
3734
|
+
const last = segs[segs.length - 1];
|
|
3735
|
+
const width = last.x + widthOf(last.start, last.end, measure);
|
|
3736
|
+
if (width <= maxWidthMm || maxWidthMm - last.x <= h)
|
|
3737
|
+
raw.push({ start: p0, end: p1, tabbed });
|
|
3738
|
+
else
|
|
3739
|
+
wrapWords2(last.start, p1, maxWidthMm - last.x).forEach(
|
|
3740
|
+
([s, e], i) => raw.push(
|
|
3741
|
+
i === 0 ? { start: p0, end: e, tabbed } : { start: s, end: e, hang: last.x, tabbed }
|
|
3742
|
+
)
|
|
3743
|
+
);
|
|
3744
|
+
}
|
|
3745
|
+
p0 = p1 + 1;
|
|
3746
|
+
}
|
|
3747
|
+
const lines = [];
|
|
3748
|
+
let baseline = 0;
|
|
3749
|
+
let prevCap = 0;
|
|
3750
|
+
for (const r of raw) {
|
|
3751
|
+
const segs = r.hang !== void 0 ? [{ start: r.start, end: r.end, x: r.hang }] : segments(r.start, r.end);
|
|
3752
|
+
const pieces = [];
|
|
3753
|
+
for (const seg of segs) {
|
|
3754
|
+
let x = seg.x;
|
|
3755
|
+
for (const run of runsIn(seg.start, seg.end)) {
|
|
3756
|
+
const text = content.slice(
|
|
3757
|
+
Math.max(seg.start, run.start),
|
|
3758
|
+
Math.min(seg.end, run.end)
|
|
3759
|
+
);
|
|
3760
|
+
const width = measure.measureTextWidth(
|
|
3761
|
+
text,
|
|
3762
|
+
run.glyph,
|
|
3763
|
+
run.face,
|
|
3764
|
+
base.widthFactor
|
|
3765
|
+
);
|
|
3766
|
+
pieces.push({
|
|
3767
|
+
text,
|
|
3768
|
+
x,
|
|
3769
|
+
width,
|
|
3770
|
+
dy: run.dy,
|
|
3771
|
+
heightMm: run.glyph,
|
|
3772
|
+
face: run.face,
|
|
3773
|
+
...run.attrs.color ? { color: run.attrs.color } : {},
|
|
3774
|
+
...run.attrs.underline ? { underline: true } : {}
|
|
3775
|
+
});
|
|
3776
|
+
x += width;
|
|
3777
|
+
}
|
|
3778
|
+
}
|
|
3779
|
+
const at = runsIn(r.start, Math.max(r.end, r.start + 1));
|
|
3780
|
+
const cap = Math.max(...at.map((run) => run.cap), at.length ? 0 : h);
|
|
3781
|
+
baseline += lines.length === 0 ? cap : LINE_HEIGHT_FACTOR * (prevCap + cap) / 2;
|
|
3782
|
+
prevCap = cap;
|
|
3783
|
+
const last = pieces[pieces.length - 1];
|
|
3784
|
+
lines.push({
|
|
3785
|
+
start: r.start,
|
|
3786
|
+
end: r.end,
|
|
3787
|
+
pieces,
|
|
3788
|
+
width: last ? last.x + last.width : 0,
|
|
3789
|
+
fromBlockEdge: r.tabbed,
|
|
3790
|
+
baseline
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3793
|
+
return {
|
|
3794
|
+
lines,
|
|
3795
|
+
width: maxWidthMm !== void 0 && maxWidthMm > 0 ? maxWidthMm : Math.max(...lines.map((l) => l.width), 0),
|
|
3796
|
+
height: baseline
|
|
3797
|
+
};
|
|
3798
|
+
};
|
|
3799
|
+
|
|
2805
3800
|
// ../core/src/paint/advanceTables.ts
|
|
2806
3801
|
var EXTRACTED_RANGES = [
|
|
2807
3802
|
[32, 126],
|
|
@@ -6284,6 +7279,473 @@ var approximateTextMeasurer = {
|
|
|
6284
7279
|
}
|
|
6285
7280
|
};
|
|
6286
7281
|
|
|
7282
|
+
// ../core/src/paint/dimensionGeometry.ts
|
|
7283
|
+
var RAD2DEG = 180 / Math.PI;
|
|
7284
|
+
var formatDimValue = (value, precision) => {
|
|
7285
|
+
const fixed = value.toFixed(precision);
|
|
7286
|
+
return fixed.includes(".") ? fixed.replace(/\.?0+$/, "") : fixed;
|
|
7287
|
+
};
|
|
7288
|
+
var dimLabelContent = (kind, label, formatted) => {
|
|
7289
|
+
const parts = (label?.content ?? DIM_DEFAULT_CONTENT[kind]).split(
|
|
7290
|
+
DIM_VALUE_TOKEN
|
|
7291
|
+
);
|
|
7292
|
+
const content = parts.join(formatted);
|
|
7293
|
+
if (!label?.spans?.length || label.content === void 0) return { content };
|
|
7294
|
+
const T = DIM_VALUE_TOKEN.length;
|
|
7295
|
+
const map = (p, end) => {
|
|
7296
|
+
let t = 0;
|
|
7297
|
+
let c = 0;
|
|
7298
|
+
for (let i = 0; i < parts.length; i++) {
|
|
7299
|
+
if (p <= t + parts[i].length) return c + (p - t);
|
|
7300
|
+
t += parts[i].length;
|
|
7301
|
+
c += parts[i].length;
|
|
7302
|
+
if (i === parts.length - 1) break;
|
|
7303
|
+
if (p < t + T) return end ? c + formatted.length : c;
|
|
7304
|
+
t += T;
|
|
7305
|
+
c += formatted.length;
|
|
7306
|
+
}
|
|
7307
|
+
return content.length;
|
|
7308
|
+
};
|
|
7309
|
+
const spans = normalizeSpans(
|
|
7310
|
+
label.spans.map((s) => ({
|
|
7311
|
+
...s,
|
|
7312
|
+
start: map(s.start, false),
|
|
7313
|
+
end: map(s.end, true)
|
|
7314
|
+
})),
|
|
7315
|
+
content
|
|
7316
|
+
);
|
|
7317
|
+
return spans.length ? { content, spans } : { content };
|
|
7318
|
+
};
|
|
7319
|
+
var labelWidth = (label, h, font, widthFactor) => label.spans?.length ? richTextBlock(
|
|
7320
|
+
label.content,
|
|
7321
|
+
label.spans,
|
|
7322
|
+
{ face: font, heightMm: h, widthFactor },
|
|
7323
|
+
approximateTextMeasurer,
|
|
7324
|
+
approximateTextMeasurer
|
|
7325
|
+
).width : approximateTextMeasurer.measureTextWidth(
|
|
7326
|
+
label.content,
|
|
7327
|
+
h,
|
|
7328
|
+
font,
|
|
7329
|
+
widthFactor
|
|
7330
|
+
);
|
|
7331
|
+
var resolveDimStyle = (obj, styles) => ({
|
|
7332
|
+
...dimStyleFor(obj, styles),
|
|
7333
|
+
...obj.styleOverride,
|
|
7334
|
+
scale: obj.scale
|
|
7335
|
+
});
|
|
7336
|
+
var readableRotation = (u) => {
|
|
7337
|
+
const raw = normAngle(angle(u));
|
|
7338
|
+
const flipped = raw > Math.PI / 2 + 1e-9 && raw <= 3 * Math.PI / 2 + 1e-9;
|
|
7339
|
+
return flipped ? raw - Math.PI : raw;
|
|
7340
|
+
};
|
|
7341
|
+
var straightFrame = (origin, u, n, s0, s1) => ({
|
|
7342
|
+
s0,
|
|
7343
|
+
s1,
|
|
7344
|
+
toWorld: (along, across) => add(origin, add(scale(u, along), scale(n, across))),
|
|
7345
|
+
fromWorld: (p) => {
|
|
7346
|
+
const d = sub(p, origin);
|
|
7347
|
+
return { along: dot(d, u), across: dot(d, n) };
|
|
7348
|
+
},
|
|
7349
|
+
tangent: () => u
|
|
7350
|
+
});
|
|
7351
|
+
var linearAxis = (obj) => {
|
|
7352
|
+
const first = obj.points[0];
|
|
7353
|
+
const last = obj.points[obj.points.length - 1];
|
|
7354
|
+
const u = obj.rotation !== void 0 ? fromAngle(obj.rotation) : dist(first, last) > 1e-9 ? norm(sub(last, first)) : { x: 1, y: 0 };
|
|
7355
|
+
return { u, n: perp(u) };
|
|
7356
|
+
};
|
|
7357
|
+
var linearFeet = (obj) => {
|
|
7358
|
+
const { u, n } = linearAxis(obj);
|
|
7359
|
+
const first = obj.points[0];
|
|
7360
|
+
const h = obj.offset ?? 0;
|
|
7361
|
+
const feet = obj.points.map(
|
|
7362
|
+
(p) => add(p, scale(n, h - dot(sub(p, first), n)))
|
|
7363
|
+
);
|
|
7364
|
+
return { feet, u, n };
|
|
7365
|
+
};
|
|
7366
|
+
var dimensionLabelFrames = (obj) => {
|
|
7367
|
+
switch (obj.kind) {
|
|
7368
|
+
case "linear": {
|
|
7369
|
+
if (obj.points.length < 2) return [];
|
|
7370
|
+
const { feet, u, n } = linearFeet(obj);
|
|
7371
|
+
const across = (obj.offset ?? 0) >= 0 ? n : scale(n, -1);
|
|
7372
|
+
const frames = [];
|
|
7373
|
+
for (let i = 0; i + 1 < feet.length; i++) {
|
|
7374
|
+
const L = dot(sub(feet[i + 1], feet[i]), u);
|
|
7375
|
+
if (Math.abs(L) < 1e-9) continue;
|
|
7376
|
+
const dir = L > 0 ? u : scale(u, -1);
|
|
7377
|
+
frames.push(straightFrame(feet[i], dir, across, 0, Math.abs(L)));
|
|
7378
|
+
}
|
|
7379
|
+
return frames;
|
|
7380
|
+
}
|
|
7381
|
+
case "angular": {
|
|
7382
|
+
const polar2 = angularFrame(obj);
|
|
7383
|
+
return polar2 ? [polar2.frame] : [];
|
|
7384
|
+
}
|
|
7385
|
+
case "radial": {
|
|
7386
|
+
if (obj.points.length < 2) return [];
|
|
7387
|
+
const [center, p] = obj.points;
|
|
7388
|
+
const r = dist(center, p);
|
|
7389
|
+
if (r < 1e-9) return [];
|
|
7390
|
+
const u = norm(sub(p, center));
|
|
7391
|
+
return [straightFrame(center, u, perp(u), 0, r)];
|
|
7392
|
+
}
|
|
7393
|
+
case "diameter": {
|
|
7394
|
+
if (obj.points.length < 2) return [];
|
|
7395
|
+
const [p1, p2] = obj.points;
|
|
7396
|
+
const d = dist(p1, p2);
|
|
7397
|
+
if (d < 1e-9) return [];
|
|
7398
|
+
const u = norm(sub(p2, p1));
|
|
7399
|
+
const center = add(p1, scale(u, d / 2));
|
|
7400
|
+
return [straightFrame(center, u, perp(u), -d / 2, d / 2)];
|
|
7401
|
+
}
|
|
7402
|
+
}
|
|
7403
|
+
};
|
|
7404
|
+
var angularFrame = (obj) => {
|
|
7405
|
+
if (obj.points.length < 3) return null;
|
|
7406
|
+
const [vertex, a, b] = obj.points;
|
|
7407
|
+
const signed = obj.offset ?? 0;
|
|
7408
|
+
const radius = Math.abs(signed);
|
|
7409
|
+
if (radius < 1e-9 || dist(vertex, a) < 1e-9 || dist(vertex, b) < 1e-9)
|
|
7410
|
+
return null;
|
|
7411
|
+
const angA = angle(sub(a, vertex));
|
|
7412
|
+
const angB = angle(sub(b, vertex));
|
|
7413
|
+
const start = signed >= 0 ? angA : angB;
|
|
7414
|
+
const sweep = signed >= 0 ? normAngle(angB - angA) : normAngle(angA - angB);
|
|
7415
|
+
if (sweep < 1e-9) return null;
|
|
7416
|
+
const frame = {
|
|
7417
|
+
s0: 0,
|
|
7418
|
+
s1: radius * sweep,
|
|
7419
|
+
toWorld: (along, across) => add(vertex, scale(fromAngle(start + along / radius), radius + across)),
|
|
7420
|
+
fromWorld: (p) => {
|
|
7421
|
+
const d = sub(p, vertex);
|
|
7422
|
+
let w = normAngle(angle(d) - start);
|
|
7423
|
+
if (w > Math.PI) w -= 2 * Math.PI;
|
|
7424
|
+
return { along: w * radius, across: len(d) - radius };
|
|
7425
|
+
},
|
|
7426
|
+
tangent: (along) => perp(fromAngle(start + along / radius))
|
|
7427
|
+
};
|
|
7428
|
+
return { vertex, radius, start, sweep, frame };
|
|
7429
|
+
};
|
|
7430
|
+
var overlaps = (a, b) => a[0] < b[1] - 1e-9 && b[0] < a[1] - 1e-9;
|
|
7431
|
+
var placeLabel = (frame, spec, index, label, style, arrowCount, mode, stack) => {
|
|
7432
|
+
const s = style.scale;
|
|
7433
|
+
const h = style.textHeight * s;
|
|
7434
|
+
const gap = style.textOffset * s;
|
|
7435
|
+
const A = style.arrowSize * s;
|
|
7436
|
+
const font = dimFontFace(style);
|
|
7437
|
+
const width = labelWidth(label, h, font, style.widthFactor);
|
|
7438
|
+
const L = frame.s1 - frame.s0;
|
|
7439
|
+
const arrowsInside = L >= arrowCount * A - 1e-9;
|
|
7440
|
+
let along = spec?.along;
|
|
7441
|
+
let across = spec?.across ?? 0;
|
|
7442
|
+
let row = 0;
|
|
7443
|
+
if (along === void 0) {
|
|
7444
|
+
const fits = L >= width + 2 * gap + arrowCount * A - 1e-9;
|
|
7445
|
+
const push = (arrowsInside ? 0 : A) + gap + width / 2;
|
|
7446
|
+
if (fits) along = (frame.s0 + frame.s1) / 2;
|
|
7447
|
+
else if (mode === "end") along = frame.s1 + push;
|
|
7448
|
+
else if (mode === "start") along = frame.s0 - push;
|
|
7449
|
+
else {
|
|
7450
|
+
along = (frame.s0 + frame.s1) / 2;
|
|
7451
|
+
row = 1;
|
|
7452
|
+
const interval2 = [along - width / 2, along + width / 2];
|
|
7453
|
+
if (stack && stack.row >= 1 && overlaps(interval2, stack.interval))
|
|
7454
|
+
row = stack.row + 1;
|
|
7455
|
+
across = row * (h + gap);
|
|
7456
|
+
}
|
|
7457
|
+
}
|
|
7458
|
+
const interval = [along - width / 2, along + width / 2];
|
|
7459
|
+
let cover = null;
|
|
7460
|
+
if (across === 0 && (interval[1] > frame.s1 || interval[0] < frame.s0))
|
|
7461
|
+
cover = [
|
|
7462
|
+
Math.min(frame.s0, interval[0] - gap),
|
|
7463
|
+
Math.max(frame.s1, interval[1] + gap)
|
|
7464
|
+
];
|
|
7465
|
+
const leaders = [];
|
|
7466
|
+
if (spec?.across !== void 0 && spec.across !== 0) {
|
|
7467
|
+
const landingA = frame.toWorld(interval[0], across);
|
|
7468
|
+
const landingB = frame.toWorld(interval[1], across);
|
|
7469
|
+
const from = frame.toWorld((frame.s0 + frame.s1) / 2, 0);
|
|
7470
|
+
const to = dist(from, landingA) <= dist(from, landingB) ? landingA : landingB;
|
|
7471
|
+
leaders.push({ a: from, b: to }, { a: landingA, b: landingB });
|
|
7472
|
+
}
|
|
7473
|
+
const tangent = frame.tangent(along);
|
|
7474
|
+
const rotation = readableRotation(tangent);
|
|
7475
|
+
const textUp = perp(fromAngle(rotation));
|
|
7476
|
+
const text = {
|
|
7477
|
+
content: label.content,
|
|
7478
|
+
...label.spans ? { spans: label.spans } : {},
|
|
7479
|
+
anchor: add(frame.toWorld(along, across), scale(textUp, gap)),
|
|
7480
|
+
rotation,
|
|
7481
|
+
height: h,
|
|
7482
|
+
width,
|
|
7483
|
+
font,
|
|
7484
|
+
widthFactor: style.widthFactor,
|
|
7485
|
+
segment: index,
|
|
7486
|
+
along,
|
|
7487
|
+
across
|
|
7488
|
+
};
|
|
7489
|
+
return { text, cover, leaders, row };
|
|
7490
|
+
};
|
|
7491
|
+
var linearGeometry = (obj, style) => {
|
|
7492
|
+
if (obj.points.length < 2) return null;
|
|
7493
|
+
const s = style.scale;
|
|
7494
|
+
const A = style.arrowSize * s;
|
|
7495
|
+
const { feet, u } = linearFeet(obj);
|
|
7496
|
+
const frames = dimensionLabelFrames(obj);
|
|
7497
|
+
if (frames.length === 0) return null;
|
|
7498
|
+
const extensionLines = [];
|
|
7499
|
+
obj.points.forEach((p, i) => {
|
|
7500
|
+
const f = feet[i];
|
|
7501
|
+
const gap = dist(p, f);
|
|
7502
|
+
if (gap < 1e-9) return;
|
|
7503
|
+
const w = norm(sub(f, p));
|
|
7504
|
+
extensionLines.push({
|
|
7505
|
+
a: style.extensionType === "short" ? sub(f, scale(w, style.extensionOvershoot * s)) : add(p, scale(w, Math.min(style.extensionOffset * s, gap))),
|
|
7506
|
+
b: add(f, scale(w, style.extensionOvershoot * s))
|
|
7507
|
+
});
|
|
7508
|
+
});
|
|
7509
|
+
const dimLines = [];
|
|
7510
|
+
const arrows = [];
|
|
7511
|
+
const labels = [];
|
|
7512
|
+
const leaders = [];
|
|
7513
|
+
let stack = null;
|
|
7514
|
+
frames.forEach((frame, i) => {
|
|
7515
|
+
const L = frame.s1 - frame.s0;
|
|
7516
|
+
const value = L;
|
|
7517
|
+
const mode = frames.length === 1 || i === frames.length - 1 ? "end" : i === 0 ? "start" : "raise";
|
|
7518
|
+
const placed = placeLabel(
|
|
7519
|
+
frame,
|
|
7520
|
+
obj.labels[i],
|
|
7521
|
+
i,
|
|
7522
|
+
dimLabelContent(
|
|
7523
|
+
obj.kind,
|
|
7524
|
+
obj.labels[i],
|
|
7525
|
+
formatDimValue(value, style.precision)
|
|
7526
|
+
),
|
|
7527
|
+
style,
|
|
7528
|
+
2,
|
|
7529
|
+
mode,
|
|
7530
|
+
stack
|
|
7531
|
+
);
|
|
7532
|
+
stack = placed.row > 0 ? {
|
|
7533
|
+
row: placed.row,
|
|
7534
|
+
interval: [
|
|
7535
|
+
placed.text.along - placed.text.width / 2,
|
|
7536
|
+
placed.text.along + placed.text.width / 2
|
|
7537
|
+
]
|
|
7538
|
+
} : null;
|
|
7539
|
+
labels.push(placed.text);
|
|
7540
|
+
leaders.push(...placed.leaders);
|
|
7541
|
+
const a = frame.toWorld(frame.s0, 0);
|
|
7542
|
+
const b = frame.toWorld(frame.s1, 0);
|
|
7543
|
+
const arrowsInside = L >= 2 * A - 1e-9;
|
|
7544
|
+
let from = frame.s0;
|
|
7545
|
+
let to = frame.s1;
|
|
7546
|
+
if (!arrowsInside) {
|
|
7547
|
+
from -= 2 * A;
|
|
7548
|
+
to += 2 * A;
|
|
7549
|
+
}
|
|
7550
|
+
if (placed.cover) {
|
|
7551
|
+
from = Math.min(from, placed.cover[0]);
|
|
7552
|
+
to = Math.max(to, placed.cover[1]);
|
|
7553
|
+
}
|
|
7554
|
+
dimLines.push({ a: frame.toWorld(from, 0), b: frame.toWorld(to, 0) });
|
|
7555
|
+
arrows.push(
|
|
7556
|
+
arrowsInside ? { tip: a, toward: b, size: A } : { tip: a, toward: frame.toWorld(from, 0), size: A },
|
|
7557
|
+
arrowsInside ? { tip: b, toward: a, size: A } : { tip: b, toward: frame.toWorld(to, 0), size: A }
|
|
7558
|
+
);
|
|
7559
|
+
});
|
|
7560
|
+
return {
|
|
7561
|
+
extensionLines,
|
|
7562
|
+
dimLines,
|
|
7563
|
+
dimArc: null,
|
|
7564
|
+
leaders,
|
|
7565
|
+
arrows,
|
|
7566
|
+
arrowType: style.arrowType,
|
|
7567
|
+
labels,
|
|
7568
|
+
value: Math.abs(dot(sub(feet[feet.length - 1], feet[0]), u))
|
|
7569
|
+
};
|
|
7570
|
+
};
|
|
7571
|
+
var angularGeometry = (obj, style) => {
|
|
7572
|
+
const polar2 = angularFrame(obj);
|
|
7573
|
+
if (!polar2) return null;
|
|
7574
|
+
const { vertex, radius, start, sweep, frame } = polar2;
|
|
7575
|
+
const s = style.scale;
|
|
7576
|
+
const A = style.arrowSize * s;
|
|
7577
|
+
const [, a, b] = obj.points;
|
|
7578
|
+
const extensionLines = [];
|
|
7579
|
+
for (const p of [a, b]) {
|
|
7580
|
+
const d = dist(vertex, p);
|
|
7581
|
+
const w = norm(sub(p, vertex));
|
|
7582
|
+
const inner = style.extensionType === "short" ? radius - style.extensionOvershoot * s : Math.min(d + style.extensionOffset * s, radius);
|
|
7583
|
+
const outer = radius + style.extensionOvershoot * s;
|
|
7584
|
+
if (outer - inner > 1e-9)
|
|
7585
|
+
extensionLines.push({
|
|
7586
|
+
a: add(vertex, scale(w, inner)),
|
|
7587
|
+
b: add(vertex, scale(w, outer))
|
|
7588
|
+
});
|
|
7589
|
+
}
|
|
7590
|
+
const placed = placeLabel(
|
|
7591
|
+
frame,
|
|
7592
|
+
obj.labels[0],
|
|
7593
|
+
0,
|
|
7594
|
+
dimLabelContent(
|
|
7595
|
+
obj.kind,
|
|
7596
|
+
obj.labels[0],
|
|
7597
|
+
formatDimValue(sweep * RAD2DEG, style.precision)
|
|
7598
|
+
),
|
|
7599
|
+
style,
|
|
7600
|
+
2,
|
|
7601
|
+
"end",
|
|
7602
|
+
null
|
|
7603
|
+
);
|
|
7604
|
+
const L = frame.s1;
|
|
7605
|
+
const arrowsInside = L >= 2 * A - 1e-9;
|
|
7606
|
+
let from = 0;
|
|
7607
|
+
let to = L;
|
|
7608
|
+
if (!arrowsInside) {
|
|
7609
|
+
from -= 2 * A;
|
|
7610
|
+
to += 2 * A;
|
|
7611
|
+
}
|
|
7612
|
+
if (placed.cover) {
|
|
7613
|
+
from = Math.min(from, placed.cover[0]);
|
|
7614
|
+
to = Math.max(to, placed.cover[1]);
|
|
7615
|
+
}
|
|
7616
|
+
const step = Math.min(sweep / 3, A * 2 / radius) * radius;
|
|
7617
|
+
const at = (along) => frame.toWorld(along, 0);
|
|
7618
|
+
return {
|
|
7619
|
+
extensionLines,
|
|
7620
|
+
dimLines: [],
|
|
7621
|
+
dimArc: {
|
|
7622
|
+
center: vertex,
|
|
7623
|
+
radius,
|
|
7624
|
+
startAngle: start + from / radius,
|
|
7625
|
+
endAngle: start + to / radius
|
|
7626
|
+
},
|
|
7627
|
+
leaders: placed.leaders,
|
|
7628
|
+
arrows: [
|
|
7629
|
+
{ tip: at(0), toward: at(arrowsInside ? step : -step), size: A },
|
|
7630
|
+
{ tip: at(L), toward: at(arrowsInside ? L - step : L + step), size: A }
|
|
7631
|
+
],
|
|
7632
|
+
arrowType: style.arrowType,
|
|
7633
|
+
labels: [placed.text],
|
|
7634
|
+
value: sweep
|
|
7635
|
+
};
|
|
7636
|
+
};
|
|
7637
|
+
var radialGeometry = (obj, style) => {
|
|
7638
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7639
|
+
if (!frame) return null;
|
|
7640
|
+
const s = style.scale;
|
|
7641
|
+
const A = style.arrowSize * s;
|
|
7642
|
+
const [center, p] = obj.points;
|
|
7643
|
+
const r = frame.s1;
|
|
7644
|
+
const spec = obj.labels[0];
|
|
7645
|
+
const content = dimLabelContent(
|
|
7646
|
+
obj.kind,
|
|
7647
|
+
spec,
|
|
7648
|
+
formatDimValue(r, style.precision)
|
|
7649
|
+
);
|
|
7650
|
+
const width = labelWidth(
|
|
7651
|
+
content,
|
|
7652
|
+
style.textHeight * s,
|
|
7653
|
+
dimFontFace(style),
|
|
7654
|
+
style.widthFactor
|
|
7655
|
+
);
|
|
7656
|
+
const gap = style.textOffset * s;
|
|
7657
|
+
const autoInside = spec?.along === void 0 && r >= width + 2 * gap + A - 1e-9 ? { ...spec, along: r - A - gap - width / 2 } : spec;
|
|
7658
|
+
const placed = placeLabel(
|
|
7659
|
+
frame,
|
|
7660
|
+
autoInside,
|
|
7661
|
+
0,
|
|
7662
|
+
content,
|
|
7663
|
+
style,
|
|
7664
|
+
1,
|
|
7665
|
+
"end",
|
|
7666
|
+
null
|
|
7667
|
+
);
|
|
7668
|
+
const outside = placed.text.along > r + 1e-9;
|
|
7669
|
+
let to = r;
|
|
7670
|
+
if (placed.cover) to = Math.max(to, placed.cover[1]);
|
|
7671
|
+
return {
|
|
7672
|
+
extensionLines: [],
|
|
7673
|
+
dimLines: [{ a: center, b: frame.toWorld(to, 0) }],
|
|
7674
|
+
dimArc: null,
|
|
7675
|
+
leaders: placed.leaders,
|
|
7676
|
+
// Head at the curve: pointing outward with the text inside, inward
|
|
7677
|
+
// (body on the outside) with the text outside.
|
|
7678
|
+
arrows: [
|
|
7679
|
+
{ tip: p, toward: outside ? frame.toWorld(r + A, 0) : center, size: A }
|
|
7680
|
+
],
|
|
7681
|
+
arrowType: style.arrowType,
|
|
7682
|
+
labels: [placed.text],
|
|
7683
|
+
value: r
|
|
7684
|
+
};
|
|
7685
|
+
};
|
|
7686
|
+
var diameterGeometry = (obj, style) => {
|
|
7687
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7688
|
+
if (!frame) return null;
|
|
7689
|
+
const s = style.scale;
|
|
7690
|
+
const A = style.arrowSize * s;
|
|
7691
|
+
const [p1, p2] = obj.points;
|
|
7692
|
+
const d = frame.s1 - frame.s0;
|
|
7693
|
+
const placed = placeLabel(
|
|
7694
|
+
frame,
|
|
7695
|
+
obj.labels[0],
|
|
7696
|
+
0,
|
|
7697
|
+
dimLabelContent(
|
|
7698
|
+
obj.kind,
|
|
7699
|
+
obj.labels[0],
|
|
7700
|
+
formatDimValue(d, style.precision)
|
|
7701
|
+
),
|
|
7702
|
+
style,
|
|
7703
|
+
2,
|
|
7704
|
+
"end",
|
|
7705
|
+
null
|
|
7706
|
+
);
|
|
7707
|
+
const arrowsInside = d >= 2 * A - 1e-9;
|
|
7708
|
+
let from = frame.s0;
|
|
7709
|
+
let to = frame.s1;
|
|
7710
|
+
if (!arrowsInside) {
|
|
7711
|
+
from -= 2 * A;
|
|
7712
|
+
to += 2 * A;
|
|
7713
|
+
}
|
|
7714
|
+
if (placed.cover) {
|
|
7715
|
+
from = Math.min(from, placed.cover[0]);
|
|
7716
|
+
to = Math.max(to, placed.cover[1]);
|
|
7717
|
+
}
|
|
7718
|
+
return {
|
|
7719
|
+
extensionLines: [],
|
|
7720
|
+
dimLines: [{ a: frame.toWorld(from, 0), b: frame.toWorld(to, 0) }],
|
|
7721
|
+
dimArc: null,
|
|
7722
|
+
leaders: placed.leaders,
|
|
7723
|
+
arrows: arrowsInside ? [
|
|
7724
|
+
{ tip: p1, toward: p2, size: A },
|
|
7725
|
+
{ tip: p2, toward: p1, size: A }
|
|
7726
|
+
] : [
|
|
7727
|
+
{ tip: p1, toward: frame.toWorld(from, 0), size: A },
|
|
7728
|
+
{ tip: p2, toward: frame.toWorld(to, 0), size: A }
|
|
7729
|
+
],
|
|
7730
|
+
arrowType: style.arrowType,
|
|
7731
|
+
labels: [placed.text],
|
|
7732
|
+
value: d
|
|
7733
|
+
};
|
|
7734
|
+
};
|
|
7735
|
+
var dimensionGeometry = (obj, styles) => {
|
|
7736
|
+
const style = resolveDimStyle(obj, styles);
|
|
7737
|
+
switch (obj.kind) {
|
|
7738
|
+
case "linear":
|
|
7739
|
+
return linearGeometry(obj, style);
|
|
7740
|
+
case "angular":
|
|
7741
|
+
return angularGeometry(obj, style);
|
|
7742
|
+
case "radial":
|
|
7743
|
+
return radialGeometry(obj, style);
|
|
7744
|
+
case "diameter":
|
|
7745
|
+
return diameterGeometry(obj, style);
|
|
7746
|
+
}
|
|
7747
|
+
};
|
|
7748
|
+
|
|
6287
7749
|
// ../core/src/paint/textGeometry.ts
|
|
6288
7750
|
var textHeight = (obj, textStyles) => (obj.styleOverride?.textHeight ?? textStyleFor(obj, textStyles).textHeight) * obj.scale;
|
|
6289
7751
|
var textArrowSize = (obj, textStyles) => (obj.styleOverride?.arrowSize ?? textStyleFor(obj, textStyles).arrowSize) * obj.scale;
|
|
@@ -6292,11 +7754,24 @@ var textWidth = (obj) => obj.width === void 0 ? void 0 : obj.width * obj.scale;
|
|
|
6292
7754
|
var FRAME_MARGIN_FACTOR = 0.35;
|
|
6293
7755
|
var textBoxLocal = (obj, measure, textStyles) => {
|
|
6294
7756
|
const { font, widthFactor } = effectiveTextFont(obj, textStyles);
|
|
6295
|
-
const
|
|
6296
|
-
|
|
7757
|
+
const block = obj.spans?.length ? (
|
|
7758
|
+
// Formatted: per-run fonts, so the measurer stays unbound.
|
|
7759
|
+
richTextBlock(
|
|
7760
|
+
obj.content,
|
|
7761
|
+
obj.spans,
|
|
7762
|
+
{
|
|
7763
|
+
face: font,
|
|
7764
|
+
heightMm: textHeight(obj, textStyles),
|
|
7765
|
+
widthFactor
|
|
7766
|
+
},
|
|
7767
|
+
measure,
|
|
7768
|
+
approximateTextMeasurer,
|
|
7769
|
+
textWidth(obj)
|
|
7770
|
+
)
|
|
7771
|
+
) : textBlock(
|
|
6297
7772
|
obj.content,
|
|
6298
7773
|
textHeight(obj, textStyles),
|
|
6299
|
-
|
|
7774
|
+
boundMeasurer(measure, font, widthFactor),
|
|
6300
7775
|
textWidth(obj)
|
|
6301
7776
|
);
|
|
6302
7777
|
const u = fromAngle(obj.rotation);
|
|
@@ -6397,7 +7872,7 @@ var cellText = (t, row, col) => {
|
|
|
6397
7872
|
id: `${t.id}:${row}:${col}`,
|
|
6398
7873
|
layerId: t.layerId,
|
|
6399
7874
|
position: { x: 0, y: 0 },
|
|
6400
|
-
content: cell.
|
|
7875
|
+
content: cell.content,
|
|
6401
7876
|
leaderLines: [],
|
|
6402
7877
|
hAlign: "center",
|
|
6403
7878
|
vAlign: "center",
|
|
@@ -6462,9 +7937,32 @@ var tableLayout = (t, textStyles) => {
|
|
|
6462
7937
|
const h = textHeight(text, textStyles);
|
|
6463
7938
|
const { font, widthFactor } = effectiveTextFont(text, textStyles);
|
|
6464
7939
|
const inner2 = colX[c + cols] - colX[c] - 2 * margin;
|
|
7940
|
+
if (cell.spans?.length) {
|
|
7941
|
+
const rich = richTextBlock(
|
|
7942
|
+
cell.content,
|
|
7943
|
+
cell.spans,
|
|
7944
|
+
{ face: font, heightMm: h, widthFactor },
|
|
7945
|
+
approximateTextMeasurer,
|
|
7946
|
+
approximateTextMeasurer,
|
|
7947
|
+
inner2 > 0 ? inner2 : void 0
|
|
7948
|
+
);
|
|
7949
|
+
let content = "";
|
|
7950
|
+
const spans = [];
|
|
7951
|
+
rich.lines.forEach((l, k) => {
|
|
7952
|
+
if (k > 0) content += "\n";
|
|
7953
|
+
spans.push(...sliceSpans(cell.spans, l.start, l.end, content.length));
|
|
7954
|
+
content += cell.content.slice(l.start, l.end);
|
|
7955
|
+
});
|
|
7956
|
+
wrapped.push({
|
|
7957
|
+
text: { ...text, spans },
|
|
7958
|
+
lines: [content],
|
|
7959
|
+
height: rich.height + 2 * margin
|
|
7960
|
+
});
|
|
7961
|
+
return;
|
|
7962
|
+
}
|
|
6465
7963
|
const measure = boundMeasurer(approximateTextMeasurer, font, widthFactor);
|
|
6466
7964
|
const block = textBlock(
|
|
6467
|
-
cell.
|
|
7965
|
+
cell.content,
|
|
6468
7966
|
h,
|
|
6469
7967
|
measure,
|
|
6470
7968
|
inner2 > 0 ? inner2 : void 0
|
|
@@ -6474,7 +7972,7 @@ var tableLayout = (t, textStyles) => {
|
|
|
6474
7972
|
text,
|
|
6475
7973
|
lines,
|
|
6476
7974
|
// An empty cell still reserves one line of its text height.
|
|
6477
|
-
height: (cell.
|
|
7975
|
+
height: (cell.content ? h + (lines.length - 1) * block.lineHeight : h) + 2 * margin
|
|
6478
7976
|
});
|
|
6479
7977
|
})
|
|
6480
7978
|
);
|
|
@@ -6553,7 +8051,7 @@ var tableLayout = (t, textStyles) => {
|
|
|
6553
8051
|
}));
|
|
6554
8052
|
anchors.forEach((a, i) => {
|
|
6555
8053
|
const { text, lines } = wrapped[i];
|
|
6556
|
-
if (!t.cells[a.row][a.col].
|
|
8054
|
+
if (!t.cells[a.row][a.col].content) return;
|
|
6557
8055
|
children.push({
|
|
6558
8056
|
...text,
|
|
6559
8057
|
...cellAnchor(t, colX, rowY, a),
|
|
@@ -6869,6 +8367,303 @@ var hexToTrueColor = (hex) => {
|
|
|
6869
8367
|
return rgb ? rgb[0] << 16 | rgb[1] << 8 | rgb[2] : null;
|
|
6870
8368
|
};
|
|
6871
8369
|
|
|
8370
|
+
// ../core/src/export/dxf/codecs.ts
|
|
8371
|
+
var LINE_WEIGHTS = [
|
|
8372
|
+
0,
|
|
8373
|
+
5,
|
|
8374
|
+
9,
|
|
8375
|
+
13,
|
|
8376
|
+
15,
|
|
8377
|
+
18,
|
|
8378
|
+
20,
|
|
8379
|
+
25,
|
|
8380
|
+
30,
|
|
8381
|
+
35,
|
|
8382
|
+
40,
|
|
8383
|
+
50,
|
|
8384
|
+
53,
|
|
8385
|
+
60,
|
|
8386
|
+
70,
|
|
8387
|
+
80,
|
|
8388
|
+
90,
|
|
8389
|
+
100,
|
|
8390
|
+
106,
|
|
8391
|
+
120,
|
|
8392
|
+
140,
|
|
8393
|
+
158,
|
|
8394
|
+
200,
|
|
8395
|
+
211
|
|
8396
|
+
];
|
|
8397
|
+
var lineWeightToMm = (lineWeight) => lineWeight === void 0 || lineWeight < 0 ? void 0 : Math.max(lineWeight, 5) / 100;
|
|
8398
|
+
var mmToLineWeight = (mm) => LINE_WEIGHTS.reduce(
|
|
8399
|
+
(best, w) => Math.abs(w - mm * 100) < Math.abs(best - mm * 100) ? w : best
|
|
8400
|
+
);
|
|
8401
|
+
var encodeMtext = (s) => s.replace(/\\/g, "\\\\").replace(/\{/g, "\\{").replace(/\}/g, "\\}").replace(/\^/g, "^ ").replace(/\n/g, "\\P").replace(/\t/g, "^I");
|
|
8402
|
+
var decodeTextEscapes = (text) => text.replace(/%%([dpcuo%])/gi, (_, ch) => {
|
|
8403
|
+
switch (ch.toLowerCase()) {
|
|
8404
|
+
case "d":
|
|
8405
|
+
return "\xB0";
|
|
8406
|
+
case "p":
|
|
8407
|
+
return "\xB1";
|
|
8408
|
+
case "c":
|
|
8409
|
+
return "\xD8";
|
|
8410
|
+
case "u":
|
|
8411
|
+
case "o":
|
|
8412
|
+
return "";
|
|
8413
|
+
default:
|
|
8414
|
+
return "%";
|
|
8415
|
+
}
|
|
8416
|
+
});
|
|
8417
|
+
var SUPERSCRIPT = {
|
|
8418
|
+
"0": "\u2070",
|
|
8419
|
+
"1": "\xB9",
|
|
8420
|
+
"2": "\xB2",
|
|
8421
|
+
"3": "\xB3",
|
|
8422
|
+
"4": "\u2074",
|
|
8423
|
+
"5": "\u2075",
|
|
8424
|
+
"6": "\u2076",
|
|
8425
|
+
"7": "\u2077",
|
|
8426
|
+
"8": "\u2078",
|
|
8427
|
+
"9": "\u2079",
|
|
8428
|
+
"+": "\u207A",
|
|
8429
|
+
"-": "\u207B",
|
|
8430
|
+
"=": "\u207C",
|
|
8431
|
+
"(": "\u207D",
|
|
8432
|
+
")": "\u207E",
|
|
8433
|
+
n: "\u207F",
|
|
8434
|
+
i: "\u2071"
|
|
8435
|
+
};
|
|
8436
|
+
var SUBSCRIPT = {
|
|
8437
|
+
"0": "\u2080",
|
|
8438
|
+
"1": "\u2081",
|
|
8439
|
+
"2": "\u2082",
|
|
8440
|
+
"3": "\u2083",
|
|
8441
|
+
"4": "\u2084",
|
|
8442
|
+
"5": "\u2085",
|
|
8443
|
+
"6": "\u2086",
|
|
8444
|
+
"7": "\u2087",
|
|
8445
|
+
"8": "\u2088",
|
|
8446
|
+
"9": "\u2089",
|
|
8447
|
+
"+": "\u208A",
|
|
8448
|
+
"-": "\u208B",
|
|
8449
|
+
"=": "\u208C",
|
|
8450
|
+
"(": "\u208D",
|
|
8451
|
+
")": "\u208E"
|
|
8452
|
+
};
|
|
8453
|
+
var toScript = (s, map) => [...s].every((c) => map[c]) ? [...s].map((c) => map[c]).join("") : s;
|
|
8454
|
+
var stackText = (body) => {
|
|
8455
|
+
const m = /^(.*?)([\^#/])(.*)$/s.exec(body);
|
|
8456
|
+
if (!m) return body;
|
|
8457
|
+
const top = m[1].trim();
|
|
8458
|
+
const bottom = m[3].trim();
|
|
8459
|
+
if (top && !bottom) return toScript(top, SUPERSCRIPT);
|
|
8460
|
+
if (!top && bottom) return toScript(bottom, SUBSCRIPT);
|
|
8461
|
+
return `${top}/${bottom}`;
|
|
8462
|
+
};
|
|
8463
|
+
var SYMBOL_FONT = {
|
|
8464
|
+
a: "\u03B1",
|
|
8465
|
+
b: "\u03B2",
|
|
8466
|
+
c: "\u03C7",
|
|
8467
|
+
d: "\u03B4",
|
|
8468
|
+
e: "\u03B5",
|
|
8469
|
+
f: "\u03C6",
|
|
8470
|
+
g: "\u03B3",
|
|
8471
|
+
h: "\u03B7",
|
|
8472
|
+
i: "\u03B9",
|
|
8473
|
+
k: "\u03BA",
|
|
8474
|
+
l: "\u03BB",
|
|
8475
|
+
m: "\u03BC",
|
|
8476
|
+
n: "\u03BD",
|
|
8477
|
+
p: "\u03C0",
|
|
8478
|
+
q: "\u03B8",
|
|
8479
|
+
r: "\u03C1",
|
|
8480
|
+
s: "\u03C3",
|
|
8481
|
+
t: "\u03C4",
|
|
8482
|
+
u: "\u03C5",
|
|
8483
|
+
w: "\u03C9",
|
|
8484
|
+
x: "\u03BE",
|
|
8485
|
+
y: "\u03C8",
|
|
8486
|
+
z: "\u03B6",
|
|
8487
|
+
D: "\u0394",
|
|
8488
|
+
F: "\u03A6",
|
|
8489
|
+
G: "\u0393",
|
|
8490
|
+
L: "\u039B",
|
|
8491
|
+
P: "\u03A0",
|
|
8492
|
+
Q: "\u0398",
|
|
8493
|
+
S: "\u03A3",
|
|
8494
|
+
W: "\u03A9",
|
|
8495
|
+
X: "\u039E",
|
|
8496
|
+
Y: "\u03A8",
|
|
8497
|
+
"\xA3": "\u2264",
|
|
8498
|
+
"\xB3": "\u2265",
|
|
8499
|
+
"\xB9": "\u2260",
|
|
8500
|
+
"\xBB": "\u2248",
|
|
8501
|
+
"\xA5": "\u221E",
|
|
8502
|
+
"\xB4": "\xD7",
|
|
8503
|
+
"\xB8": "\xF7",
|
|
8504
|
+
\u00D6: "\u221A",
|
|
8505
|
+
"\xAE": "\u2192",
|
|
8506
|
+
"\xAC": "\u2190",
|
|
8507
|
+
\u00C6: "\u2205",
|
|
8508
|
+
\u00CE: "\u2208",
|
|
8509
|
+
"\xB6": "\u2202"
|
|
8510
|
+
};
|
|
8511
|
+
var isSymbolFont = (fontCode) => /^symbol(\.ttf)?$/i.test(fontCode.split("|")[0].trim());
|
|
8512
|
+
var scanMtext = (text, opts) => {
|
|
8513
|
+
const chunks = [];
|
|
8514
|
+
let st = { symbol: false };
|
|
8515
|
+
const stack = [];
|
|
8516
|
+
const attrs = (extra) => opts ? {
|
|
8517
|
+
...st.font !== void 0 ? { font: st.font } : {},
|
|
8518
|
+
...st.bold !== void 0 ? { bold: st.bold } : {},
|
|
8519
|
+
...st.italic !== void 0 ? { italic: st.italic } : {},
|
|
8520
|
+
...st.height !== void 0 ? { height: st.height } : {},
|
|
8521
|
+
...st.color !== void 0 ? { color: st.color } : {},
|
|
8522
|
+
...st.underline ? { underline: true } : {},
|
|
8523
|
+
...extra
|
|
8524
|
+
} : {};
|
|
8525
|
+
const emit = (t, extra) => {
|
|
8526
|
+
if (!t) return;
|
|
8527
|
+
const a = attrs(extra);
|
|
8528
|
+
const last = chunks[chunks.length - 1];
|
|
8529
|
+
if (!extra && last && JSON.stringify(last.attrs) === JSON.stringify(a))
|
|
8530
|
+
last.text += t;
|
|
8531
|
+
else chunks.push({ text: t, attrs: a });
|
|
8532
|
+
};
|
|
8533
|
+
const codeBody = (i2) => {
|
|
8534
|
+
const end = text.indexOf(";", i2);
|
|
8535
|
+
return end === -1 ? ["", i2] : [text.slice(i2, end), end + 1];
|
|
8536
|
+
};
|
|
8537
|
+
let i = 0;
|
|
8538
|
+
while (i < text.length) {
|
|
8539
|
+
const ch = text[i];
|
|
8540
|
+
if (ch === "{") {
|
|
8541
|
+
stack.push(st);
|
|
8542
|
+
st = { ...st };
|
|
8543
|
+
i++;
|
|
8544
|
+
} else if (ch === "}") {
|
|
8545
|
+
st = stack.pop() ?? st;
|
|
8546
|
+
i++;
|
|
8547
|
+
} else if (ch !== "\\") {
|
|
8548
|
+
emit(st.symbol ? SYMBOL_FONT[ch] ?? ch : ch);
|
|
8549
|
+
i++;
|
|
8550
|
+
} else {
|
|
8551
|
+
const next = text[i + 1] ?? "";
|
|
8552
|
+
if (next === "\\" || next === "{" || next === "}") {
|
|
8553
|
+
emit(next);
|
|
8554
|
+
i += 2;
|
|
8555
|
+
} else if (next === "P") {
|
|
8556
|
+
emit("\n");
|
|
8557
|
+
i += 2;
|
|
8558
|
+
} else if (next === "~") {
|
|
8559
|
+
emit(" ");
|
|
8560
|
+
i += 2;
|
|
8561
|
+
} else if (next === "L" || next === "l") {
|
|
8562
|
+
st = { ...st, underline: next === "L" };
|
|
8563
|
+
i += 2;
|
|
8564
|
+
} else if ("OoKk".includes(next)) {
|
|
8565
|
+
i += 2;
|
|
8566
|
+
} else if (next === "S") {
|
|
8567
|
+
const [body, at] = codeBody(i + 2);
|
|
8568
|
+
const m = /^(.*?)([\^#/])(.*)$/s.exec(body);
|
|
8569
|
+
const top = m?.[1].trim() ?? "";
|
|
8570
|
+
const bottom = m?.[3].trim() ?? "";
|
|
8571
|
+
if (opts && m && m[2] === "^" && top && !bottom)
|
|
8572
|
+
emit(top, { script: "super" });
|
|
8573
|
+
else if (opts && m && m[2] === "^" && !top && bottom)
|
|
8574
|
+
emit(bottom, { script: "sub" });
|
|
8575
|
+
else emit(stackText(body));
|
|
8576
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8577
|
+
} else if ((next === "U" || next === "u") && /^\+[0-9a-fA-F]{4}/.test(text.slice(i + 2, i + 7))) {
|
|
8578
|
+
emit(String.fromCodePoint(parseInt(text.slice(i + 3, i + 7), 16)));
|
|
8579
|
+
i += 7;
|
|
8580
|
+
} else if (next === "f" || next === "F") {
|
|
8581
|
+
const [body, at] = codeBody(i + 2);
|
|
8582
|
+
st = { ...st, symbol: isSymbolFont(body) };
|
|
8583
|
+
if (opts && !st.symbol && body) {
|
|
8584
|
+
const [name, ...flags] = body.split("|");
|
|
8585
|
+
const file = name.includes(".");
|
|
8586
|
+
const face = fontFromDxfStyle(
|
|
8587
|
+
file ? name : void 0,
|
|
8588
|
+
file ? void 0 : name
|
|
8589
|
+
);
|
|
8590
|
+
const flag = (k) => flags.find((f) => f[0] === k)?.slice(1);
|
|
8591
|
+
st.font = face.font;
|
|
8592
|
+
st.bold = flag("b") !== void 0 ? flag("b") === "1" : face.bold;
|
|
8593
|
+
st.italic = flag("i") !== void 0 ? flag("i") === "1" : face.italic;
|
|
8594
|
+
}
|
|
8595
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8596
|
+
} else if (opts && next === "H") {
|
|
8597
|
+
const [body, at] = codeBody(i + 2);
|
|
8598
|
+
const v = Number.parseFloat(body);
|
|
8599
|
+
if (Number.isFinite(v) && v > 0)
|
|
8600
|
+
st = {
|
|
8601
|
+
...st,
|
|
8602
|
+
height: /x$/i.test(body) ? (st.height ?? 1) * v : v / (opts.heightMm > 0 ? opts.heightMm : v)
|
|
8603
|
+
};
|
|
8604
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8605
|
+
} else if (opts && next === "C") {
|
|
8606
|
+
const [body, at] = codeBody(i + 2);
|
|
8607
|
+
st = { ...st, color: aciToHex(Number.parseInt(body, 10)) };
|
|
8608
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8609
|
+
} else {
|
|
8610
|
+
const end = text.indexOf(";", i + 1);
|
|
8611
|
+
i = end === -1 ? i + 2 : end + 1;
|
|
8612
|
+
}
|
|
8613
|
+
}
|
|
8614
|
+
}
|
|
8615
|
+
return chunks;
|
|
8616
|
+
};
|
|
8617
|
+
var stripMtextCodes = (text) => scanMtext(text).map((c) => c.text).join("");
|
|
8618
|
+
var mtextWidthFactor = (text) => {
|
|
8619
|
+
const m = /\\W([0-9.]+);/.exec(text);
|
|
8620
|
+
const v = m ? Number(m[1]) : NaN;
|
|
8621
|
+
return Number.isFinite(v) && v > 0 && v !== 1 ? v : void 0;
|
|
8622
|
+
};
|
|
8623
|
+
var mtextFontFlags = (text) => {
|
|
8624
|
+
const m = /\\f[^|;]*((?:\|[a-z]\d+)*)/.exec(text);
|
|
8625
|
+
if (!m) return {};
|
|
8626
|
+
return {
|
|
8627
|
+
.../\|b1/.test(m[1]) ? { bold: true } : {},
|
|
8628
|
+
.../\|i1/.test(m[1]) ? { italic: true } : {}
|
|
8629
|
+
};
|
|
8630
|
+
};
|
|
8631
|
+
var decodeControlCodes = (text) => text.replace(
|
|
8632
|
+
/\^M\^J|\^[IJM ]|\r\n?/g,
|
|
8633
|
+
(m) => m === "^I" ? " " : m === "^ " ? "^" : "\n"
|
|
8634
|
+
);
|
|
8635
|
+
var cleanText = (raw, mtext) => decodeControlCodes(decodeTextEscapes(mtext ? stripMtextCodes(raw) : raw));
|
|
8636
|
+
var cleanRichText = (raw, heightMm) => {
|
|
8637
|
+
let content = "";
|
|
8638
|
+
const spans = [];
|
|
8639
|
+
for (const c of scanMtext(raw, { heightMm })) {
|
|
8640
|
+
const text = decodeControlCodes(decodeTextEscapes(c.text));
|
|
8641
|
+
spans.push({
|
|
8642
|
+
start: content.length,
|
|
8643
|
+
end: content.length + text.length,
|
|
8644
|
+
...c.attrs
|
|
8645
|
+
});
|
|
8646
|
+
content += text;
|
|
8647
|
+
}
|
|
8648
|
+
return { content, spans: normalizeSpans(spans, content) };
|
|
8649
|
+
};
|
|
8650
|
+
var encodeStack = (s) => encodeMtext(s).replace(/[#/;]/g, (c) => `\\${c}`);
|
|
8651
|
+
var encodeRichMtext = (content, spans, face) => {
|
|
8652
|
+
const base = parseFontFace(face);
|
|
8653
|
+
let out = "";
|
|
8654
|
+
let at = 0;
|
|
8655
|
+
for (const s of normalizeSpans(spans, content)) {
|
|
8656
|
+
out += encodeMtext(content.slice(at, s.start));
|
|
8657
|
+
const fontCode = s.font !== void 0 || s.bold !== void 0 || s.italic !== void 0 ? `\\f${fontTypeface(resolveFont(s.font ?? base.font))}|b${s.bold ?? base.bold ? 1 : 0}|i${s.italic ?? base.italic ? 1 : 0};` : "";
|
|
8658
|
+
const codes = fontCode + (s.height !== void 0 ? `\\H${s.height}x;` : "") + (s.color ? `\\C${nearestAci(s.color)};` : "") + (s.underline ? "\\L" : "");
|
|
8659
|
+
const body = content.slice(s.start, s.end);
|
|
8660
|
+
const text = s.script && !/[\n\t]/.test(body) ? s.script === "super" ? `\\S${encodeStack(body)}^;` : `\\S^${encodeStack(body)};` : encodeMtext(body);
|
|
8661
|
+
out += codes || s.script ? `{${codes}${text}}` : text;
|
|
8662
|
+
at = s.end;
|
|
8663
|
+
}
|
|
8664
|
+
return out + encodeMtext(content.slice(at));
|
|
8665
|
+
};
|
|
8666
|
+
|
|
6872
8667
|
// ../core/src/export/dxf/dxfExtras.ts
|
|
6873
8668
|
import { Point, DxfObject } from "@tarikjabiri/dxf";
|
|
6874
8669
|
var RAW_COLOR_BY_BLOCK = -1056964608;
|
|
@@ -7030,7 +8825,7 @@ var MultiLeaderEntity = class extends Point {
|
|
|
7030
8825
|
dx.push(45, 1);
|
|
7031
8826
|
dx.push(170, 1);
|
|
7032
8827
|
dx.push(90, RAW_COLOR_BY_BLOCK);
|
|
7033
|
-
dx.push(171,
|
|
8828
|
+
dx.push(171, a.attachment);
|
|
7034
8829
|
dx.push(172, 1);
|
|
7035
8830
|
dx.push(91, RAW_COLOR_NONE);
|
|
7036
8831
|
dx.push(141, 1.5);
|
|
@@ -7187,17 +8982,35 @@ var mtextAttachment = (hAlign, vAlign) => {
|
|
|
7187
8982
|
const col = hAlign === "left" ? 1 : hAlign === "center" ? 2 : 3;
|
|
7188
8983
|
return row + col;
|
|
7189
8984
|
};
|
|
7190
|
-
var
|
|
7191
|
-
var dxfLineTypeName = (lineType) => {
|
|
8985
|
+
var dxfLineTypeName = (lineType, lineTypes) => {
|
|
7192
8986
|
if (!lineType) return void 0;
|
|
7193
|
-
const p =
|
|
8987
|
+
const p = resolveLineType(lineType, lineTypes);
|
|
7194
8988
|
if (!p || p.dashesMm.length === 0) return void 0;
|
|
7195
8989
|
return p.dxfName ?? p.name.toUpperCase();
|
|
7196
8990
|
};
|
|
7197
|
-
var
|
|
8991
|
+
var setLineWeight = (target, weight) => {
|
|
8992
|
+
const emit = target.dxfy.bind(target);
|
|
8993
|
+
target.dxfy = (dx) => {
|
|
8994
|
+
const start = dx.lines.length;
|
|
8995
|
+
emit(dx);
|
|
8996
|
+
const lines = dx.lines;
|
|
8997
|
+
for (let i = start; i < lines.length; i += 2)
|
|
8998
|
+
if (lines[i] === 370) {
|
|
8999
|
+
lines[i + 1] = weight;
|
|
9000
|
+
return;
|
|
9001
|
+
}
|
|
9002
|
+
let markers = 0;
|
|
9003
|
+
for (let i = start; i < lines.length; i += 2)
|
|
9004
|
+
if (lines[i] === 100 && ++markers === 2) {
|
|
9005
|
+
lines.splice(i, 0, 370, weight);
|
|
9006
|
+
return;
|
|
9007
|
+
}
|
|
9008
|
+
lines.push(370, weight);
|
|
9009
|
+
};
|
|
9010
|
+
};
|
|
7198
9011
|
var optionsFor = (obj, ctx) => {
|
|
7199
9012
|
const layer = ctx.doc.layers.find((l) => l.id === obj.layerId);
|
|
7200
|
-
const dashed = (
|
|
9013
|
+
const dashed = (resolveLineType(obj.lineType ?? layer?.lineType ?? "", ctx.doc.lineTypes)?.dashesMm.length ?? 0) > 0;
|
|
7201
9014
|
const lineTypeScale = (obj.lineTypeScale ?? 1) * (obj.lineWidth ?? layer?.lineWidth ?? 0.25);
|
|
7202
9015
|
const trueColor = obj.color ? hexToTrueColor(obj.color) : null;
|
|
7203
9016
|
return {
|
|
@@ -7206,7 +9019,7 @@ var optionsFor = (obj, ctx) => {
|
|
|
7206
9019
|
// color (420) which wins wherever it is supported.
|
|
7207
9020
|
...obj.color ? { colorNumber: nearestAci(obj.color) } : {},
|
|
7208
9021
|
...trueColor !== null ? { trueColor: String(trueColor) } : {},
|
|
7209
|
-
...dxfLineTypeName(obj.lineType) ? { lineType: dxfLineTypeName(obj.lineType) } : {},
|
|
9022
|
+
...dxfLineTypeName(obj.lineType, ctx.doc.lineTypes) ? { lineType: dxfLineTypeName(obj.lineType, ctx.doc.lineTypes) } : {},
|
|
7210
9023
|
...dashed && lineTypeScale !== 1 ? { lineTypeScale } : {}
|
|
7211
9024
|
};
|
|
7212
9025
|
};
|
|
@@ -7251,28 +9064,87 @@ var addArrowhead = (space, tip, toward, size, type, opts) => {
|
|
|
7251
9064
|
break;
|
|
7252
9065
|
}
|
|
7253
9066
|
};
|
|
7254
|
-
var
|
|
9067
|
+
var uniqueTableName = (taken, base) => {
|
|
9068
|
+
let name = base;
|
|
9069
|
+
for (let i = 2; taken.has(name.toUpperCase()); i++) name = `${base}_${i}`;
|
|
9070
|
+
taken.add(name.toUpperCase());
|
|
9071
|
+
return name;
|
|
9072
|
+
};
|
|
9073
|
+
var writableFace = (font) => {
|
|
7255
9074
|
const def = resolveFont(font);
|
|
7256
|
-
const { bold, italic } = parseFontFace(font);
|
|
7257
|
-
const
|
|
7258
|
-
const
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
}
|
|
9075
|
+
const { font: bare, bold, italic } = parseFontFace(font);
|
|
9076
|
+
const foreign = bare !== void 0 && bare !== "" && bare !== def.id;
|
|
9077
|
+
const fontId = foreign ? bare : def.id;
|
|
9078
|
+
return {
|
|
9079
|
+
face: fontFace(fontId, bold, italic),
|
|
9080
|
+
fontFile: foreign ? `${fontId}.ttf` : def.dxfFontFile,
|
|
9081
|
+
fontId,
|
|
9082
|
+
foreign
|
|
9083
|
+
};
|
|
9084
|
+
};
|
|
9085
|
+
var addStyleRecord = (ctx, key, name, font, widthFactor = 1, fixedHeight = 0) => {
|
|
9086
|
+
const { face, fontFile } = writableFace(font);
|
|
9087
|
+
const table = ctx.writer.document.tables.styleTable;
|
|
9088
|
+
const predefined = name.toUpperCase() === "STANDARD" && !ctx.styleNames.has("STANDARD") ? table.records.find((r) => r.name.toUpperCase() === "STANDARD") : void 0;
|
|
9089
|
+
const style = predefined ?? table.addStyle(uniqueTableName(ctx.styleNames, name));
|
|
9090
|
+
if (predefined) ctx.styleNames.add("STANDARD");
|
|
9091
|
+
style.fontFileName = fontFile;
|
|
9092
|
+
style.widthFactor = widthFactor;
|
|
9093
|
+
style.fixedTextHeight = fixedHeight;
|
|
9094
|
+
const rec = { name: style.name, handle: style.handle, face };
|
|
9095
|
+
ctx.textStyles.set(key, rec);
|
|
7268
9096
|
return rec;
|
|
7269
9097
|
};
|
|
9098
|
+
var createDocTextStyles = (ctx) => {
|
|
9099
|
+
for (const s of ctx.doc.textStyles)
|
|
9100
|
+
addStyleRecord(
|
|
9101
|
+
ctx,
|
|
9102
|
+
`doc:${s.id}`,
|
|
9103
|
+
sanitizeLayerName(s.name),
|
|
9104
|
+
fontFace(s.font, s.bold, s.italic),
|
|
9105
|
+
s.widthFactor,
|
|
9106
|
+
s.textHeight
|
|
9107
|
+
);
|
|
9108
|
+
};
|
|
9109
|
+
var dimTextStyleFor = (ctx, face, widthFactor) => {
|
|
9110
|
+
const want = writableFace(face).face;
|
|
9111
|
+
const own = ctx.doc.textStyles.find(
|
|
9112
|
+
(s) => writableFace(fontFace(s.font, s.bold, s.italic)).face === want && Math.abs(s.widthFactor - widthFactor) < 1e-9
|
|
9113
|
+
);
|
|
9114
|
+
const ownRec = own && ctx.textStyles.get(`doc:${own.id}`);
|
|
9115
|
+
if (ownRec) return ownRec;
|
|
9116
|
+
if (Math.abs(widthFactor - 1) < 1e-9) return textStyleFor2(ctx, face);
|
|
9117
|
+
const key = `${want}|w${widthFactor}`;
|
|
9118
|
+
return ctx.textStyles.get(key) ?? addStyleRecord(
|
|
9119
|
+
ctx,
|
|
9120
|
+
key,
|
|
9121
|
+
`${textStyleFor2(ctx, face).name}_W${Math.round(widthFactor * 100)}`,
|
|
9122
|
+
face,
|
|
9123
|
+
widthFactor
|
|
9124
|
+
);
|
|
9125
|
+
};
|
|
9126
|
+
var textStyleFor2 = (ctx, font) => {
|
|
9127
|
+
const { face, fontId, foreign } = writableFace(font);
|
|
9128
|
+
const { bold, italic } = parseFontFace(face);
|
|
9129
|
+
const suffix = (bold ? "B" : "") + (italic ? "I" : "");
|
|
9130
|
+
return ctx.textStyles.get(face) ?? addStyleRecord(
|
|
9131
|
+
ctx,
|
|
9132
|
+
face,
|
|
9133
|
+
`LINEA_${(foreign ? fontId.replace(/[^A-Za-z0-9_-]/g, "_") : fontId).toUpperCase()}${suffix ? `_${suffix}` : ""}`,
|
|
9134
|
+
face
|
|
9135
|
+
);
|
|
9136
|
+
};
|
|
9137
|
+
var textRecordFor = (ctx, obj, face) => {
|
|
9138
|
+
const base = textStyleFor(obj, ctx.doc.textStyles);
|
|
9139
|
+
const own = ctx.textStyles.get(`doc:${base.id}`);
|
|
9140
|
+
return own && writableFace(fontFace(base.font, base.bold, base.italic)).face === writableFace(face).face ? own : textStyleFor2(ctx, face);
|
|
9141
|
+
};
|
|
7270
9142
|
var addTextLines = (space, content, position, height, rotation, hAlign, vAlign, opts, measure, mtextWidth, fontOpts = {}) => {
|
|
7271
|
-
const { styleName, font, widthFactor = 1 } = fontOpts;
|
|
9143
|
+
const { styleName, font, widthFactor = 1, spans } = fontOpts;
|
|
7272
9144
|
const m = boundMeasurer(measure, font, widthFactor);
|
|
7273
9145
|
const block = textBlock(content, height, m, mtextWidth);
|
|
7274
|
-
if (block.lines.length > 1 || mtextWidth !== void 0 && mtextWidth > 0 || content.includes(" ")) {
|
|
7275
|
-
const value = (widthFactor !== 1 ? `\\W${widthFactor};` : "") +
|
|
9146
|
+
if (block.lines.length > 1 || mtextWidth !== void 0 && mtextWidth > 0 || content.includes(" ") || !!spans?.length) {
|
|
9147
|
+
const value = (widthFactor !== 1 ? `\\W${widthFactor};` : "") + (spans?.length ? encodeRichMtext(content, spans, font) : encodeMtext(content));
|
|
7276
9148
|
const mtext = space.addMText(v3(position), height, value, {
|
|
7277
9149
|
rotation: rotation * RAD2DEG2,
|
|
7278
9150
|
attachmentPoint: mtextAttachment(hAlign, vAlign),
|
|
@@ -7298,11 +9170,84 @@ var addTextLines = (space, content, position, height, rotation, hAlign, vAlign,
|
|
|
7298
9170
|
if (styleName) text.textStyle = styleName;
|
|
7299
9171
|
});
|
|
7300
9172
|
};
|
|
9173
|
+
var documentPattern = (ctx, name) => ctx.doc.hatchPatterns.find(
|
|
9174
|
+
(p) => hatchPatternKey(p.name) === hatchPatternKey(name)
|
|
9175
|
+
);
|
|
9176
|
+
var injectHatchPatternLines = (content, ctx) => {
|
|
9177
|
+
if (ctx.doc.hatchPatterns.length === 0 && ctx.hatchOrigins.size === 0)
|
|
9178
|
+
return content;
|
|
9179
|
+
const out = [];
|
|
9180
|
+
let pos = 0;
|
|
9181
|
+
for (; ; ) {
|
|
9182
|
+
const start = content.indexOf("\n0\nHATCH\n", pos);
|
|
9183
|
+
if (start === -1) break;
|
|
9184
|
+
const rest = content.slice(start + 8);
|
|
9185
|
+
const m = /\n0\n(?=[A-Z][A-Z0-9_]*\n)/.exec(rest);
|
|
9186
|
+
const end = m ? start + 8 + m.index : content.length;
|
|
9187
|
+
let record = content.slice(start, end);
|
|
9188
|
+
const handle = /\n5\n([0-9A-Fa-f]+)\n/.exec(record)?.[1];
|
|
9189
|
+
const bodyAt = record.indexOf("\nAcDbHatch\n");
|
|
9190
|
+
const body = bodyAt === -1 ? record : record.slice(bodyAt);
|
|
9191
|
+
const name = /\n2\n([^\n]*)\n/.exec(body)?.[1];
|
|
9192
|
+
const anchor = handle ? ctx.hatchOrigins.get(handle) : void 0;
|
|
9193
|
+
const own = name ? documentPattern(ctx, name) : void 0;
|
|
9194
|
+
const pat = own ?? (name && anchor ? resolveHatchPattern(name, []) : void 0);
|
|
9195
|
+
const m77 = pat ? /\n77\n[^\n]*\n/.exec(body) : null;
|
|
9196
|
+
if (pat && m77 && bodyAt !== -1) {
|
|
9197
|
+
const angle2 = Number(/\n52\n([^\n]*)\n/.exec(body)?.[1] ?? 0) * Math.PI / 180;
|
|
9198
|
+
const scale3 = Number(/\n41\n([^\n]*)\n/.exec(body)?.[1] ?? 1) || 1;
|
|
9199
|
+
const cos = Math.cos(angle2);
|
|
9200
|
+
const sin = Math.sin(angle2);
|
|
9201
|
+
const bake = (x, y) => [
|
|
9202
|
+
(cos * x - sin * y) * scale3,
|
|
9203
|
+
(sin * x + cos * y) * scale3
|
|
9204
|
+
];
|
|
9205
|
+
const lines = pat.lines.map((l) => {
|
|
9206
|
+
const [bx, by] = bake(l.origin.x, l.origin.y);
|
|
9207
|
+
const ox = bx + (anchor?.x ?? 0);
|
|
9208
|
+
const oy = by + (anchor?.y ?? 0);
|
|
9209
|
+
const bakedAngle = l.angle + angle2;
|
|
9210
|
+
const dx = (Math.cos(bakedAngle) * l.deltaX - Math.sin(bakedAngle) * l.deltaY) * scale3;
|
|
9211
|
+
const dy = (Math.sin(bakedAngle) * l.deltaX + Math.cos(bakedAngle) * l.deltaY) * scale3;
|
|
9212
|
+
const dashes = l.dashesMm ?? [];
|
|
9213
|
+
return `53
|
|
9214
|
+
${(l.angle * 180 / Math.PI + angle2 * 180 / Math.PI).toFixed(6)}
|
|
9215
|
+
43
|
|
9216
|
+
${ox.toFixed(6)}
|
|
9217
|
+
44
|
|
9218
|
+
${oy.toFixed(6)}
|
|
9219
|
+
45
|
|
9220
|
+
${dx.toFixed(6)}
|
|
9221
|
+
46
|
|
9222
|
+
${dy.toFixed(6)}
|
|
9223
|
+
79
|
|
9224
|
+
${dashes.length}
|
|
9225
|
+
` + dashes.map((d) => `49
|
|
9226
|
+
${(d * scale3).toFixed(6)}
|
|
9227
|
+
`).join("");
|
|
9228
|
+
}).join("");
|
|
9229
|
+
const at = bodyAt + m77.index + m77[0].length;
|
|
9230
|
+
const tail = record.slice(at);
|
|
9231
|
+
const writerBlock = tail.startsWith("78\n") ? (() => {
|
|
9232
|
+
const stop = /\n(?:47|98)\n/.exec(tail);
|
|
9233
|
+
return stop ? stop.index + 1 : tail.length;
|
|
9234
|
+
})() : 0;
|
|
9235
|
+
record = record.slice(0, at) + `78
|
|
9236
|
+
${pat.lines.length}
|
|
9237
|
+
` + lines + tail.slice(writerBlock);
|
|
9238
|
+
if (own) record = record.replace(/\n76\n1\n/, "\n76\n2\n");
|
|
9239
|
+
}
|
|
9240
|
+
out.push(content.slice(pos, start), record);
|
|
9241
|
+
pos = end;
|
|
9242
|
+
}
|
|
9243
|
+
out.push(content.slice(pos));
|
|
9244
|
+
return out.join("");
|
|
9245
|
+
};
|
|
7301
9246
|
var dxfPatternName = (name) => {
|
|
7302
9247
|
const key = name.toUpperCase().replace(/-/g, "_").replace(/\./g, "_");
|
|
7303
9248
|
return HatchPredefinedPatterns[key] ?? HatchPredefinedPatterns.ANSI31;
|
|
7304
9249
|
};
|
|
7305
|
-
var writeHatch = (space, obj, opts) => {
|
|
9250
|
+
var writeHatch = (space, obj, opts, ctx) => {
|
|
7306
9251
|
if (obj.type !== "hatch") return;
|
|
7307
9252
|
if (obj.fill.kind === "gradient") {
|
|
7308
9253
|
opts = {
|
|
@@ -7326,9 +9271,11 @@ var writeHatch = (space, obj, opts) => {
|
|
|
7326
9271
|
obj.fill.kind === "solid" || obj.fill.kind === "gradient" ? pattern({ name: HatchPredefinedPatterns.SOLID }) : obj.fill.kind === "pattern" ? (
|
|
7327
9272
|
// The curated library names are the standard predefined patterns, so
|
|
7328
9273
|
// this is a direct mapping; fill.angle/scale ARE the DXF rotation
|
|
7329
|
-
// (code 52) and scale (code 41).
|
|
9274
|
+
// (code 52) and scale (code 41). A DOCUMENT pattern goes out under
|
|
9275
|
+
// its own name; its definition lines are spliced in afterwards
|
|
9276
|
+
// (injectHatchPatternLines — the writer has no custom patterns).
|
|
7330
9277
|
pattern({
|
|
7331
|
-
name: dxfPatternName(obj.fill.name),
|
|
9278
|
+
name: documentPattern(ctx, obj.fill.name) ? obj.fill.name.toUpperCase() : dxfPatternName(obj.fill.name),
|
|
7332
9279
|
angle: obj.fill.angle * RAD2DEG2,
|
|
7333
9280
|
scale: obj.fill.scale * obj.scale
|
|
7334
9281
|
})
|
|
@@ -7339,10 +9286,12 @@ var writeHatch = (space, obj, opts) => {
|
|
|
7339
9286
|
scale: obj.fill.spacing * obj.scale / ANSI31_BASE_SPACING
|
|
7340
9287
|
})
|
|
7341
9288
|
);
|
|
7342
|
-
space.addHatch(boundary, fill, opts);
|
|
9289
|
+
const written = space.addHatch(boundary, fill, opts);
|
|
9290
|
+
if (obj.fill.kind === "pattern" && obj.fill.origin)
|
|
9291
|
+
ctx.hatchOrigins.set(written.handle, obj.fill.origin);
|
|
7343
9292
|
};
|
|
7344
9293
|
var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
7345
|
-
for (const seg of [...geom.extensionLines, ...geom.dimLines])
|
|
9294
|
+
for (const seg of [...geom.extensionLines, ...geom.dimLines, ...geom.leaders])
|
|
7346
9295
|
target.addLine(v3(seg.a), v3(seg.b), opts);
|
|
7347
9296
|
if (geom.dimArc)
|
|
7348
9297
|
target.addArc(
|
|
@@ -7361,7 +9310,7 @@ var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
|
7361
9310
|
geom.arrowType,
|
|
7362
9311
|
opts
|
|
7363
9312
|
);
|
|
7364
|
-
for (const text of geom.
|
|
9313
|
+
for (const text of geom.labels)
|
|
7365
9314
|
addTextLines(
|
|
7366
9315
|
target,
|
|
7367
9316
|
text.content,
|
|
@@ -7376,13 +9325,43 @@ var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
|
7376
9325
|
{
|
|
7377
9326
|
styleName: textStyleFor2(ctx, text.font).name,
|
|
7378
9327
|
font: text.font,
|
|
7379
|
-
widthFactor: text.widthFactor
|
|
9328
|
+
widthFactor: text.widthFactor,
|
|
9329
|
+
spans: text.spans
|
|
7380
9330
|
}
|
|
7381
9331
|
);
|
|
7382
9332
|
};
|
|
7383
|
-
var
|
|
9333
|
+
var addDimStyleRecord = (ctx, name, style) => {
|
|
9334
|
+
const table = ctx.writer.document.tables.dimStyleTable;
|
|
9335
|
+
const predefined = name.toUpperCase() === "STANDARD" && !ctx.dimStyleNames.has("STANDARD") ? table.records.find((r) => r.name.toUpperCase() === "STANDARD") : void 0;
|
|
9336
|
+
const rec = predefined ?? ctx.writer.addDimStyle(uniqueTableName(ctx.dimStyleNames, name));
|
|
9337
|
+
if (predefined) ctx.dimStyleNames.add("STANDARD");
|
|
7384
9338
|
const scale3 = style.scale ?? 1;
|
|
9339
|
+
rec.DIMASZ = style.arrowSize;
|
|
9340
|
+
rec.DIMEXO = style.extensionOffset;
|
|
9341
|
+
rec.DIMEXE = style.extensionOvershoot;
|
|
9342
|
+
rec.DIMTXT = style.textHeight;
|
|
9343
|
+
rec.DIMGAP = style.textOffset;
|
|
9344
|
+
rec.DIMDEC = style.precision;
|
|
9345
|
+
if (scale3 !== 1) rec.DIMSCALE = scale3;
|
|
9346
|
+
if (style.arrowType !== "filled") rec.DIMBLK = DIMBLK_NAMES[style.arrowType];
|
|
9347
|
+
rec.DIMTXSTY = dimTextStyleFor(
|
|
9348
|
+
ctx,
|
|
9349
|
+
dimFontFace(style),
|
|
9350
|
+
style.widthFactor
|
|
9351
|
+
).handle;
|
|
9352
|
+
return rec.name;
|
|
9353
|
+
};
|
|
9354
|
+
var createDocDimStyles = (ctx) => {
|
|
9355
|
+
for (const s of ctx.doc.dimStyles)
|
|
9356
|
+
ctx.dimStyleRecords.set(
|
|
9357
|
+
s.id,
|
|
9358
|
+
addDimStyleRecord(ctx, sanitizeLayerName(s.name), s)
|
|
9359
|
+
);
|
|
9360
|
+
};
|
|
9361
|
+
var dimOverrideStyleFor = (ctx, base, style) => {
|
|
9362
|
+
const baseName = ctx.dimStyleRecords.get(base.id) ?? ctx.dimStyleRecords.values().next().value ?? "Standard";
|
|
7385
9363
|
const key = JSON.stringify([
|
|
9364
|
+
baseName,
|
|
7386
9365
|
style.arrowSize,
|
|
7387
9366
|
style.arrowType,
|
|
7388
9367
|
style.extensionOffset,
|
|
@@ -7391,21 +9370,13 @@ var dimStyleFor2 = (ctx, style) => {
|
|
|
7391
9370
|
style.textOffset,
|
|
7392
9371
|
style.precision,
|
|
7393
9372
|
dimFontFace(style),
|
|
7394
|
-
|
|
9373
|
+
style.scale ?? 1
|
|
7395
9374
|
]);
|
|
7396
|
-
|
|
7397
|
-
if (
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
rec.DIMEXO = style.extensionOffset;
|
|
7402
|
-
rec.DIMEXE = style.extensionOvershoot;
|
|
7403
|
-
rec.DIMTXT = style.textHeight;
|
|
7404
|
-
rec.DIMGAP = style.textOffset;
|
|
7405
|
-
rec.DIMDEC = style.precision;
|
|
7406
|
-
if (scale3 !== 1) rec.DIMSCALE = scale3;
|
|
7407
|
-
if (style.arrowType !== "filled") rec.DIMBLK = DIMBLK_NAMES[style.arrowType];
|
|
7408
|
-
rec.DIMTXSTY = textStyleFor2(ctx, dimFontFace(style)).handle;
|
|
9375
|
+
const cached = ctx.dimStyles.get(key);
|
|
9376
|
+
if (cached) return cached;
|
|
9377
|
+
const n = (ctx.dimOverrideCounts.get(baseName) ?? 0) + 1;
|
|
9378
|
+
ctx.dimOverrideCounts.set(baseName, n);
|
|
9379
|
+
const name = addDimStyleRecord(ctx, `${baseName}_${n}`, style);
|
|
7409
9380
|
ctx.dimStyles.set(key, name);
|
|
7410
9381
|
return name;
|
|
7411
9382
|
};
|
|
@@ -7431,26 +9402,38 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7431
9402
|
const blockName = `LINEA_DIM_${ctx.dimBlockCount++}`;
|
|
7432
9403
|
const block = ctx.writer.addBlock(blockName);
|
|
7433
9404
|
writeDimensionGeometry(block, geom, opts, ctx);
|
|
7434
|
-
const
|
|
7435
|
-
|
|
9405
|
+
const baseStyle = dimStyleFor(obj, ctx.doc.dimStyles);
|
|
9406
|
+
const hasOverride = obj.styleOverride !== void 0 && Object.values(obj.styleOverride).some((v) => v !== void 0);
|
|
9407
|
+
const styleName = hasOverride || obj.scale !== 1 ? dimOverrideStyleFor(ctx, baseStyle, {
|
|
9408
|
+
...baseStyle,
|
|
7436
9409
|
...obj.styleOverride,
|
|
7437
9410
|
scale: obj.scale
|
|
7438
|
-
}) :
|
|
9411
|
+
}) : ctx.dimStyleRecords.get(baseStyle.id) ?? dimOverrideStyleFor(ctx, baseStyle, baseStyle);
|
|
9412
|
+
const content = obj.labels[0]?.content;
|
|
9413
|
+
const precision = {
|
|
9414
|
+
...dimStyleFor(obj, ctx.doc.dimStyles),
|
|
9415
|
+
...obj.styleOverride
|
|
9416
|
+
}.precision;
|
|
9417
|
+
const text = content === void 0 ? void 0 : content.split(DIM_DEFAULT_CONTENT[obj.kind]).join("<>").split(DIM_VALUE_TOKEN).join(
|
|
9418
|
+
obj.kind === "radial" || obj.kind === "diameter" ? formatDimValue(geom.value, precision) : "<>"
|
|
9419
|
+
);
|
|
7439
9420
|
const dimOpts = {
|
|
7440
9421
|
blockName,
|
|
7441
|
-
text:
|
|
9422
|
+
...text === void 0 ? {} : { text },
|
|
7442
9423
|
styleName,
|
|
7443
9424
|
// Text middle point (group 11) — without it a regenerating CAD places
|
|
7444
9425
|
// the value at the style default instead of where the user saw it.
|
|
7445
|
-
...geom.
|
|
9426
|
+
...geom.labels[0] ? { middlePoint: v3(geom.labels[0].anchor) } : {},
|
|
7446
9427
|
...opts
|
|
7447
9428
|
};
|
|
7448
9429
|
switch (obj.kind) {
|
|
7449
9430
|
case "angular": {
|
|
7450
9431
|
const [vertex, a, b] = obj.points;
|
|
9432
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7451
9433
|
space.addAngularPointsDim(v3(vertex), v3(a), v3(b), {
|
|
7452
9434
|
...dimOpts,
|
|
7453
|
-
|
|
9435
|
+
// A point on the arc (its middle): the radius and which arc.
|
|
9436
|
+
definitionPoint: v3(frame.toWorld((frame.s0 + frame.s1) / 2, 0))
|
|
7454
9437
|
});
|
|
7455
9438
|
break;
|
|
7456
9439
|
}
|
|
@@ -7466,8 +9449,7 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7466
9449
|
}
|
|
7467
9450
|
case "linear": {
|
|
7468
9451
|
const [p1, p2] = obj.points;
|
|
7469
|
-
const
|
|
7470
|
-
const u = upLen > 1e-9 ? perp(scale(obj.offset, 1 / upLen)) : norm(sub(p2, p1));
|
|
9452
|
+
const { u } = linearAxis(obj);
|
|
7471
9453
|
space.addLinearDim(v3(p1), v3(p2), {
|
|
7472
9454
|
...dimOpts,
|
|
7473
9455
|
definitionPoint: v3(geom.dimLines[0].b),
|
|
@@ -7479,6 +9461,13 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7479
9461
|
return true;
|
|
7480
9462
|
};
|
|
7481
9463
|
var writeObject = (space, obj, ctx) => {
|
|
9464
|
+
const before = space.entities.length;
|
|
9465
|
+
writeObjectEntities(space, obj, ctx);
|
|
9466
|
+
if (obj.lineWidth !== void 0)
|
|
9467
|
+
for (const entity of space.entities.slice(before))
|
|
9468
|
+
setLineWeight(entity, mmToLineWeight(obj.lineWidth));
|
|
9469
|
+
};
|
|
9470
|
+
var writeObjectEntities = (space, obj, ctx) => {
|
|
7482
9471
|
const opts = optionsFor(obj, ctx);
|
|
7483
9472
|
switch (obj.type) {
|
|
7484
9473
|
case "line":
|
|
@@ -7523,12 +9512,27 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7523
9512
|
);
|
|
7524
9513
|
break;
|
|
7525
9514
|
case "hatch":
|
|
7526
|
-
writeHatch(space, obj, opts);
|
|
9515
|
+
writeHatch(space, obj, opts, ctx);
|
|
7527
9516
|
break;
|
|
7528
9517
|
case "text": {
|
|
7529
9518
|
const eff = resolveTextStyle(obj, ctx.doc.textStyles);
|
|
7530
9519
|
const { arrowSize, arrowType } = eff;
|
|
7531
9520
|
const face = fontFace(eff.font, eff.bold, eff.italic);
|
|
9521
|
+
for (const part of textFrameGeometry(
|
|
9522
|
+
obj,
|
|
9523
|
+
ctx.measure,
|
|
9524
|
+
ctx.doc.textStyles
|
|
9525
|
+
))
|
|
9526
|
+
space.addLWPolyline(
|
|
9527
|
+
part.points.map((v) => ({
|
|
9528
|
+
point: { x: v.x, y: v.y },
|
|
9529
|
+
bulge: v.bulge
|
|
9530
|
+
})),
|
|
9531
|
+
{
|
|
9532
|
+
flags: part.closed ? LWPolylineFlags.Closed : LWPolylineFlags.None,
|
|
9533
|
+
...opts
|
|
9534
|
+
}
|
|
9535
|
+
);
|
|
7532
9536
|
if (obj.leaderLines.length > 0 && ctx.explodeLeaders) {
|
|
7533
9537
|
for (const line of obj.leaderLines) {
|
|
7534
9538
|
space.addLWPolyline(
|
|
@@ -7562,13 +9566,15 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7562
9566
|
junction,
|
|
7563
9567
|
doglegDirection: { x: toText.x / gap, y: toText.y / gap },
|
|
7564
9568
|
doglegLength: gap,
|
|
7565
|
-
content:
|
|
9569
|
+
content: obj.spans?.length ? encodeRichMtext(obj.content, obj.spans, face) : encodeMtext(obj.content),
|
|
7566
9570
|
textHeight: eff.textHeight,
|
|
7567
9571
|
arrowSize,
|
|
7568
9572
|
overallScale: obj.scale,
|
|
7569
9573
|
textLocation: obj.position,
|
|
9574
|
+
// Model alignment → MTEXT-style attachment point (1–9).
|
|
9575
|
+
attachment: 1 + 3 * ["top", "center", "bottom"].indexOf(obj.vAlign) + ["left", "center", "right"].indexOf(obj.hAlign),
|
|
7570
9576
|
styleHandle: ctx.mleaderStyleHandle,
|
|
7571
|
-
textStyleHandle:
|
|
9577
|
+
textStyleHandle: textRecordFor(ctx, obj, face).handle,
|
|
7572
9578
|
lineTypeHandle: ctx.lineTypeHandle
|
|
7573
9579
|
});
|
|
7574
9580
|
entity.layerName = ctx.layerNames.get(obj.layerId) ?? "0";
|
|
@@ -7592,9 +9598,10 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7592
9598
|
ctx.measure,
|
|
7593
9599
|
obj.width === void 0 ? void 0 : obj.width * obj.scale,
|
|
7594
9600
|
{
|
|
7595
|
-
styleName:
|
|
9601
|
+
styleName: textRecordFor(ctx, obj, face).name,
|
|
7596
9602
|
font: face,
|
|
7597
|
-
widthFactor: eff.widthFactor
|
|
9603
|
+
widthFactor: eff.widthFactor,
|
|
9604
|
+
spans: obj.spans
|
|
7598
9605
|
}
|
|
7599
9606
|
);
|
|
7600
9607
|
break;
|
|
@@ -7694,6 +9701,14 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7694
9701
|
const writer = new DxfWriter();
|
|
7695
9702
|
writer.setUnits(Units.Millimeters);
|
|
7696
9703
|
const emittedLtypes = /* @__PURE__ */ new Set();
|
|
9704
|
+
for (const t of doc.lineTypes) {
|
|
9705
|
+
if (t.dashesMm.length === 0) continue;
|
|
9706
|
+
const dxfName = t.name.toUpperCase();
|
|
9707
|
+
if (emittedLtypes.has(dxfName)) continue;
|
|
9708
|
+
emittedLtypes.add(dxfName);
|
|
9709
|
+
const descriptive = (t.description ?? t.name).replace(/[^\x20-\x7e]/g, "").slice(0, 47);
|
|
9710
|
+
writer.addLType(dxfName, descriptive, t.dashesMm);
|
|
9711
|
+
}
|
|
7697
9712
|
for (const p of LINE_TYPE_DEFS) {
|
|
7698
9713
|
if (p.dashesMm.length === 0) continue;
|
|
7699
9714
|
const dxfName = p.dxfName ?? p.name.toUpperCase();
|
|
@@ -7715,18 +9730,22 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7715
9730
|
layerNames.set(layer.id, name);
|
|
7716
9731
|
if (name === "0") {
|
|
7717
9732
|
const zero = writer.layer("0");
|
|
7718
|
-
if (zero)
|
|
9733
|
+
if (zero) {
|
|
9734
|
+
setLineWeight(zero, mmToLineWeight(layer.lineWidth));
|
|
9735
|
+
layerRecords.set(layer.id, zero);
|
|
9736
|
+
}
|
|
7719
9737
|
continue;
|
|
7720
9738
|
}
|
|
7721
9739
|
const flags = (layer.visible ? 0 : LayerFlags.Frozen) | (layer.locked ? LayerFlags.Locked : 0);
|
|
7722
9740
|
const record = writer.addLayer(
|
|
7723
9741
|
name,
|
|
7724
9742
|
nearestAci(layer.color),
|
|
7725
|
-
dxfLineTypeName(layer.lineType) ?? "Continuous",
|
|
9743
|
+
dxfLineTypeName(layer.lineType, doc.lineTypes) ?? "Continuous",
|
|
7726
9744
|
flags || void 0
|
|
7727
9745
|
);
|
|
7728
9746
|
const tc = hexToTrueColor(layer.color);
|
|
7729
9747
|
if (tc !== null) record.trueColor = tc;
|
|
9748
|
+
setLineWeight(record, mmToLineWeight(layer.lineWidth));
|
|
7730
9749
|
layerRecords.set(layer.id, record);
|
|
7731
9750
|
}
|
|
7732
9751
|
const textStyleHandle = writer.document.tables.styleTable.records.find((r) => r.name === "Standard")?.handle ?? "0";
|
|
@@ -7762,9 +9781,15 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7762
9781
|
textStyleHandle,
|
|
7763
9782
|
lineTypeHandle,
|
|
7764
9783
|
textStyles: /* @__PURE__ */ new Map(),
|
|
7765
|
-
|
|
9784
|
+
styleNames: /* @__PURE__ */ new Set(),
|
|
9785
|
+
dimStyleRecords: /* @__PURE__ */ new Map(),
|
|
9786
|
+
dimStyleNames: /* @__PURE__ */ new Set(),
|
|
9787
|
+
dimStyles: /* @__PURE__ */ new Map(),
|
|
9788
|
+
dimOverrideCounts: /* @__PURE__ */ new Map(),
|
|
9789
|
+
hatchOrigins: /* @__PURE__ */ new Map()
|
|
7766
9790
|
};
|
|
7767
|
-
|
|
9791
|
+
createDocTextStyles(ctx);
|
|
9792
|
+
createDocDimStyles(ctx);
|
|
7768
9793
|
for (const obj of doc.objects)
|
|
7769
9794
|
writeObject(writer.document.blocks.modelSpace, obj, ctx);
|
|
7770
9795
|
const layoutRecords = [];
|
|
@@ -7837,15 +9862,21 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7837
9862
|
if (record) record.layoutObject = layoutObj.handle;
|
|
7838
9863
|
}
|
|
7839
9864
|
return {
|
|
7840
|
-
content:
|
|
9865
|
+
content: injectHatchPatternLines(
|
|
9866
|
+
injectStyleTypefaces(writer.stringify(), ctx.textStyles),
|
|
9867
|
+
ctx
|
|
9868
|
+
),
|
|
7841
9869
|
exported: ctx.exported,
|
|
7842
9870
|
skipped: ctx.skipped
|
|
7843
9871
|
};
|
|
7844
9872
|
};
|
|
7845
9873
|
var injectStyleTypefaces = (content, textStyles) => {
|
|
7846
9874
|
let out = content;
|
|
7847
|
-
for (const
|
|
7848
|
-
const
|
|
9875
|
+
for (const rec of textStyles.values()) {
|
|
9876
|
+
const fontId = rec.face;
|
|
9877
|
+
const { font: bare } = parseFontFace(fontId);
|
|
9878
|
+
const def = resolveFont(fontId);
|
|
9879
|
+
const typeface = bare !== void 0 && bare !== def.id ? bare : fontTypeface(def);
|
|
7849
9880
|
const { bold, italic } = parseFontFace(fontId);
|
|
7850
9881
|
const flags = (italic ? 16777216 : 0) | (bold ? 33554432 : 0);
|
|
7851
9882
|
const marker = `
|
|
@@ -7875,6 +9906,7 @@ export {
|
|
|
7875
9906
|
add,
|
|
7876
9907
|
sub,
|
|
7877
9908
|
scale,
|
|
9909
|
+
dot,
|
|
7878
9910
|
len,
|
|
7879
9911
|
dist,
|
|
7880
9912
|
norm,
|
|
@@ -7894,10 +9926,12 @@ export {
|
|
|
7894
9926
|
Vec2Schema,
|
|
7895
9927
|
ColorSchema,
|
|
7896
9928
|
FONTS,
|
|
9929
|
+
fontFace,
|
|
7897
9930
|
parseFontFace,
|
|
7898
9931
|
REAL_FACES,
|
|
7899
9932
|
realFace,
|
|
7900
9933
|
resolveFont,
|
|
9934
|
+
fontFromDxfStyle,
|
|
7901
9935
|
TextStyleSchema,
|
|
7902
9936
|
DEFAULT_TEXT_STYLE,
|
|
7903
9937
|
textStyleFor,
|
|
@@ -7916,6 +9950,8 @@ export {
|
|
|
7916
9950
|
approximateTextMeasurer,
|
|
7917
9951
|
lineSegments,
|
|
7918
9952
|
textBlock,
|
|
9953
|
+
normalizeSpans,
|
|
9954
|
+
richTextBlock,
|
|
7919
9955
|
textHeight,
|
|
7920
9956
|
textArrowSize,
|
|
7921
9957
|
textArrowType,
|
|
@@ -7923,15 +9959,34 @@ export {
|
|
|
7923
9959
|
textBoxCorners,
|
|
7924
9960
|
textFrameGeometry,
|
|
7925
9961
|
tableLayout,
|
|
9962
|
+
matIdentity,
|
|
9963
|
+
matMultiply,
|
|
9964
|
+
matApply,
|
|
9965
|
+
signedArcSweep,
|
|
9966
|
+
arcToBeziers,
|
|
9967
|
+
computeHatchLines,
|
|
9968
|
+
ellipseArcToBeziers,
|
|
9969
|
+
getHatchPattern,
|
|
9970
|
+
MAX_HATCH_SEGMENTS,
|
|
9971
|
+
estimatePatternSegments,
|
|
9972
|
+
computePatternGeometry,
|
|
9973
|
+
HatchPatternSchema,
|
|
9974
|
+
hatchPatternKey,
|
|
9975
|
+
resolveHatchPattern,
|
|
7926
9976
|
getLineType,
|
|
7927
9977
|
renderDashes,
|
|
9978
|
+
LineTypeSchema,
|
|
9979
|
+
lineTypeKey,
|
|
9980
|
+
resolveLineType,
|
|
7928
9981
|
CURRENT_DOCUMENT_VERSION,
|
|
7929
9982
|
dimensionRawToOffset,
|
|
9983
|
+
dimensionRawToLabels,
|
|
7930
9984
|
migrateDocument,
|
|
7931
9985
|
HEX_COLOR,
|
|
7932
9986
|
valueParams,
|
|
7933
9987
|
resolveDocumentObject,
|
|
7934
9988
|
documentObjectResolver,
|
|
9989
|
+
BlockChildSchema,
|
|
7935
9990
|
ensureScriptTranspiler,
|
|
7936
9991
|
executeScriptModule,
|
|
7937
9992
|
scriptTranspilerReady,
|
|
@@ -7949,9 +10004,17 @@ export {
|
|
|
7949
10004
|
testBlockDefinition,
|
|
7950
10005
|
getEvaluatedWorldChildren,
|
|
7951
10006
|
ANSI31_BASE_SPACING,
|
|
10007
|
+
linearAxis,
|
|
7952
10008
|
dimensionGeometry,
|
|
10009
|
+
hexToRgb,
|
|
7953
10010
|
rgbToHex,
|
|
7954
10011
|
aciToHex,
|
|
10012
|
+
lineWeightToMm,
|
|
10013
|
+
decodeTextEscapes,
|
|
10014
|
+
mtextWidthFactor,
|
|
10015
|
+
mtextFontFlags,
|
|
10016
|
+
cleanText,
|
|
10017
|
+
cleanRichText,
|
|
7955
10018
|
buildDxf
|
|
7956
10019
|
};
|
|
7957
|
-
//# sourceMappingURL=chunk-
|
|
10020
|
+
//# sourceMappingURL=chunk-VWED6V6F.js.map
|