@flighthq/textlayout 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/index.d.ts +13 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +13 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/richTextContent.d.ts +6 -0
  6. package/dist/richTextContent.d.ts.map +1 -0
  7. package/dist/richTextContent.js +435 -0
  8. package/dist/richTextContent.js.map +1 -0
  9. package/dist/richTextMetrics.d.ts +9 -0
  10. package/dist/richTextMetrics.d.ts.map +1 -0
  11. package/dist/richTextMetrics.js +44 -0
  12. package/dist/richTextMetrics.js.map +1 -0
  13. package/dist/richTextQuery.d.ts +14 -0
  14. package/dist/richTextQuery.d.ts.map +1 -0
  15. package/dist/richTextQuery.js +205 -0
  16. package/dist/richTextQuery.js.map +1 -0
  17. package/dist/textBounds.d.ts +13 -0
  18. package/dist/textBounds.d.ts.map +1 -0
  19. package/dist/textBounds.js +42 -0
  20. package/dist/textBounds.js.map +1 -0
  21. package/dist/textFormat.d.ts +7 -0
  22. package/dist/textFormat.d.ts.map +1 -0
  23. package/dist/textFormat.js +24 -0
  24. package/dist/textFormat.js.map +1 -0
  25. package/dist/textFormatRange.d.ts +3 -0
  26. package/dist/textFormatRange.d.ts.map +1 -0
  27. package/dist/textFormatRange.js +4 -0
  28. package/dist/textFormatRange.js.map +1 -0
  29. package/dist/textLayout.d.ts +8 -0
  30. package/dist/textLayout.d.ts.map +1 -0
  31. package/dist/textLayout.js +632 -0
  32. package/dist/textLayout.js.map +1 -0
  33. package/dist/textLayoutGroup.d.ts +3 -0
  34. package/dist/textLayoutGroup.d.ts.map +1 -0
  35. package/dist/textLayoutGroup.js +17 -0
  36. package/dist/textLayoutGroup.js.map +1 -0
  37. package/dist/textLayoutMeasure.d.ts +4 -0
  38. package/dist/textLayoutMeasure.d.ts.map +1 -0
  39. package/dist/textLayoutMeasure.js +23 -0
  40. package/dist/textLayoutMeasure.js.map +1 -0
  41. package/dist/textLayoutRuntime.d.ts +4 -0
  42. package/dist/textLayoutRuntime.d.ts.map +1 -0
  43. package/dist/textLayoutRuntime.js +11 -0
  44. package/dist/textLayoutRuntime.js.map +1 -0
  45. package/dist/textLineBreaks.d.ts +8 -0
  46. package/dist/textLineBreaks.d.ts.map +1 -0
  47. package/dist/textLineBreaks.js +36 -0
  48. package/dist/textLineBreaks.js.map +1 -0
  49. package/dist/textMetrics.d.ts +4 -0
  50. package/dist/textMetrics.d.ts.map +1 -0
  51. package/dist/textMetrics.js +12 -0
  52. package/dist/textMetrics.js.map +1 -0
  53. package/package.json +38 -0
  54. package/src/richTextContent.test.ts +201 -0
  55. package/src/richTextMetrics.test.ts +124 -0
  56. package/src/richTextQuery.test.ts +196 -0
  57. package/src/textBounds.test.ts +110 -0
  58. package/src/textFormat.test.ts +66 -0
  59. package/src/textFormatRange.test.ts +9 -0
  60. package/src/textLayout.test.ts +661 -0
  61. package/src/textLayoutGroup.test.ts +30 -0
  62. package/src/textLayoutMeasure.test.ts +36 -0
  63. package/src/textLayoutRuntime.test.ts +30 -0
  64. package/src/textLineBreaks.test.ts +73 -0
  65. package/src/textMetrics.test.ts +19 -0
