@weasel-js/text 1.13.0-rc.0 → 1.14.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.
@@ -1,1043 +0,0 @@
1
- import { isSolidPaint, resolveFill, resolveScreenLength } from '@weasel-js/paint';
2
- import { cssFamilyName, faceGeneration, resolveFontVariant, metricsOf, warnNoMetrics, resolveColorCluster, glyphIn, resolveGlyph } from '@weasel-js/font';
3
-
4
- var __defProp = Object.defineProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
-
10
- // src/layout/tabStops.ts
11
- var DEFAULT_TAB_SIZE = 8;
12
- function tabAdvance(x, stop, min) {
13
- if (!(stop > 0)) return 0;
14
- const toNext = (Math.floor(x / stop) + 1) * stop - x;
15
- return toNext < min ? toNext + stop : toNext;
16
- }
17
- function widthWithTabs(start, end, tabs, stopOf, flatWidth, piece) {
18
- let x = 0;
19
- let from = start;
20
- const lay = (to) => {
21
- if (to <= from) return;
22
- piece?.(from, to, x);
23
- x += flatWidth(from, to);
24
- };
25
- for (const t of tabs) {
26
- if (t < start) continue;
27
- if (t >= end) break;
28
- lay(t);
29
- const { stop, min } = stopOf(t);
30
- x += tabAdvance(x, stop, min);
31
- from = t + 1;
32
- }
33
- lay(end);
34
- return x;
35
- }
36
-
37
- // src/textStyle.ts
38
- function resolveAlign(align, direction) {
39
- if (align === "start" || align === "justify") return direction === "rtl" ? "right" : "left";
40
- if (align === "end") return direction === "rtl" ? "left" : "right";
41
- return align;
42
- }
43
- var DEFAULT_FILL = { kind: "solid", color: "#000" };
44
- var DEFAULT_TEXT_FILL = { paint: DEFAULT_FILL };
45
- function paintColor(p) {
46
- return isSolidPaint(p) ? p.color : "#000";
47
- }
48
- function defaultSelectionBackground(textColor) {
49
- return `color-mix(in srgb, ${textColor} 25%, transparent)`;
50
- }
51
- var DEFAULT_TEXT_STYLE = {
52
- fontSize: 16,
53
- fontFamily: "sans-serif",
54
- fontWeight: 400,
55
- fontStyle: "normal",
56
- align: "left",
57
- direction: "auto",
58
- lineHeight: 1.2,
59
- tabSize: DEFAULT_TAB_SIZE,
60
- wrap: false,
61
- fill: null,
62
- caretColor: paintColor(DEFAULT_FILL),
63
- selectionBackground: defaultSelectionBackground(paintColor(DEFAULT_FILL)),
64
- selectionColor: null,
65
- letterSpacing: 0,
66
- underline: false,
67
- strikethrough: false,
68
- overline: false,
69
- textTransform: "none",
70
- fontVariantCaps: "normal"
71
- };
72
- function resolveTextStyle(style, paint, scale = 1) {
73
- const fill = resolveFill(paint?.fill);
74
- const stroke = paint?.stroke ?? void 0;
75
- if (!style) {
76
- return fill === null && stroke === void 0 ? DEFAULT_TEXT_STYLE : {
77
- ...DEFAULT_TEXT_STYLE,
78
- fill,
79
- caretColor: paintColor(fill?.paint ?? null),
80
- selectionBackground: defaultSelectionBackground(paintColor(fill?.paint ?? null)),
81
- ...stroke !== void 0 ? { stroke } : {}
82
- };
83
- }
84
- const caretColor = style.caretColor ?? paintColor(fill?.paint ?? null);
85
- let selectionBackground;
86
- if (style.selectionBackground === "none") {
87
- selectionBackground = null;
88
- } else if (style.selectionBackground != null) {
89
- selectionBackground = style.selectionBackground;
90
- } else {
91
- selectionBackground = defaultSelectionBackground(caretColor);
92
- }
93
- return {
94
- fontSize: resolveScreenLength(style.fontSize ?? DEFAULT_TEXT_STYLE.fontSize, scale),
95
- fontFamily: style.fontFamily ?? DEFAULT_TEXT_STYLE.fontFamily,
96
- fontWeight: style.fontWeight ?? DEFAULT_TEXT_STYLE.fontWeight,
97
- fontStyle: style.fontStyle ?? DEFAULT_TEXT_STYLE.fontStyle,
98
- align: style.align ?? DEFAULT_TEXT_STYLE.align,
99
- direction: style.direction ?? DEFAULT_TEXT_STYLE.direction,
100
- lineHeight: style.lineHeight ?? DEFAULT_TEXT_STYLE.lineHeight,
101
- tabSize: style.tabSize ?? DEFAULT_TEXT_STYLE.tabSize,
102
- wrap: style.wrap ?? DEFAULT_TEXT_STYLE.wrap,
103
- fill,
104
- caretColor,
105
- selectionBackground,
106
- selectionColor: style.selectionColor ?? null,
107
- letterSpacing: resolveScreenLength(style.letterSpacing ?? DEFAULT_TEXT_STYLE.letterSpacing, scale),
108
- underline: style.underline ?? DEFAULT_TEXT_STYLE.underline,
109
- strikethrough: style.strikethrough ?? DEFAULT_TEXT_STYLE.strikethrough,
110
- overline: style.overline ?? DEFAULT_TEXT_STYLE.overline,
111
- textTransform: style.textTransform ?? DEFAULT_TEXT_STYLE.textTransform,
112
- fontVariantCaps: style.fontVariantCaps ?? DEFAULT_TEXT_STYLE.fontVariantCaps,
113
- ...style.script !== void 0 ? { script: style.script } : {},
114
- ...stroke !== void 0 ? { stroke } : {}
115
- };
116
- }
117
- function fontString(s) {
118
- return `${s.fontStyle} ${s.fontWeight} ${s.fontSize}px ${cssFamilyName(s.fontFamily)}`;
119
- }
120
-
121
- // src/layout/lineBreak/lineBreakTable.ts
122
- var lineBreakTable_exports = {};
123
- __export(lineBreakTable_exports, {
124
- AK: () => AK,
125
- AL: () => AL,
126
- AP: () => AP,
127
- AS: () => AS,
128
- B2: () => B2,
129
- BA: () => BA,
130
- BB: () => BB,
131
- BK: () => BK,
132
- CB: () => CB,
133
- CL: () => CL,
134
- CLASS_MASK: () => CLASS_MASK,
135
- CM: () => CM,
136
- CP: () => CP,
137
- CR: () => CR,
138
- EAST_ASIAN: () => EAST_ASIAN,
139
- EB: () => EB,
140
- EM: () => EM,
141
- EX: () => EX,
142
- GL: () => GL,
143
- H2: () => H2,
144
- H3: () => H3,
145
- HL: () => HL,
146
- HY: () => HY,
147
- ID: () => ID,
148
- IN: () => IN,
149
- IS: () => IS,
150
- JL: () => JL,
151
- JT: () => JT,
152
- JV: () => JV,
153
- LF: () => LF,
154
- NL: () => NL,
155
- NS: () => NS,
156
- NU: () => NU,
157
- OP: () => OP,
158
- PICTOGRAPHIC_CN: () => PICTOGRAPHIC_CN,
159
- PO: () => PO,
160
- PR: () => PR,
161
- QU: () => QU,
162
- QU_PF: () => QU_PF,
163
- QU_PI: () => QU_PI,
164
- RI: () => RI,
165
- SP: () => SP,
166
- SY: () => SY,
167
- UNICODE_VERSION: () => UNICODE_VERSION,
168
- VF: () => VF,
169
- VI: () => VI,
170
- WJ: () => WJ,
171
- ZW: () => ZW,
172
- ZWJ: () => ZWJ,
173
- lineBreakPropsOf: () => lineBreakPropsOf
174
- });
175
- var UNICODE_VERSION = "16.0.0";
176
- var BK = 0;
177
- var CR = 1;
178
- var LF = 2;
179
- var NL = 3;
180
- var SP = 4;
181
- var ZW = 5;
182
- var ZWJ = 6;
183
- var CM = 7;
184
- var WJ = 8;
185
- var GL = 9;
186
- var BA = 10;
187
- var BB = 11;
188
- var B2 = 12;
189
- var HY = 13;
190
- var CB = 14;
191
- var CL = 15;
192
- var CP = 16;
193
- var EX = 17;
194
- var IN = 18;
195
- var NS = 19;
196
- var OP = 20;
197
- var QU = 21;
198
- var IS = 22;
199
- var NU = 23;
200
- var PO = 24;
201
- var PR = 25;
202
- var SY = 26;
203
- var AL = 27;
204
- var HL = 28;
205
- var ID = 29;
206
- var EB = 30;
207
- var EM = 31;
208
- var H2 = 32;
209
- var H3 = 33;
210
- var JL = 34;
211
- var JV = 35;
212
- var JT = 36;
213
- var RI = 37;
214
- var AK = 38;
215
- var AP = 39;
216
- var AS = 40;
217
- var VF = 41;
218
- var VI = 42;
219
- var QU_PI = 43;
220
- var QU_PF = 44;
221
- var CLASS_MASK = 63;
222
- var EAST_ASIAN = 64;
223
- var PICTOGRAPHIC_CN = 128;
224
- var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+,-./:;<=>?@[]^_{|}~";
225
- var PALETTE = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 71, 73, 74, 79, 81, 82, 83, 84, 88, 89, 91, 93, 94, 95, 96, 97, 98, 155, 157];
226
- var RUNS = 2787;
227
- var PACKED = "9H1K1C2A1B18H1E1R1V1b1Z1Y1b1V1U1Q1b1Z1W1N1W1a10X2W3b1R27b1U1Z1Q29b1U1K1P1b6H1D26H1J1U1Y3Z5b1n1b1K2b1Y1Z2b1L6b1o3b1U520b1L3b1L18b1L32b79H1J12H7J13H14b1W260b7H255b1W1K4b1Z1b45H1K1H1b2H1b2H1R1H8b27c4b4c13b6X3b3Y2W2b11H1R1H3R43b21H10X1Y2X3b1H99b1R1b7H1X1b6H2b2H1b4H2b10X23b1H30b27H91b11H15b10X33b9H4b1W1R3b1H2Z22b4H1b9H1b3H1b5H43b3H52b2X5b9H42b24H1X33H54b3H1b18H1b7H10b2H2K10X17b3H56b1H1b7H2b2H2b3H9b1H10b2H2b10X2b2Y5b1Y1b1Z2b1H2b3H56b1H1b5H4b2H2b3H3b1H20b10X2H3b1H11b3H56b1H1b8H1b3H1b3H20b2H2b10X1b1Z8b6H1b3H56b1H1b7H2b2H2b3H7b3H10b2H2b10X18b1H59b5H3b3H1b4H9b1H14b10X9b1Z6b5H55b1H1b7H1b3H1b4H7b2H11b2H2b10X7b1L9b3H1L55b1H1b7H1b3H1b4H7b2H11b2H2b10X3b1H12b4H55b2H1b7H1b3H1b4H9b1H10b2H2b10X9b1Y7b3H70b1H4b6H1b1H1b8H6b10X2b2H61b1H2b7H4b1Z7b8H1b10X2K85b1H2b9H11b7H1b10X39b4L1b2L1J2L1K1J5R1J1b1R3b2H6b10X10b1K1H1b1H1b1H1U1P1U1P2H49b14H1K5H1K2H5b11H1b36H1b2K6b1H9b2L1K1L5b2J80b20H1b10X2K10b4H4b3H1b3H2b7H3b4H13b12H1b1H10X4H98b96(72f88g349b3H1b1K158b1K639b1K26b1U1P78b3K36b4H28b3H2K27b2H30b2H64b32H2K1T1b1K1b1K1Z1b1H2b10X24b2R2K1L1b2R1b3H1J1H10X107b2H34b1H118b12H4b12H8b2R10X128b11X60b5H57b10H1b29H2b1H10X6b10X22b31H49b5H47i16H1m8i1b2K10k2K1d4K10d9H9d3K3H30b13H2b10X6b38k12H2l48b20H3b5K10X6b10X36b2K80b3H1b21H4b1H6b1H2b3H198b13H1J46H1J3H509b1L2b7K1J3K1F1H1G2H1K1J2K1M3b1n1o1U2n1o1U1n4b3S1K2A5H1J8Y1b1n1o1b2T6b1W1U1P3T12b1K1Y4K1b3K1I5b10H13b1U1P14b1U1P17b7Z1Y1Z1y12Z1Y4Z1Y2Z1Y1Z1Y15Z33H18b1Y5b1Y12b1Z251b2Z219b1S24b1U1P1U1P14b2!13b1w1s190b4z3b1!2d1!521b2z1b4d16b2!2b1d1b3d1e2d16b8z1b3d12b12z20b1d22b1!10b6z3b1z13b1z8b2z17b2!5d2!3d4b1d1z3d1b1d1!3b2d2b1d2b3d8b1!6b1d2!1d1!1b2d1e1!2b1!7d1z2b2d2#2e26b1z35b1z1b1z4b3z1b1z3b6V1b2R1d3b1U1P1U1P1U1P1U1P1U1P1U1P1U1P31b3z24b1z14b1z5b1U1P31b1U1P1U1P1U1P1U1P1U1P403b1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P63b1U1P1U1P32b1U1P285b2z51b1z4b1z409b3H7b1R3K1b1R1K112b1K14b1H96b32H2V1n1o1n1o3V1n1o1V1n1o8K1b1K1U1K2b1n1o2b1n1o1U1P1U1P1U1P1U1P4K1R1b2K1b2K5b2M3K1b2K1U8K1b1K1b2K3b2R1U1Q1U1Q1U1Q1U1Q1K34b26!1b89!12b214!26b16!1r2s2!1v2!1w1s1w1s1w1s1w1s1w1s2!1w1s1w1s1w1s1w1s1v1w2s10!6p5!1p5!2v2!1d1b1v1!1v1!1v1!1v1!1v25!1v31!1v1!1v1!1v6!1v6!2v2b2p4v1!2v1!1v1!1v1!1v1!1v25!1v31!1v1!1v1!1v6!1v6!2v4!4v1!5b43!1b94!1b86!9b1!16v31!1b40!8b7024!64z21013!1v1143!3b55!55b2K269b1K1R1K16b10X69b4H1b10H32b2H80b2H1b5K266b1H3b1H4b1H23b5H4b1H11b1Y59b2L2R8b2H50b18H8b2K10X6b18H10b1L2b1H10X28b8H2K23b13H12b29(3b4H47i13H1m6d3K4d1b1K10k4b2d5b1H10b10X6b41k14H9b3K1H8K2H2b10k2b1d3K27b3H50b1H1b3H2b2H5b2H1b1H41b5H2K3b2H236b8H1K2H2b10X6b1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&12b23f4b49g8452b512!29b1c1H10c1b13c1b5c1b1c1b2c1b2c1b10c494b1P1U188b1Y3b16H3s2v2t1w1s1u6b1J1H1J1H1J1H2J1H1J1H1J1H2J1H5!1w1s1w1s1w1s1w1s1w1s1w1s1w1s1w1s2!1w1s7!1s1!1s1b2v2t1!1w1s1w1s1w1s8!1b1!1y1x1!147b1I1b1t2!1y1x2!1w1s2!1s1!1s11!2v3!1t27!1w1!1s29!1w1!1s1!1w2s1w2s1v1!10v45!2v31!3b6!2b6!2b6!2b3!3b1x1y3!2y1b7z10b3H1O259b3K250b1H226b1H149b5H36b1K48b1K207b10X941b1K199b1K225b3H1b2H5b4H40b3H4b1H16b8K141b2H9b6K1S66b7K484b4H8b10X6b10X31b5H1K316b2H1K78b4H70b11H49b4H122b3H2j51i14H1m2K5d4b20d10k1H2i2H1i9b1J3H45b11H2b1X4K1H10b1X34b10X6b3H36b14H1b10X4K1b2H44b1H1b1L10b3H48b14H4b2K1b1K4H1b2H10X1b1L1b3K76b12H2K1b2K1b1H2b1H103b1K53b12H5b10X6b4H1b8i2b2i2b22i1b7i1b2i1b5i1b2H1K7H2b2H2b2H1m2b1k6b1H5b1K2k2i2H2b7H3b5H11b10k1b1k2b1k1b2k36i1b1d9H1b1H2b1H1b4H1b4H1m1j1H3d1b2d8b2H82b18H4b4K1b10X2K2b1H81b20H12b10X213b7H2b9H1L2K2R3b15K4b2H82b17H2K13b10X6b13L62b13H8b10X6b20X57b15H4b10X2b3K237b15H165b10X22b7i2b1i2b8i1b2i1b24i6H1b2H2b3H1m1j1H1j2H3K9b10k119b7H2b7H1b1L1b1H28b10H40b7H1b4H1L1b4K1L1b1H9b11H46b16H3K1b3L2K93b10L230b10X53b8H1b8H1b5K10b10X22b1L1R32b22H1b14H122b6H3b1H1b2H1b7H1b1H8b10X48b5H1b2H1b5H8b10X310b18k1K4H2K7b2H1j1H13i1b34i7H3b4H1m2K11d10k1H130b4Y30b1K1136b5K3555b3U3P36b1P3b1U1P1U1P239b1U2P179b1U7J1U1P3J1U1P1U1P1H6b15H4472b1U1P6960b30k18H10k2342b10X4b2K80b10X38b5H1K58b7H3K10b1K11b10X532b2K10X285b2K182b1H1b55H7b4H77b4v1q11b2p14b6136!8b768!470z41b1z9!8935b4z1b7z1b2z1b291!15b1v29b3v2b1v14b4v8b396!2465b2H1K4H4172b10X518b46H2b23H542b5H3b22H2b7H30b4H148b3H187b87z9b23z1111b50X512b55H4b50H8b1H14b1H2b4K16b5H1b15H1360b7H1b17H2b7H1b2H1b5H100b1H160b7H9b10X356b1H61b4H10X5b1Z492b4H10X244b2H1b10X725b7H109b7H5b10X4b2U844b1Y3b1Y847b4d1!39d4*100d12*15d2*15d1*14d1!1*37d10*142b1z2b10z19b56*26h3!13*44!4*9!7*2!14*6!154*33!12d9!1d70!1d7!1#14!8d2b2d21!2z5!1z5!3#2!1#2!1#2e2d5!12d17!3d1!3d3!5$63!1d1!1d2#2!11#21!19#3!1#4!3#1!3#7!1#1!1#14!1z1!1z1!1z5!1#4!1z1!2z74!2d1!7z16!14z13!12z12b1d4!1d24!12d2e4d1#21d1e4d2#13d1!47d8b24d6b1d74!3#3!5#38b3V3T4b35!1#16!3#9!1#5!6d1#3d3!2d3!4*4!11d2!3*4d9!3*116b3d4*5d85b5d6*12!4*1!15*12b4)56b8)10b6)40b8)30b2)12b4)2b62)12b1#2!1#8!8#6!1#9!10#1!1d3#7!1d48!1#61!2#1!2#1!1#17!3#1!13#34!84b12*14d2*13!3*10!5*52!3#1!7*15!2*11!6*9#7*240b10X6b1022*2b65534!2b65534!655363b1H30b96H128b240H196112b";
228
- var bmp = null;
229
- var astralStarts = null;
230
- var astralValues = null;
231
- function decode() {
232
- const direct = new Uint8Array(65536);
233
- const starts = new Int32Array(RUNS);
234
- const values = new Uint8Array(RUNS);
235
- const slot = new Uint8Array(128);
236
- for (let i = 0; i < ALPHABET.length; i++) slot[ALPHABET.charCodeAt(i)] = PALETTE[i];
237
- let cp = 0;
238
- let run = 0;
239
- let len = 0;
240
- for (let i = 0; i < PACKED.length; i++) {
241
- const code = PACKED.charCodeAt(i);
242
- if (code <= 57 && code >= 48) len = len * 10 + code - 48;
243
- else {
244
- const v = slot[code];
245
- starts[run] = cp;
246
- values[run] = v;
247
- if (cp < 65536) direct.fill(v, cp, Math.min(cp + len, 65536));
248
- run++;
249
- cp += len;
250
- len = 0;
251
- }
252
- }
253
- bmp = direct;
254
- astralStarts = starts;
255
- astralValues = values;
256
- }
257
- function lineBreakPropsOf(cp) {
258
- if (bmp === null) decode();
259
- if (cp < 65536) return bmp[cp];
260
- if (cp > 1114111) return AL;
261
- const starts = astralStarts;
262
- let lo = 0;
263
- let hi = starts.length - 1;
264
- while (lo < hi) {
265
- const mid = lo + hi + 1 >> 1;
266
- if (starts[mid] <= cp) lo = mid;
267
- else hi = mid - 1;
268
- }
269
- return astralValues[lo];
270
- }
271
-
272
- // src/layout/lineBreak/lineBreaks.ts
273
- var {
274
- lineBreakPropsOf: lineBreakPropsOf2,
275
- CLASS_MASK: CLASS_MASK2,
276
- EAST_ASIAN: EAST_ASIAN2,
277
- PICTOGRAPHIC_CN: PICTOGRAPHIC_CN2,
278
- BK: BK2,
279
- CR: CR2,
280
- LF: LF2,
281
- NL: NL2,
282
- SP: SP2,
283
- ZW: ZW2,
284
- ZWJ: ZWJ2,
285
- CM: CM2,
286
- WJ: WJ2,
287
- GL: GL2,
288
- BA: BA2,
289
- BB: BB2,
290
- B2: B22,
291
- HY: HY2,
292
- CB: CB2,
293
- CL: CL2,
294
- CP: CP2,
295
- EX: EX2,
296
- IN: IN2,
297
- NS: NS2,
298
- OP: OP2,
299
- QU: QU2,
300
- IS: IS2,
301
- NU: NU2,
302
- PO: PO2,
303
- PR: PR2,
304
- SY: SY2,
305
- AL: AL2,
306
- HL: HL2,
307
- ID: ID2,
308
- EB: EB2,
309
- EM: EM2,
310
- H2: H22,
311
- H3: H32,
312
- JL: JL2,
313
- JV: JV2,
314
- JT: JT2,
315
- RI: RI2,
316
- AK: AK2,
317
- AP: AP2,
318
- AS: AS2,
319
- VF: VF2,
320
- VI: VI2,
321
- QU_PI: QU_PI2,
322
- QU_PF: QU_PF2
323
- } = lineBreakTable_exports;
324
- var NO_BREAK = 0;
325
- var BREAK_ALLOWED = 1;
326
- var BREAK_MANDATORY = 2;
327
- var HYPHEN = 8208;
328
- var DOTTED_CIRCLE = 9676;
329
- var isQU = (c) => c === QU2 || c === QU_PI2 || c === QU_PF2;
330
- var isHard = (c) => c === BK2 || c === CR2 || c === LF2 || c === NL2;
331
- function isHardLineBreak(cp) {
332
- return isHard(lineBreakPropsOf2(cp) & CLASS_MASK2);
333
- }
334
- var isAlpha = (c) => c === AL2 || c === HL2;
335
- var isKorean = (c) => c === JL2 || c === JV2 || c === JT2 || c === H22 || c === H32;
336
- var isIdeoLike = (c) => c === ID2 || c === EB2 || c === EM2;
337
- function lineBreakOpportunities(cps) {
338
- const n = cps.length;
339
- const out = new Uint8Array(n + 1);
340
- if (n === 0) return out;
341
- out[n] = BREAK_MANDATORY;
342
- const cls = new Uint8Array(n);
343
- const ea = new Uint8Array(n);
344
- const pict = new Uint8Array(n);
345
- const cp = new Int32Array(n);
346
- const start = new Int32Array(n);
347
- let u = 0;
348
- for (let i = 0; i < n; i++) {
349
- const props = lineBreakPropsOf2(cps[i]);
350
- const c = props & CLASS_MASK2;
351
- if ((c === CM2 || c === ZWJ2) && u > 0) {
352
- const base = cls[u - 1];
353
- if (!isHard(base) && base !== SP2 && base !== ZW2) continue;
354
- }
355
- if (c === CM2 || c === ZWJ2) {
356
- cls[u] = AL2;
357
- ea[u] = 0;
358
- pict[u] = 0;
359
- } else {
360
- cls[u] = c;
361
- ea[u] = props & EAST_ASIAN2 ? 1 : 0;
362
- pict[u] = props & PICTOGRAPHIC_CN2 ? 1 : 0;
363
- }
364
- cp[u] = cps[i];
365
- start[u] = i;
366
- u++;
367
- }
368
- const units = u;
369
- const prevIsZWJ = (b) => (lineBreakPropsOf2(cps[start[b] - 1]) & CLASS_MASK2) === ZWJ2;
370
- const beforeSpaces = (k) => {
371
- while (k >= 0 && cls[k] === SP2) k--;
372
- return k;
373
- };
374
- for (let b = 1; b < units; b++) {
375
- out[start[b]] = decide(b);
376
- }
377
- return out;
378
- function decide(b) {
379
- const a = b - 1;
380
- const A = cls[a];
381
- const B = cls[b];
382
- if (A === CR2 && B === LF2) return NO_BREAK;
383
- if (isHard(A)) return BREAK_MANDATORY;
384
- if (isHard(B) || B === SP2 || B === ZW2) return NO_BREAK;
385
- const s = beforeSpaces(a);
386
- if (s >= 0 && cls[s] === ZW2) return BREAK_ALLOWED;
387
- if (prevIsZWJ(b)) return NO_BREAK;
388
- if (A === WJ2 || B === WJ2 || A === GL2) return NO_BREAK;
389
- if (B === GL2 && A !== SP2 && A !== BA2 && A !== HY2) return NO_BREAK;
390
- if (B === CL2 || B === CP2 || B === EX2 || B === SY2) return NO_BREAK;
391
- const S = s >= 0 ? cls[s] : -1;
392
- if (S === OP2) return NO_BREAK;
393
- if (S === QU_PI2) {
394
- const p = s - 1;
395
- if (p < 0) return NO_BREAK;
396
- const P = cls[p];
397
- if (isHard(P) || P === OP2 || isQU(P) || P === GL2 || P === SP2 || P === ZW2) return NO_BREAK;
398
- }
399
- if (B === QU_PF2) {
400
- if (b + 1 >= units) return NO_BREAK;
401
- const N = cls[b + 1];
402
- if (N === SP2 || N === GL2 || N === WJ2 || N === CL2 || isQU(N) || N === CP2 || N === EX2 || N === IS2 || N === SY2 || isHard(N) || N === ZW2) return NO_BREAK;
403
- }
404
- if (A === SP2 && B === IS2 && b + 1 < units && cls[b + 1] === NU2) return BREAK_ALLOWED;
405
- if (B === IS2) return NO_BREAK;
406
- if ((S === CL2 || S === CP2) && B === NS2) return NO_BREAK;
407
- if (S === B22 && B === B22) return NO_BREAK;
408
- if (A === SP2) return BREAK_ALLOWED;
409
- if (B === QU2 || B === QU_PF2) return NO_BREAK;
410
- if (A === QU2 || A === QU_PI2) return NO_BREAK;
411
- if (isQU(B)) {
412
- if (!ea[a]) return NO_BREAK;
413
- if (b + 1 >= units || !ea[b + 1]) return NO_BREAK;
414
- }
415
- if (isQU(A)) {
416
- if (!ea[b]) return NO_BREAK;
417
- if (a === 0 || !ea[a - 1]) return NO_BREAK;
418
- }
419
- if (A === CB2 || B === CB2) return BREAK_ALLOWED;
420
- if ((A === HY2 || cp[a] === HYPHEN) && B === AL2) {
421
- if (a === 0) return NO_BREAK;
422
- const P = cls[a - 1];
423
- if (isHard(P) || P === SP2 || P === ZW2 || P === CB2 || P === GL2) return NO_BREAK;
424
- }
425
- if (B === BA2 || B === HY2 || B === NS2 || A === BB2) return NO_BREAK;
426
- if (a > 0 && cls[a - 1] === HL2 && (A === HY2 || A === BA2 && !ea[a]) && B !== HL2) return NO_BREAK;
427
- if (A === SY2 && B === HL2) return NO_BREAK;
428
- if (B === IN2) return NO_BREAK;
429
- if (isAlpha(A) && B === NU2 || A === NU2 && isAlpha(B)) return NO_BREAK;
430
- if (A === PR2 && isIdeoLike(B) || isIdeoLike(A) && B === PO2) return NO_BREAK;
431
- if ((A === PR2 || A === PO2) && isAlpha(B) || isAlpha(A) && (B === PR2 || B === PO2)) return NO_BREAK;
432
- if (B === PO2 || B === PR2) {
433
- let k = A === CL2 || A === CP2 ? a - 1 : a;
434
- while (k >= 0 && (cls[k] === SY2 || cls[k] === IS2)) k--;
435
- if (k >= 0 && cls[k] === NU2) return NO_BREAK;
436
- }
437
- if (A === PO2 || A === PR2) {
438
- if (B === NU2) return NO_BREAK;
439
- if (B === OP2 && b + 1 < units) {
440
- const N = cls[b + 1];
441
- if (N === NU2) return NO_BREAK;
442
- if (N === IS2 && b + 2 < units && cls[b + 2] === NU2) return NO_BREAK;
443
- }
444
- }
445
- if ((A === HY2 || A === IS2) && B === NU2) return NO_BREAK;
446
- if (B === NU2) {
447
- let k = a;
448
- while (k >= 0 && (cls[k] === SY2 || cls[k] === IS2)) k--;
449
- if (k >= 0 && cls[k] === NU2) return NO_BREAK;
450
- }
451
- if (A === JL2 && (B === JL2 || B === JV2 || B === H22 || B === H32)) return NO_BREAK;
452
- if ((A === JV2 || A === H22) && (B === JV2 || B === JT2)) return NO_BREAK;
453
- if ((A === JT2 || A === H32) && B === JT2) return NO_BREAK;
454
- if (isKorean(A) && B === PO2 || A === PR2 && isKorean(B)) return NO_BREAK;
455
- if (isAlpha(A) && isAlpha(B)) return NO_BREAK;
456
- const aksaraA = A === AK2 || A === AS2 || cp[a] === DOTTED_CIRCLE;
457
- const aksaraB = B === AK2 || B === AS2 || cp[b] === DOTTED_CIRCLE;
458
- if (A === AP2 && aksaraB) return NO_BREAK;
459
- if (aksaraA && (B === VF2 || B === VI2)) return NO_BREAK;
460
- if (A === VI2 && a > 0 && (cls[a - 1] === AK2 || cls[a - 1] === AS2 || cp[a - 1] === DOTTED_CIRCLE) && (B === AK2 || cp[b] === DOTTED_CIRCLE)) return NO_BREAK;
461
- if (aksaraA && aksaraB && b + 1 < units && cls[b + 1] === VF2) return NO_BREAK;
462
- if (A === IS2 && isAlpha(B)) return NO_BREAK;
463
- if ((isAlpha(A) || A === NU2) && B === OP2 && !ea[b]) return NO_BREAK;
464
- if (A === CP2 && !ea[a] && (isAlpha(B) || B === NU2)) return NO_BREAK;
465
- if (A === RI2 && B === RI2) {
466
- let k = a;
467
- while (k >= 0 && cls[k] === RI2) k--;
468
- if ((a - k) % 2 === 1) return NO_BREAK;
469
- }
470
- if (B === EM2 && (A === EB2 || pict[a])) return NO_BREAK;
471
- return BREAK_ALLOWED;
472
- }
473
- }
474
-
475
- // src/layout/bidiRegistry.ts
476
- var registered = null;
477
- function registerBidi(engine) {
478
- registered = engine;
479
- return () => {
480
- if (registered === engine) registered = null;
481
- };
482
- }
483
- function registeredBidi() {
484
- return registered;
485
- }
486
- function directionOfLevel(level) {
487
- return level % 2 === 1 ? "rtl" : "ltr";
488
- }
489
- function paragraphDirection(text, direction = "auto", engine = registered) {
490
- if (direction !== "auto") return direction;
491
- if (engine === null) return "ltr";
492
- const cps = [];
493
- for (const ch of text) {
494
- const cp = ch.codePointAt(0);
495
- if (isHardLineBreak(cp)) break;
496
- cps.push(cp);
497
- }
498
- return directionOfLevel(engine.baseLevel(engine.analyze(cps, "auto")));
499
- }
500
- var RTL_BLOCKS = [
501
- [1424, 1535],
502
- [1536, 1983],
503
- [2144, 2303],
504
- [64285, 65023],
505
- [65136, 65279],
506
- [67584, 69631],
507
- [124928, 126975]
508
- ];
509
- var RTL_BLOCK_NUMBERS = [
510
- [1536, 1541],
511
- [1632, 1644],
512
- [1757, 1757],
513
- [1776, 1785],
514
- [2274, 2274],
515
- [68912, 68921],
516
- [69216, 69246]
517
- ];
518
- var RTL_BLOCK_NEUTRALS = [
519
- [1548, 1548],
520
- [64830, 64831],
521
- [65279, 65279]
522
- ];
523
- var within = (ranges, cp) => ranges.some(([lo, hi]) => cp >= lo && cp <= hi);
524
- var warnedLogicalRtl = false;
525
- function warnRtlWithoutEngine(codePoints) {
526
- if (warnedLogicalRtl) return;
527
- for (const cp of codePoints) {
528
- if (!within(RTL_BLOCKS, cp) || within(RTL_BLOCK_NUMBERS, cp) || within(RTL_BLOCK_NEUTRALS, cp)) continue;
529
- warnedLogicalRtl = true;
530
- console.warn(
531
- // Naming the import in `from "<pkg>"` form would trip labkit's
532
- // consumer smoke test, which greps dist for that exact shape.
533
- "weasel layoutRuns: this text contains right-to-left characters but no `bidi` engine is registered, so it is being laid out in logical order \u2014 the glyphs will appear reversed. Import `bidi` out of the `@weasel-js/bidi` package and call `registerBidi(bidi)` once at startup."
534
- );
535
- return;
536
- }
537
- }
538
- function _resetBidiWarningForTests() {
539
- warnedLogicalRtl = false;
540
- }
541
-
542
- // src/layout/bidiLines.ts
543
- function analyzeParagraphs(engine, codePoints, isBreak, direction) {
544
- const paragraphs = [];
545
- let start = 0;
546
- for (let i = 0; i <= codePoints.length; i++) {
547
- if (i < codePoints.length && !isBreak(i)) continue;
548
- if (i > start) {
549
- paragraphs.push({ start, end: i, analysis: engine.analyze(codePoints.slice(start, i), direction) });
550
- }
551
- start = i + 1;
552
- }
553
- const holding = (at) => {
554
- let lo = 0;
555
- let hi = paragraphs.length - 1;
556
- while (lo < hi) {
557
- const mid = lo + hi >> 1;
558
- if (paragraphs[mid].end <= at) lo = mid + 1;
559
- else hi = mid;
560
- }
561
- const p = paragraphs[lo];
562
- return p !== void 0 && at >= p.start && at < p.end ? p : void 0;
563
- };
564
- return {
565
- reorder(from, to) {
566
- const p = holding(from);
567
- if (p === void 0 || to > p.end) return { order: [], levels: [] };
568
- const r = engine.reorder(p.analysis, from - p.start, to - p.start);
569
- return { order: r.order.map((i) => i + p.start), levels: r.levels };
570
- },
571
- baseLevel(at) {
572
- const p = holding(at);
573
- return p === void 0 ? 0 : engine.baseLevel(p.analysis);
574
- }
575
- };
576
- }
577
- function restoreRemoved(order, count, rtl) {
578
- if (order.length === count) return [...order];
579
- const kept = new Set(order);
580
- const leading = [];
581
- const following = /* @__PURE__ */ new Map();
582
- let anchor = -1;
583
- let firstKept = -1;
584
- for (let k = 0; k < count; k++) {
585
- if (kept.has(k)) {
586
- anchor = k;
587
- if (firstKept < 0) firstKept = k;
588
- } else if (anchor < 0) {
589
- leading.push(k);
590
- } else {
591
- const list = following.get(anchor);
592
- if (list) list.push(k);
593
- else following.set(anchor, [k]);
594
- }
595
- }
596
- if (firstKept < 0) return leading;
597
- const out = [];
598
- for (const p of order) {
599
- const after = following.get(p) ?? [];
600
- const before = p === firstKept ? leading : [];
601
- if (rtl(p)) out.push(...[...after].reverse(), p, ...[...before].reverse());
602
- else out.push(...before, p, ...after);
603
- }
604
- return out;
605
- }
606
- function orderLine(paragraphs, start, count) {
607
- const levels = new Array(count).fill(0);
608
- if (paragraphs === null || count === 0) return { visual: levels.map((_, pos) => pos), levels };
609
- const r = paragraphs.reorder(start, start + count);
610
- for (let pos = 0; pos < count; pos++) {
611
- const level = r.levels[pos];
612
- if (typeof level === "number" && level >= 0) levels[pos] = level;
613
- }
614
- const kept = /* @__PURE__ */ new Set();
615
- for (const at of r.order) {
616
- const pos = at - start;
617
- if (Number.isInteger(pos) && pos >= 0 && pos < count) kept.add(pos);
618
- }
619
- return { visual: restoreRemoved([...kept], count, (pos) => levels[pos] % 2 === 1), levels };
620
- }
621
-
622
- // src/measure/graphemes.ts
623
- var segmenter;
624
- var NEEDS_SEGMENTING = /[\r\u0300-\uffff]/;
625
- function graphemeSegmenter() {
626
- if (segmenter === void 0) {
627
- segmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
628
- }
629
- return segmenter;
630
- }
631
- function graphemeEnds(text) {
632
- const out = [];
633
- if (!NEEDS_SEGMENTING.test(text)) {
634
- for (let i = 1; i <= text.length; i++) out.push(i);
635
- return out;
636
- }
637
- const seg = graphemeSegmenter();
638
- if (seg) {
639
- for (const s of seg.segment(text)) out.push(s.index + s.segment.length);
640
- return out;
641
- }
642
- let at = 0;
643
- for (const ch of text) out.push(at += ch.length);
644
- return out;
645
- }
646
- function graphemeCount(text) {
647
- return graphemeEnds(text).length;
648
- }
649
-
650
- // src/layout/layoutEntries.ts
651
- var NONSPACING_MARK = /^[\p{Mn}\p{Me}]$/u;
652
- function measureRuns(runs, tabSize) {
653
- const entries = [];
654
- let prev;
655
- let srcIndex = 0;
656
- runs.forEach((run, runIndex) => {
657
- const resolved = resolveFontVariant(run.fontFamily, run.fontWeight, run.fontStyle);
658
- const metrics = metricsOf(resolved);
659
- if (!metrics) {
660
- warnNoMetrics(run.fontFamily, run.fontWeight, run.fontStyle);
661
- srcIndex += run.srcMap?.length ?? run.text.length;
662
- prev = void 0;
663
- return;
664
- }
665
- const runBase = srcIndex;
666
- const map = run.srcMap;
667
- const clusterEnds = graphemeEnds(run.text);
668
- let cluster = 0;
669
- let clusterStart = 0;
670
- let color = null;
671
- let at = 0;
672
- for (const ch of run.text) {
673
- const cp = ch.codePointAt(0);
674
- const fontSize = run.sizeMap ? run.sizeMap[at] : run.fontSize;
675
- if (at === clusterStart) {
676
- color = resolveColorCluster(
677
- resolved,
678
- run.fontFamily,
679
- run.fontWeight,
680
- run.fontStyle,
681
- run.text.slice(at, clusterEnds[cluster])
682
- );
683
- }
684
- const clusterEnd = at + ch.length === clusterEnds[cluster];
685
- if (clusterEnd) clusterStart = clusterEnds[cluster++];
686
- const tracking = clusterEnd ? run.letterSpacing : 0;
687
- const srcStart = map ? runBase + map.starts[at] : runBase + at;
688
- const srcEnd = map ? runBase + map.ends[at] : runBase + at + ch.length;
689
- at += ch.length;
690
- srcIndex = map ? runBase + map.length : srcEnd;
691
- const mark = NONSPACING_MARK.test(ch);
692
- const kerningBefore = prev && !mark ? prev.metrics.kernOf(prev.cp, cp) * (prev.fontSize / prev.metrics.size) : 0;
693
- const blank = {
694
- run: runIndex,
695
- cp,
696
- fontSize,
697
- lineSize: Math.max(run.fontSize, run.strutSize ?? 0),
698
- // Optional on the authored run type; absent, every y would go NaN.
699
- baselineShift: run.baselineShift ?? 0,
700
- srcIndex: srcStart,
701
- srcEnd,
702
- clusterEnd,
703
- resolved,
704
- metrics,
705
- font: null,
706
- glyph: null,
707
- advance: 0,
708
- tracking: 0,
709
- kerningBefore: 0,
710
- drawsInk: false
711
- };
712
- if (color) {
713
- entries.push(clusterEnd ? ink(blank, color, 0, tracking) : blank);
714
- prev = void 0;
715
- } else if (isHardLineBreak(cp)) {
716
- entries.push(blank);
717
- prev = void 0;
718
- } else if (cp === 9 || cp === 32) {
719
- const space = metrics.advanceOf(32);
720
- const advance = space !== null ? space * (fontSize / metrics.size) : fontSize * 0.25;
721
- if (cp === 9) {
722
- entries.push({ ...blank, tab: { stop: tabSize * (advance + run.letterSpacing), min: advance / 2 } });
723
- prev = void 0;
724
- } else {
725
- const own = glyphIn(resolved, 32);
726
- blank.font = own?.font ?? null;
727
- blank.glyph = own?.glyph ?? null;
728
- blank.advance = advance;
729
- blank.tracking = tracking;
730
- blank.kerningBefore = kerningBefore;
731
- prev = blank;
732
- entries.push(prev);
733
- }
734
- } else {
735
- const hit = resolveGlyph(resolved, run.fontFamily, run.fontWeight, run.fontStyle, cp);
736
- const entry = hit ? ink(blank, hit, kerningBefore, tracking) : blank;
737
- entries.push(entry);
738
- if (!mark) prev = entry;
739
- }
740
- }
741
- });
742
- return entries;
743
- }
744
- function ink(e, hit, kerning, tracking) {
745
- e.resolved = hit.resolved;
746
- e.metrics = hit.metrics;
747
- e.font = hit.font;
748
- e.glyph = hit.glyph;
749
- e.advance = hit.advance * (e.fontSize / hit.metrics.size);
750
- e.tracking = tracking;
751
- e.kerningBefore = kerning;
752
- e.drawsInk = true;
753
- return e;
754
- }
755
- function mirrorEntries(entries, levels, mirror, runs) {
756
- return entries.map((entry, pos) => {
757
- if (levels[pos] % 2 === 0) return entry;
758
- const cp = mirror(entry.cp);
759
- if (cp === null || cp === entry.cp) return entry;
760
- if (entry.font === null) return { ...entry, cp };
761
- const run = runs[entry.run];
762
- const hit = resolveGlyph(entry.resolved, run.fontFamily, run.fontWeight, run.fontStyle, cp, false);
763
- if (!hit) return entry;
764
- return { ...entry, cp, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph };
765
- });
766
- }
767
-
768
- // src/layout/lineBreak/wrapLines.ts
769
- var hangs = (cp) => cp === 32 || cp === 9;
770
- function wrapLines(cps, maxWidth, widthOf) {
771
- const n = cps.length;
772
- const breaks = Number.isFinite(maxWidth) ? lineBreakOpportunities(cps) : null;
773
- const lines = [];
774
- let start = 0;
775
- let i = 0;
776
- while (i < n) {
777
- const cp = cps[i];
778
- if (isHardLineBreak(cp)) {
779
- lines.push({ start, end: i, wrapped: false });
780
- i += cp === 13 && cps[i + 1] === 10 ? 2 : 1;
781
- start = i;
782
- continue;
783
- }
784
- if (hangs(cp)) {
785
- i++;
786
- continue;
787
- }
788
- let j = i + 1;
789
- let ink2 = i + 1;
790
- while (j < n && !isHardLineBreak(cps[j]) && (!breaks || breaks[j] === NO_BREAK)) {
791
- if (!hangs(cps[j])) ink2 = j + 1;
792
- j++;
793
- }
794
- if (breaks && i > start && widthOf(start, ink2) > maxWidth) {
795
- lines.push({ start, end: i, wrapped: true });
796
- start = i;
797
- }
798
- i = j;
799
- }
800
- if (start < n) lines.push({ start, end: n, wrapped: false });
801
- return lines;
802
- }
803
-
804
- // src/layout/layoutLines.ts
805
- function aboveBaseline(e, lineHeight) {
806
- const k = e.lineSize / e.metrics.size;
807
- const ascent = e.metrics.ascent * k;
808
- if (e.metrics.descent === void 0) return ascent;
809
- return (e.lineSize * lineHeight - ascent - e.metrics.descent * k) / 2 + ascent;
810
- }
811
- function breakLines(entries, maxWidth, lineHeight) {
812
- const sum = new Float64Array(entries.length + 1);
813
- const tabs = [];
814
- entries.forEach((e, k) => {
815
- sum[k + 1] = sum[k] + e.kerningBefore + e.advance + e.tracking;
816
- if (e.tab) tabs.push(k);
817
- });
818
- const flatWidth = (start, end) => entries[start].advance + entries[start].tracking + sum[end] - sum[start + 1];
819
- const widthOf = tabs.length === 0 ? flatWidth : (start, end) => widthWithTabs(start, end, tabs, (k) => entries[k].tab, flatWidth);
820
- return wrapLines(entries.map((e) => e.cp), maxWidth, widthOf).map((span) => {
821
- const line = {
822
- start: span.start,
823
- entries: [],
824
- width: 0,
825
- height: 0,
826
- ascent: 0,
827
- wrapped: span.wrapped,
828
- srcEnd: 0
829
- };
830
- if (span.start === span.end) {
831
- const brk = entries[span.end];
832
- line.height = brk.lineSize * lineHeight;
833
- line.ascent = aboveBaseline(brk, lineHeight);
834
- line.srcEnd = brk.srcIndex;
835
- return line;
836
- }
837
- for (let k = span.start; k < span.end; k++) {
838
- const e = entries[k];
839
- const opened = k > span.start ? e : { ...e, kerningBefore: 0 };
840
- const placed = e.tab ? { ...opened, advance: tabAdvance(line.width, e.tab.stop, e.tab.min) } : opened;
841
- line.entries.push(placed);
842
- line.width += placed.kerningBefore + placed.advance + placed.tracking;
843
- line.height = Math.max(line.height, e.lineSize * lineHeight);
844
- line.ascent = Math.max(line.ascent, aboveBaseline(placed, lineHeight));
845
- }
846
- line.srcEnd = entries[span.end - 1].srcEnd;
847
- return line;
848
- });
849
- }
850
- function hungWidth(entries) {
851
- let hung = 0;
852
- for (let k = entries.length - 1; k >= 0 && hangs(entries[k].cp); k--) {
853
- const e = entries[k];
854
- hung += e.kerningBefore + e.advance + e.tracking;
855
- }
856
- return hung;
857
- }
858
- function wordGaps(entries) {
859
- const gaps = /* @__PURE__ */ new Set();
860
- let first = 0;
861
- while (first < entries.length && entries[first].cp === 32) first++;
862
- let last = entries.length - 1;
863
- while (last > first && entries[last].cp === 32) last--;
864
- for (let k = first + 1; k < last; k++) if (entries[k].cp === 32) gaps.add(k);
865
- return gaps;
866
- }
867
- function alignOffset(align, alignWidth, inkWidth) {
868
- if (align === "left") return 0;
869
- if (!Number.isFinite(alignWidth)) return align === "center" ? -inkWidth / 2 : -inkWidth;
870
- const slack = alignWidth - inkWidth;
871
- return align === "center" ? slack / 2 : slack;
872
- }
873
- function placeLine(line, y, order, align, alignWidth, justify) {
874
- const { entries } = line;
875
- const hung = hungWidth(entries);
876
- const inkWidth = line.width - hung;
877
- const slack = alignWidth - inkWidth;
878
- const gaps = justify && line.wrapped && Number.isFinite(alignWidth) && slack > 0 ? wordGaps(entries) : /* @__PURE__ */ new Set();
879
- const gapExtra = gaps.size > 0 ? slack / gaps.size : 0;
880
- const spread = gapExtra * gaps.size;
881
- const inkLeft = spread > 0 ? 0 : alignOffset(align, alignWidth, inkWidth);
882
- const hangsLeft = hung > 0 && order.levels[entries.length - 1] % 2 === 1;
883
- const left = hangsLeft ? inkLeft - hung : inkLeft;
884
- const lineBaselineY = y + line.ascent;
885
- const cells = new Array(entries.length);
886
- const glyphs = [];
887
- let penX = left;
888
- let prevPos = -1;
889
- for (const pos of order.visual) {
890
- const e = entries[pos];
891
- penX += prevPos < 0 ? 0 : pos === prevPos + 1 ? e.kerningBefore : prevPos === pos + 1 ? entries[prevPos].kerningBefore : 0;
892
- prevPos = pos;
893
- const step = e.advance + e.tracking + (gaps.has(pos) ? gapExtra : 0);
894
- cells[pos] = {
895
- srcIndex: e.srcIndex,
896
- srcEnd: e.srcEnd,
897
- cp: e.cp,
898
- x: penX,
899
- advance: step,
900
- level: order.levels[pos],
901
- drawsInk: e.drawsInk,
902
- clusterEnd: e.clusterEnd
903
- };
904
- glyphs.push({
905
- run: e.run,
906
- cell: pos,
907
- cp: e.cp,
908
- fontSize: e.fontSize,
909
- resolved: e.resolved,
910
- metrics: e.metrics,
911
- font: e.font,
912
- glyph: e.glyph,
913
- x: penX,
914
- // Positive raises, and y grows down, so the shift subtracts.
915
- baselineY: lineBaselineY - e.baselineShift,
916
- advance: e.advance,
917
- step
918
- });
919
- penX += step;
920
- }
921
- return {
922
- box: {
923
- x0: left,
924
- y0: y,
925
- x1: left + line.width + spread,
926
- y1: y + line.height,
927
- baselineY: lineBaselineY,
928
- cells,
929
- glyphs,
930
- srcEnd: line.srcEnd,
931
- justified: spread > 0
932
- },
933
- inkWidth: inkWidth + spread
934
- };
935
- }
936
-
937
- // src/layout/layoutOpts.ts
938
- function resolveLayoutOpts(opts) {
939
- return {
940
- maxWidth: opts.maxWidth,
941
- alignWidth: opts.alignWidth ?? opts.maxWidth,
942
- lineHeight: opts.lineHeight,
943
- align: opts.align,
944
- justify: opts.justify === true || opts.align === "justify",
945
- bidi: opts.bidi ?? registeredBidi(),
946
- direction: opts.direction ?? "auto",
947
- tabSize: opts.tabSize ?? DEFAULT_TAB_SIZE
948
- };
949
- }
950
-
951
- // src/layout/layoutRuns.ts
952
- function layoutRuns(runs, opts) {
953
- const o = resolveLayoutOpts(opts);
954
- const entries = measureRuns(runs, o.tabSize);
955
- const cps = entries.map((e) => e.cp);
956
- const { bidi } = o;
957
- const paragraphs = bidi ? analyzeParagraphs(bidi, cps, (i) => isHardLineBreak(cps[i]), o.direction) : null;
958
- if (!bidi) warnRtlWithoutEngine(cps);
959
- const lines = [];
960
- let y = 0;
961
- let width = 0;
962
- for (const line of breakLines(entries, o.maxWidth, o.lineHeight)) {
963
- const order = orderLine(paragraphs, line.start, line.entries.length);
964
- if (bidi) line.entries = mirrorEntries(line.entries, order.levels, (cp) => bidi.mirror(cp), runs);
965
- const reads = o.direction !== "auto" ? o.direction : directionOfLevel(line.entries.length > 0 ? paragraphs?.baseLevel(line.start) ?? 0 : 0);
966
- const placed = placeLine(line, y, order, resolveAlign(o.align, reads), o.alignWidth, o.justify);
967
- lines.push(placed.box);
968
- width = Math.max(width, placed.inkWidth);
969
- y += line.height;
970
- }
971
- return { lines, bounds: { width, height: y } };
972
- }
973
-
974
- // src/layout/refId.ts
975
- var nextRefId = 1;
976
- var refIds = /* @__PURE__ */ new WeakMap();
977
- function refId(o) {
978
- let id = refIds.get(o);
979
- if (id === void 0) {
980
- id = nextRefId++;
981
- refIds.set(o, id);
982
- }
983
- return id;
984
- }
985
-
986
- // src/layout/layoutCache.ts
987
- var LAYOUT_CACHE_VARIANT_LIMIT = 8;
988
- var LAYOUT_CACHE_STRUCTURAL_LIMIT = 64;
989
- var cache = /* @__PURE__ */ new WeakMap();
990
- var structural = /* @__PURE__ */ new Map();
991
- var structuralGeneration = -1;
992
- function variantKey(opts) {
993
- const o = resolveLayoutOpts(opts);
994
- return `${o.maxWidth}|${o.alignWidth}|${o.lineHeight}|${o.align}|${o.justify ? "j" : ""}|${o.direction}|${o.bidi ? refId(o.bidi) : ""}|${o.tabSize}`;
995
- }
996
- function runsKey(runs) {
997
- let out = "";
998
- for (const r of runs) {
999
- out += `${r.text.length}:${r.text}|${r.fontFamily.length}:${r.fontFamily}|${r.fontSize}|${r.fontWeight}|${r.fontStyle}|${r.letterSpacing}|${r.baselineShift}|${r.strutSize ?? ""}|${r.srcMap ? `${r.srcMap.length}:${r.srcMap.starts.join(",")}` : ""}|${r.sizeMap ? r.sizeMap.join(",") : ""}|`;
1000
- }
1001
- return out;
1002
- }
1003
- function cachedLayoutRuns(runs, opts) {
1004
- const fonts = faceGeneration();
1005
- let entry = cache.get(runs);
1006
- if (entry === void 0) {
1007
- entry = { generation: fonts, byVariant: /* @__PURE__ */ new Map() };
1008
- cache.set(runs, entry);
1009
- } else if (entry.generation !== fonts) {
1010
- entry.generation = fonts;
1011
- entry.byVariant.clear();
1012
- }
1013
- const key = variantKey(opts);
1014
- const hit = entry.byVariant.get(key);
1015
- if (hit !== void 0) return hit;
1016
- if (structuralGeneration !== fonts) {
1017
- structural.clear();
1018
- structuralGeneration = fonts;
1019
- }
1020
- const structuralK = `${runsKey(runs)}\0${key}`;
1021
- let laid = structural.get(structuralK);
1022
- if (laid !== void 0) {
1023
- structural.delete(structuralK);
1024
- } else {
1025
- laid = layoutRuns(runs, opts);
1026
- if (structural.size >= LAYOUT_CACHE_STRUCTURAL_LIMIT) {
1027
- structural.delete(structural.keys().next().value);
1028
- }
1029
- }
1030
- structural.set(structuralK, laid);
1031
- if (entry.byVariant.size >= LAYOUT_CACHE_VARIANT_LIMIT) entry.byVariant.clear();
1032
- entry.byVariant.set(key, laid);
1033
- return laid;
1034
- }
1035
- function _resetLayoutCacheForTests() {
1036
- cache = /* @__PURE__ */ new WeakMap();
1037
- structural = /* @__PURE__ */ new Map();
1038
- structuralGeneration = -1;
1039
- }
1040
-
1041
- export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_TAB_SIZE, DEFAULT_TEXT_FILL, DEFAULT_TEXT_STYLE, LAYOUT_CACHE_STRUCTURAL_LIMIT, LAYOUT_CACHE_VARIANT_LIMIT, NO_BREAK, _resetBidiWarningForTests, _resetLayoutCacheForTests, cachedLayoutRuns, fontString, graphemeCount, hangs, isHardLineBreak, layoutRuns, lineBreakOpportunities, paragraphDirection, registerBidi, resolveAlign, resolveTextStyle, tabAdvance, widthWithTabs, wrapLines };
1042
- //# sourceMappingURL=chunk-ADRQIIHS.js.map
1043
- //# sourceMappingURL=chunk-ADRQIIHS.js.map