@@ -0,0 +1,205 @@
1
+ import { TEXT_LAYOUT_GUTTER } from './textLayout';
2
+ export function computeRichTextCharIndexAtPoint(layout, x, y) {
3
+ if (layout.groups.length === 0)
4
+ return 0;
5
+ let closestLineIndex = 0;
6
+ let closestDist = Infinity;
7
+ let closestLineBottom = 0;
8
+ for (let i = 0; i < layout.lineHeights.length; i++) {
9
+ const lineTop = getLineOffsetY(layout, i);
10
+ const lineBottom = lineTop + (layout.lineHeights[i] ?? 0);
11
+ const dist = y < lineTop ? lineTop - y : y > lineBottom ? y - lineBottom : 0;
12
+ if (dist < closestDist) {
13
+ closestDist = dist;
14
+ closestLineIndex = i;
15
+ closestLineBottom = lineBottom;
16
+ }
17
+ }
18
+ if (y > closestLineBottom) {
19
+ let lineEnd = 0;
20
+ for (const group of layout.groups) {
21
+ if (group.lineIndex === closestLineIndex)
22
+ lineEnd = Math.max(lineEnd, group.endIndex);
23
+ }
24
+ return lineEnd;
25
+ }
26
+ let lineStart = layout.groups.length > 0 ? (layout.groups[layout.groups.length - 1]?.endIndex ?? 0) : 0;
27
+ let lineEnd = 0;
28
+ for (const group of layout.groups) {
29
+ if (group.lineIndex !== closestLineIndex)
30
+ continue;
31
+ lineStart = Math.min(lineStart, group.startIndex);
32
+ lineEnd = Math.max(lineEnd, group.endIndex);
33
+ if (x <= group.offsetX)
34
+ return group.startIndex;
35
+ if (x <= group.offsetX + group.width) {
36
+ let gx = group.offsetX;
37
+ for (let i = 0; i < group.positions.length; i++) {
38
+ const advance = group.positions[i] ?? 0;
39
+ if (x <= gx + advance / 2)
40
+ return group.startIndex + i;
41
+ gx += advance;
42
+ }
43
+ return group.endIndex;
44
+ }
45
+ }
46
+ return lineEnd > 0 ? lineEnd : lineStart;
47
+ }
48
+ export function computeRichTextLineMetrics(layout, lineIndex) {
49
+ let ascent = 0;
50
+ let descent = 0;
51
+ let leading = 0;
52
+ let x = Infinity;
53
+ let right = 0;
54
+ let found = false;
55
+ for (const group of layout.groups) {
56
+ if (group.lineIndex !== lineIndex)
57
+ continue;
58
+ found = true;
59
+ ascent = Math.max(ascent, group.ascent);
60
+ descent = Math.max(descent, group.descent);
61
+ leading = Math.max(leading, group.leading);
62
+ x = Math.min(x, group.offsetX);
63
+ right = Math.max(right, group.offsetX + group.width);
64
+ }
65
+ if (!found)
66
+ return null;
67
+ return {
68
+ ascent,
69
+ descent,
70
+ height: layout.lineHeights[lineIndex] ?? ascent + descent + leading,
71
+ leading,
72
+ width: right - x,
73
+ x: x === Infinity ? 0 : x,
74
+ };
75
+ }
76
+ export function getRichTextCharBoundaries(out, layout, charIndex) {
77
+ const group = getGroupContainingIndex(layout, charIndex);
78
+ if (group === null)
79
+ return false;
80
+ let x = group.offsetX;
81
+ const limit = Math.min(charIndex - group.startIndex, group.positions.length);
82
+ for (let i = 0; i < limit; i++)
83
+ x += group.positions[i] ?? 0;
84
+ const charWidth = group.positions[charIndex - group.startIndex] ?? 0;
85
+ out.x = x;
86
+ out.y = group.offsetY;
87
+ out.width = charWidth;
88
+ out.height = group.height;
89
+ return true;
90
+ }
91
+ export function getRichTextFirstCharInParagraph(text, charIndex) {
92
+ const clamped = Math.max(0, Math.min(text.length, charIndex));
93
+ for (let i = clamped - 1; i >= 0; i--) {
94
+ if (text[i] === '\n')
95
+ return i + 1;
96
+ }
97
+ return 0;
98
+ }
99
+ export function getRichTextLineIndexAtPoint(layout, y) {
100
+ let closestLineIndex = 0;
101
+ let closestDist = Infinity;
102
+ for (let i = 0; i < layout.lineHeights.length; i++) {
103
+ const lineTop = getLineOffsetY(layout, i);
104
+ const lineBottom = lineTop + layout.lineHeights[i];
105
+ const dist = y < lineTop ? lineTop - y : y > lineBottom ? y - lineBottom : 0;
106
+ if (dist < closestDist) {
107
+ closestDist = dist;
108
+ closestLineIndex = i;
109
+ }
110
+ }
111
+ return closestLineIndex;
112
+ }
113
+ export function getRichTextLineIndexOfChar(layout, charIndex) {
114
+ const group = getGroupContainingIndex(layout, charIndex);
115
+ return group?.lineIndex ?? 0;
116
+ }
117
+ export function getRichTextLineLength(layout, lineIndex) {
118
+ let start = Infinity;
119
+ let end = 0;
120
+ for (const group of layout.groups) {
121
+ if (group.lineIndex !== lineIndex)
122
+ continue;
123
+ start = Math.min(start, group.startIndex);
124
+ end = Math.max(end, group.endIndex);
125
+ }
126
+ return start === Infinity ? 0 : end - start;
127
+ }
128
+ export function getRichTextLineOffset(layout, lineIndex) {
129
+ for (const group of layout.groups) {
130
+ if (group.lineIndex === lineIndex)
131
+ return group.startIndex;
132
+ }
133
+ return 0;
134
+ }
135
+ export function getRichTextLineText(text, layout, lineIndex) {
136
+ let start = Infinity;
137
+ let end = 0;
138
+ for (const group of layout.groups) {
139
+ if (group.lineIndex !== lineIndex)
140
+ continue;
141
+ start = Math.min(start, group.startIndex);
142
+ end = Math.max(end, group.endIndex);
143
+ }
144
+ return start === Infinity ? '' : text.slice(start, end);
145
+ }
146
+ export function getRichTextLinkAtPoint(layout, x, y) {
147
+ for (const group of layout.groups) {
148
+ if (!group.format.url)
149
+ continue;
150
+ if (x >= group.offsetX &&
151
+ x <= group.offsetX + group.width &&
152
+ y >= group.offsetY &&
153
+ y <= group.offsetY + group.height) {
154
+ return group.format.url;
155
+ }
156
+ }
157
+ return null;
158
+ }
159
+ export function getRichTextParagraphLength(text, charIndex) {
160
+ const start = getRichTextFirstCharInParagraph(text, charIndex);
161
+ const newline = text.indexOf('\n', start);
162
+ const end = newline === -1 ? text.length : newline + 1;
163
+ return end - start;
164
+ }
165
+ export function getRichTextSelectionRectangles(out, beginIndex, endIndex, layout) {
166
+ out.length = 0;
167
+ if (beginIndex === endIndex)
168
+ return;
169
+ const start = Math.min(beginIndex, endIndex);
170
+ const end = Math.max(beginIndex, endIndex);
171
+ for (const group of layout.groups) {
172
+ const groupStart = Math.max(start, group.startIndex);
173
+ const groupEnd = Math.min(end, group.endIndex);
174
+ if (groupStart >= groupEnd)
175
+ continue;
176
+ const x = getCaretX(group, groupStart);
177
+ const right = getCaretX(group, groupEnd);
178
+ out.push({ height: group.height, lineIndex: group.lineIndex, width: right - x, x, y: group.offsetY });
179
+ }
180
+ }
181
+ function getCaretX(group, index) {
182
+ let x = group.offsetX;
183
+ const limit = Math.max(0, Math.min(index, group.endIndex) - group.startIndex);
184
+ for (let i = 0; i < limit; i++)
185
+ x += group.positions[i] ?? 0;
186
+ return x;
187
+ }
188
+ function getGroupContainingIndex(layout, charIndex) {
189
+ for (const group of layout.groups) {
190
+ if (charIndex >= group.startIndex && charIndex < group.endIndex)
191
+ return group;
192
+ }
193
+ return null;
194
+ }
195
+ function getLineOffsetY(layout, lineIndex) {
196
+ for (const group of layout.groups) {
197
+ if (group.lineIndex === lineIndex)
198
+ return group.offsetY;
199
+ }
200
+ let y = TEXT_LAYOUT_GUTTER;
201
+ for (let i = 0; i < lineIndex; i++)
202
+ y += layout.lineHeights[i] ?? 0;
203
+ return y;
204
+ }
205
+ //# sourceMappingURL=richTextQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"richTextQuery.js","sourceRoot":"","sources":["../src/richTextQuery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { RectangleLike, TextAutoSize, TextLayoutResult } from '@flighthq/types';
2
+ export type TextBoundsSpec = Readonly<{
3
+ autoSize: TextAutoSize;
4
+ height: number;
5
+ width: number;
6
+ wordWrap?: boolean;
7
+ }>;
8
+ export declare const TEXT_BOUNDS_GUTTER = 2;
9
+ export declare function computeTextBoundsHeight(spec: TextBoundsSpec, layout: Readonly<TextLayoutResult>): number;
10
+ export declare function computeTextBoundsOffsetX(spec: TextBoundsSpec, layout: Readonly<TextLayoutResult>): number;
11
+ export declare function computeTextBoundsRectangle(out: RectangleLike, spec: TextBoundsSpec, layout: Readonly<TextLayoutResult>): void;
12
+ export declare function computeTextBoundsWidth(spec: TextBoundsSpec, layout: Readonly<TextLayoutResult>): number;
13
+ //# sourceMappingURL=textBounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textBounds.d.ts","sourceRoot":"","sources":["../src/textBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQrF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAKrH,eAAO,MAAM,kBAAkB,IAAqB,CAAC;AAIrD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAGxG;AAID,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAKzG;AAMD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACjC,IAAI,CAON;AAID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAGvG"}
@@ -0,0 +1,42 @@
1
+ import { TEXT_LAYOUT_GUTTER } from './textLayout';
2
+ // Inner padding (px) between the box edge and its text, applied on every side. Exported for the scroll
3
+ // metrics in richTextMetrics, which subtract it to derive the visible content area.
4
+ // Alias of TEXT_LAYOUT_GUTTER so both names refer to the same shared value without duplication risk.
5
+ export const TEXT_BOUNDS_GUTTER = TEXT_LAYOUT_GUTTER;
6
+ // The box height: the declared height when autoSize is off, else the measured content height plus a
7
+ // gutter on the top and bottom.
8
+ export function computeTextBoundsHeight(spec, layout) {
9
+ if (spec.autoSize === 'none')
10
+ return spec.height;
11
+ return Math.ceil(layout.textHeight + TEXT_LAYOUT_GUTTER * 2);
12
+ }
13
+ // The horizontal anchor offset of the box within the declared width: 0 for left/none, the full slack
14
+ // for right, half for center. Renderers that position the field use this directly.
15
+ export function computeTextBoundsOffsetX(spec, layout) {
16
+ const slack = spec.width - computeTextBoundsWidth(spec, layout);
17
+ if (spec.autoSize === 'right')
18
+ return slack;
19
+ if (spec.autoSize === 'center')
20
+ return slack / 2;
21
+ return 0;
22
+ }
23
+ // Fills `out` with the local-bounds rectangle a text object occupies: x = the left/right/center anchor
24
+ // offset, y = 0, width/height = the box. This is the per-frame calculation behind the text kinds'
25
+ // computeLocalBoundsRectangle hooks; callers that want the cached node bounds go through
26
+ // getNodeLocalBoundsRectangle instead. `out` may not alias `spec` (spec is read after out.x is written).
27
+ export function computeTextBoundsRectangle(out, spec, layout) {
28
+ const width = computeTextBoundsWidth(spec, layout);
29
+ const slack = spec.width - width;
30
+ out.x = spec.autoSize === 'right' ? slack : spec.autoSize === 'center' ? slack / 2 : 0;
31
+ out.y = 0;
32
+ out.width = width;
33
+ out.height = computeTextBoundsHeight(spec, layout);
34
+ }
35
+ // The box width: the declared width when autoSize is off or wordWrap constrains it, else the measured
36
+ // content width plus a gutter on the left and right.
37
+ export function computeTextBoundsWidth(spec, layout) {
38
+ if (spec.autoSize === 'none' || spec.wordWrap)
39
+ return spec.width;
40
+ return Math.ceil(layout.textWidth + TEXT_LAYOUT_GUTTER * 2);
41
+ }
42
+ //# sourceMappingURL=textBounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textBounds.js","sourceRoot":"","sources":["../src/textBounds.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAQlD,uGAAuG;AACvG,oFAAoF;AACpF,qGAAqG;AACrG,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAErD,oGAAoG;AACpG,gCAAgC;AAChC,MAAM,UAAU,uBAAuB,CAAC,IAAoB,EAAE,MAAkC;IAC9F,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,kBAAkB,GAAG,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,mFAAmF;AACnF,MAAM,UAAU,wBAAwB,CAAC,IAAoB,EAAE,MAAkC;IAC/F,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChE,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,uGAAuG;AACvG,kGAAkG;AAClG,yFAAyF;AACzF,yGAAyG;AACzG,MAAM,UAAU,0BAA0B,CACxC,GAAkB,EAClB,IAAoB,EACpB,MAAkC;IAElC,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACjC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IAClB,GAAG,CAAC,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,sGAAsG;AACtG,qDAAqD;AACrD,MAAM,UAAU,sBAAsB,CAAC,IAAoB,EAAE,MAAkC;IAC7F,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IACjE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,kBAAkB,GAAG,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TextFormat } from '@flighthq/types';
2
+ export declare function getTextFormatAscent(format: TextFormat): number;
3
+ export declare function getTextFormatDescent(format: TextFormat): number;
4
+ export declare function getTextFormatHeight(format: TextFormat): number;
5
+ export declare function getTextFormatLeading(format: TextFormat): number;
6
+ export declare function mergeTextFormat(base: TextFormat, override: TextFormat): TextFormat;
7
+ //# sourceMappingURL=textFormat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textFormat.d.ts","sourceRoot":"","sources":["../src/textFormat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE/D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,UAAU,CASlF"}
@@ -0,0 +1,24 @@
1
+ const DEFAULT_SIZE = 12;
2
+ export function getTextFormatAscent(format) {
3
+ return format.size ?? DEFAULT_SIZE;
4
+ }
5
+ export function getTextFormatDescent(format) {
6
+ return (format.size ?? DEFAULT_SIZE) * 0.185;
7
+ }
8
+ export function getTextFormatHeight(format) {
9
+ return getTextFormatAscent(format) + getTextFormatDescent(format) + getTextFormatLeading(format);
10
+ }
11
+ export function getTextFormatLeading(format) {
12
+ return format.leading ?? 0;
13
+ }
14
+ export function mergeTextFormat(base, override) {
15
+ const result = { ...base };
16
+ for (const key of Object.keys(override)) {
17
+ const value = override[key];
18
+ if (value != null) {
19
+ result[key] = value;
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ //# sourceMappingURL=textFormat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textFormat.js","sourceRoot":"","sources":["../src/textFormat.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,OAAO,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC,GAAG,KAAK,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,OAAO,mBAAmB,CAAC,MAAM,CAAC,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,OAAO,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAgB,EAAE,QAAoB;IACpE,MAAM,MAAM,GAAe,EAAE,GAAG,IAAI,EAAE,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAyB,EAAE,CAAC;QAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YACjB,MAAkC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACnD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TextFormat, TextFormatRange } from '@flighthq/types';
2
+ export declare function createTextFormatRange(format: TextFormat, start: number, end: number): TextFormatRange;
3
+ //# sourceMappingURL=textFormatRange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textFormatRange.d.ts","sourceRoot":"","sources":["../src/textFormatRange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CAErG"}
@@ -0,0 +1,4 @@
1
+ export function createTextFormatRange(format, start, end) {
2
+ return { end, format, start };
3
+ }
4
+ //# sourceMappingURL=textFormatRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textFormatRange.js","sourceRoot":"","sources":["../src/textFormatRange.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,MAAkB,EAAE,KAAa,EAAE,GAAW;IAClF,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { TextLayoutParams, TextLayoutResult } from '@flighthq/types';
2
+ export type { TextLayoutParams, TextLayoutResult, TextMeasureFunction } from '@flighthq/types';
3
+ /** Inner padding (px) between a text box edge and its content, applied on every side. */
4
+ export declare const TEXT_LAYOUT_GUTTER = 2;
5
+ export declare function computeTextLayout(out: TextLayoutResult, params: TextLayoutParams): void;
6
+ export declare function createTextLayoutResult(): TextLayoutResult;
7
+ export declare function getTextLayoutIsTruncated(layout: Readonly<TextLayoutResult>, params: Readonly<TextLayoutParams>): boolean;
8
+ //# sourceMappingURL=textLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textLayout.d.ts","sourceRoot":"","sources":["../src/textLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,gBAAgB,EAChB,gBAAgB,EAEjB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAM/F,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAQpC,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAqDvF;AAwpBD,wBAAgB,sBAAsB,IAAI,gBAAgB,CAYzD;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACjC,OAAO,CAGT"}