@weasel-js/text 1.6.1 → 1.7.1
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/dist/chunk-JQPOFIGT.js +1207 -0
- package/dist/chunk-JQPOFIGT.js.map +1 -0
- package/dist/index.d.ts +61 -17
- package/dist/index.js +185 -110
- package/dist/index.js.map +1 -1
- package/dist/{test-seams-CeRWeyMm.d.ts → test-seams-DbGu8K5F.d.ts} +208 -49
- package/dist/test-seams.d.ts +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-GNAAPRO5.js +0 -762
- package/dist/chunk-GNAAPRO5.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ScreenLength, FillStyle, Stroke } from '@weasel-js/paint';
|
|
2
|
-
import { FontStyle } from '@weasel-js/font';
|
|
2
|
+
import { FaceMetrics, FontStyle, FaceRuleMetrics } from '@weasel-js/font';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* CSS `text-transform` over styled runs: `uppercase`, `lowercase` and
|
|
@@ -44,6 +44,49 @@ interface TransformedRunText {
|
|
|
44
44
|
*/
|
|
45
45
|
declare function transformRunTexts(texts: readonly string[], transforms: readonly TextTransform[]): TransformedRunText[];
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Synthetic small caps: lowercase drawn as capitals at a smaller size, the
|
|
49
|
+
* way a browser synthesizes `font-variant: small-caps` for a face with no
|
|
50
|
+
* `smcp` feature. It is the one run style that sizes characters within a run
|
|
51
|
+
* differently, so it reports a per-unit size map beside the text.
|
|
52
|
+
*
|
|
53
|
+
* It reads the text *after* `textTransform`, as CSS does: `uppercase` leaves
|
|
54
|
+
* nothing to shrink, and `lowercase` shrinks everything.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/** The CSS `font-variant-caps` keywords the run model carries. `normal` is an
|
|
58
|
+
* explicit override: a run can turn off small caps it would inherit. */
|
|
59
|
+
type FontVariantCaps = 'normal' | 'small-caps';
|
|
60
|
+
/**
|
|
61
|
+
* The small-caps size, as a fraction of the run's, for a face that states no
|
|
62
|
+
* x-height and cap height. 0.7 is the factor Chromium and WebKit synthesize
|
|
63
|
+
* with.
|
|
64
|
+
*/
|
|
65
|
+
declare const SMALL_CAPS_SCALE = 0.7;
|
|
66
|
+
/** The small-caps size for a face: its x-height over its cap height, so a
|
|
67
|
+
* small capital stands as tall as its lowercase letters do, or
|
|
68
|
+
* {@link SMALL_CAPS_SCALE} where the face lacks either. */
|
|
69
|
+
declare function smallCapsScale(face?: FaceMetrics): number;
|
|
70
|
+
/** The small-caps scale a run set in `(family, weight, style)` gets —
|
|
71
|
+
* resolved through the font registry exactly as layout resolves the run. */
|
|
72
|
+
declare function smallCapsScaleFor(family: string, weight: number, style: FontStyle): number;
|
|
73
|
+
/** Whether small caps draws `ch` as a smaller capital: whether it has a
|
|
74
|
+
* capital other than itself. */
|
|
75
|
+
declare function isSmallCapsLetter(ch: string): boolean;
|
|
76
|
+
/** A run's drawn text under small caps. `small[i]` says whether UTF-16 unit
|
|
77
|
+
* `i` of `text` draws at the small size; absent when none does. */
|
|
78
|
+
interface SmallCapsText {
|
|
79
|
+
text: string;
|
|
80
|
+
srcMap?: RunSourceMap;
|
|
81
|
+
small?: readonly boolean[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Apply small caps to a run's drawn text. `srcMap` is the map `textTransform`
|
|
85
|
+
* already produced for it, if any; the result's map composes the two, so
|
|
86
|
+
* each drawn unit still names the source character it came from.
|
|
87
|
+
*/
|
|
88
|
+
declare function smallCapsText(text: string, srcMap?: RunSourceMap): SmallCapsText;
|
|
89
|
+
|
|
47
90
|
/**
|
|
48
91
|
* Canonical inline-styling primitive for text nodes. A node's text is
|
|
49
92
|
* either a plain `string` (treated as a single-run, default-styled fragment)
|
|
@@ -51,8 +94,8 @@ declare function transformRunTexts(texts: readonly string[], transforms: readonl
|
|
|
51
94
|
* either form into the array shape used by the renderer.
|
|
52
95
|
*
|
|
53
96
|
* Every field except `text` is optional; missing fields fall back to the
|
|
54
|
-
* node-level `TextStyle`. `bold`/`italic` are toggles;
|
|
55
|
-
*
|
|
97
|
+
* node-level `TextStyle`. `bold`/`italic` are toggles; `fontWeight` is the
|
|
98
|
+
* numeric weight `bold` is a preset over.
|
|
56
99
|
*/
|
|
57
100
|
|
|
58
101
|
/** A span of text with its own styling, as authored. Fields left absent
|
|
@@ -60,7 +103,11 @@ declare function transformRunTexts(texts: readonly string[], transforms: readonl
|
|
|
60
103
|
* and a fully resolved one. */
|
|
61
104
|
interface StyledRun {
|
|
62
105
|
text: string;
|
|
106
|
+
/** Draw at weight 700. A preset over `fontWeight`, which wins when both
|
|
107
|
+
* are present. */
|
|
63
108
|
bold?: boolean;
|
|
109
|
+
/** Numeric weight, 100–900. Overrides the node's weight and `bold`. */
|
|
110
|
+
fontWeight?: number;
|
|
64
111
|
italic?: boolean;
|
|
65
112
|
fontFamily?: string;
|
|
66
113
|
/** World units, or `{ px }` for screen pixels — resolved against the view
|
|
@@ -82,8 +129,9 @@ interface StyledRun {
|
|
|
82
129
|
*
|
|
83
130
|
* A preset over the two primitives below, not a third mechanism: it supplies
|
|
84
131
|
* a `baselineShift` and a `fontScale`, and naming either of those directly
|
|
85
|
-
* overrides that half while leaving the other alone. The numbers are
|
|
86
|
-
* {@link SCRIPT_METRICS}
|
|
132
|
+
* overrides that half while leaving the other alone. The numbers are the
|
|
133
|
+
* face's own `OS/2` script metrics, or {@link SCRIPT_METRICS} for a face
|
|
134
|
+
* that states none — `scriptMetricsFor` answers which.
|
|
87
135
|
*/
|
|
88
136
|
script?: 'super' | 'sub';
|
|
89
137
|
/**
|
|
@@ -105,6 +153,13 @@ interface StyledRun {
|
|
|
105
153
|
* off.
|
|
106
154
|
*/
|
|
107
155
|
textTransform?: TextTransform;
|
|
156
|
+
/**
|
|
157
|
+
* `'small-caps'` draws this run's lowercase letters as capitals at a
|
|
158
|
+
* smaller size — synthesized, at the face's x-height over its cap height.
|
|
159
|
+
* Like `textTransform`, only what is drawn changes. Overrides the node's
|
|
160
|
+
* own; `'normal'` turns an inherited one off.
|
|
161
|
+
*/
|
|
162
|
+
fontVariantCaps?: FontVariantCaps;
|
|
108
163
|
}
|
|
109
164
|
/** Normalize the two accepted spellings of text content — a plain string or
|
|
110
165
|
* an array of runs — to runs. Throws on a run with no string `text`. */
|
|
@@ -172,17 +227,20 @@ declare function markdownToRuns(input: string, grammar?: RunGrammar): StyledRun[
|
|
|
172
227
|
|
|
173
228
|
/**
|
|
174
229
|
* Horizontal alignment. `start` / `end` resolve against the reading direction;
|
|
175
|
-
* `left` / `right` are absolute.
|
|
176
|
-
* the
|
|
230
|
+
* `left` / `right` are absolute. `justify` spreads every wrapped line across
|
|
231
|
+
* the box by widening its word gaps, and sets a paragraph's last line at the
|
|
232
|
+
* start edge. The same values as CSS `text-align`, with the same meanings.
|
|
177
233
|
*/
|
|
178
|
-
type TextAlign = 'left' | 'center' | 'right' | 'start' | 'end';
|
|
234
|
+
type TextAlign = 'left' | 'center' | 'right' | 'start' | 'end' | 'justify';
|
|
179
235
|
/** Reading direction, which is what gives `start` / `end` their meaning. */
|
|
180
236
|
type TextDirection = 'ltr' | 'rtl';
|
|
181
237
|
/**
|
|
182
238
|
* Collapse a possibly reading-order-relative alignment to an absolute edge.
|
|
183
239
|
*
|
|
184
240
|
* Layout works in absolute edges, so this runs once at its entry and `start` /
|
|
185
|
-
* `end` never reach the geometry.
|
|
241
|
+
* `end` never reach the geometry. `justify` collapses to the start edge, which
|
|
242
|
+
* is where it sets every line it does not spread; whether to spread is carried
|
|
243
|
+
* separately, as `LayoutRunsOpts.justify`.
|
|
186
244
|
*/
|
|
187
245
|
declare function resolveAlign(align: TextAlign, direction: TextDirection): 'left' | 'center' | 'right';
|
|
188
246
|
/** User-facing text style. All fields optional; defaults applied at render time via `resolveTextStyle`. */
|
|
@@ -206,7 +264,9 @@ interface TextStyle {
|
|
|
206
264
|
/** Multiplier applied to `fontSize`. Default 1.2. */
|
|
207
265
|
lineHeight?: number;
|
|
208
266
|
/**
|
|
209
|
-
* Break lines
|
|
267
|
+
* Break lines where they would pass the box width, at the break
|
|
268
|
+
* opportunities of Unicode's line breaking algorithm (UAX #14) — between
|
|
269
|
+
* words, after a hyphen, between CJK characters. Default
|
|
210
270
|
* `false`: a line runs as long as its text, and the box width only resolves
|
|
211
271
|
* `align`. A word longer than the box is never broken.
|
|
212
272
|
*/
|
|
@@ -236,6 +296,16 @@ interface TextStyle {
|
|
|
236
296
|
/** CSS `text-transform` for display; the text itself is not rewritten.
|
|
237
297
|
* Default `'none'`. */
|
|
238
298
|
textTransform?: TextTransform;
|
|
299
|
+
/** `'small-caps'` draws lowercase as smaller capitals; the text itself is
|
|
300
|
+
* not rewritten. Default `'normal'`. */
|
|
301
|
+
fontVariantCaps?: FontVariantCaps;
|
|
302
|
+
/**
|
|
303
|
+
* Set the node's text as a superscript or subscript — the default every run
|
|
304
|
+
* inherits, exactly as a run's own `StyledRun.script` is for that run. The
|
|
305
|
+
* lines keep the height and baseline the unscripted text would have had.
|
|
306
|
+
* Absent is ordinary text.
|
|
307
|
+
*/
|
|
308
|
+
script?: 'super' | 'sub';
|
|
239
309
|
}
|
|
240
310
|
/** `TextStyle` with all fields filled in from defaults — what the renderer actually consumes. */
|
|
241
311
|
interface ResolvedTextStyle {
|
|
@@ -259,6 +329,9 @@ interface ResolvedTextStyle {
|
|
|
259
329
|
strikethrough: boolean;
|
|
260
330
|
overline: boolean;
|
|
261
331
|
textTransform: TextTransform;
|
|
332
|
+
fontVariantCaps: FontVariantCaps;
|
|
333
|
+
/** Absent is ordinary text. */
|
|
334
|
+
script?: 'super' | 'sub';
|
|
262
335
|
/** Absent means no outline — unlike the other fields, this one has no
|
|
263
336
|
* default to fall back to. See {@link TextPaint.stroke}. */
|
|
264
337
|
stroke?: Stroke;
|
|
@@ -310,7 +383,9 @@ declare function fontString(s: ResolvedTextStyle): string;
|
|
|
310
383
|
* canonical shape the renderer consumes.
|
|
311
384
|
*
|
|
312
385
|
* `bold`/`italic` toggles on a run are folded into `fontWeight`/`fontStyle`:
|
|
313
|
-
* `bold: true` → fontWeight 700, `italic: true` → fontStyle 'italic'.
|
|
386
|
+
* `bold: true` → fontWeight 700, `italic: true` → fontStyle 'italic'. A run's
|
|
387
|
+
* own numeric `fontWeight` is the primitive `bold` is a preset over, so it
|
|
388
|
+
* wins over both the flag and the node weight.
|
|
314
389
|
* Explicit `fontFamily` / `fontSize` / `fill` / `letterSpacing` on the run
|
|
315
390
|
* override the node-level value (`letterSpacing: 0` on a run is an override,
|
|
316
391
|
* not an absence — it zeroes inherited tracking).
|
|
@@ -328,6 +403,10 @@ declare function fontString(s: ResolvedTextStyle): string;
|
|
|
328
403
|
* `textTransform` is applied here too, so `text` is what gets drawn. When a
|
|
329
404
|
* transform changes a length, `srcMap` says which source characters each
|
|
330
405
|
* drawn one came from; see `textTransform.ts`.
|
|
406
|
+
*
|
|
407
|
+
* `fontVariantCaps: 'small-caps'` is applied after it, over the transformed
|
|
408
|
+
* text: lowercase becomes capitals, and `sizeMap` gives those their smaller
|
|
409
|
+
* size. See `smallCaps.ts`.
|
|
331
410
|
*/
|
|
332
411
|
|
|
333
412
|
/** A run with every style resolved against the node's text style — no
|
|
@@ -341,7 +420,12 @@ interface ResolvedRun {
|
|
|
341
420
|
* means `text`'s offsets are the source's. */
|
|
342
421
|
srcMap?: RunSourceMap;
|
|
343
422
|
fontFamily: string;
|
|
423
|
+
/** The run's size — what its line and its rules are set at, and what
|
|
424
|
+
* every glyph is drawn at unless `sizeMap` says otherwise. */
|
|
344
425
|
fontSize: number;
|
|
426
|
+
/** Present when not every glyph is drawn at `fontSize`: the size each
|
|
427
|
+
* UTF-16 unit of `text` is drawn at. Small caps is what produces one. */
|
|
428
|
+
sizeMap?: readonly number[];
|
|
345
429
|
fontWeight: number;
|
|
346
430
|
fontStyle: 'normal' | 'italic';
|
|
347
431
|
/** `null` is an explicit no-fill: the glyphs are painted by `stroke` alone,
|
|
@@ -368,35 +452,83 @@ interface ResolvedRun {
|
|
|
368
452
|
* asks nothing about where it came from.
|
|
369
453
|
*/
|
|
370
454
|
baselineShift: number;
|
|
455
|
+
/**
|
|
456
|
+
* The size this run holds its line open at, when a relative size shrank it
|
|
457
|
+
* below the size it inherited — so a superscript alone on its line keeps the
|
|
458
|
+
* line's height and baseline instead of collapsing them. Absent means
|
|
459
|
+
* `fontSize`.
|
|
460
|
+
*/
|
|
461
|
+
strutSize?: number;
|
|
371
462
|
}
|
|
463
|
+
/** What one script preset expands to. */
|
|
464
|
+
type ScriptPreset = Readonly<{
|
|
465
|
+
size: number;
|
|
466
|
+
shift: number;
|
|
467
|
+
}>;
|
|
372
468
|
/**
|
|
373
|
-
* What `script: 'super'` and `script: 'sub'` expand to
|
|
374
|
-
*
|
|
375
|
-
* (negative) the
|
|
469
|
+
* What `script: 'super'` and `script: 'sub'` expand to for a face that states
|
|
470
|
+
* no script metrics of its own, as fractions of the inherited font size:
|
|
471
|
+
* `size` scales it, `shift` raises (positive) or lowers (negative) the
|
|
472
|
+
* baseline.
|
|
376
473
|
*
|
|
377
474
|
* These are Adobe's defaults — InDesign and Illustrator ship 58.3% size and
|
|
378
|
-
* 33.3% position for both
|
|
379
|
-
*
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
*
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
*
|
|
387
|
-
*
|
|
475
|
+
* 33.3% position for both. A face that carries `OS/2` script metrics uses
|
|
476
|
+
* those instead; {@link scriptMetricsFor} is what a run actually gets.
|
|
477
|
+
*/
|
|
478
|
+
declare const SCRIPT_METRICS: Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
479
|
+
/** The script presets for a face: its own `OS/2` values where it states
|
|
480
|
+
* them, {@link SCRIPT_METRICS} per half where it does not. */
|
|
481
|
+
declare function scriptMetrics(face?: FaceMetrics): Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
482
|
+
/**
|
|
483
|
+
* The script presets a run set in `(family, weight, style)` gets — resolved
|
|
484
|
+
* through the font registry exactly as layout resolves the run, so a
|
|
485
|
+
* character panel, an SVG export and the DOM edit overlay read the numbers
|
|
486
|
+
* the canvas draws with. Override either half per run with `baselineShift` /
|
|
388
487
|
* `fontScale`.
|
|
389
488
|
*/
|
|
390
|
-
declare
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
489
|
+
declare function scriptMetricsFor(family: string, weight: number, style: FontStyle): Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
490
|
+
/** A `TextStyle.fontWeight` as a number: the CSS keywords `bold` and
|
|
491
|
+
* `normal` read as 700 and 400, anything unparseable as 400. */
|
|
492
|
+
declare function numericWeight(w: number | string): number;
|
|
493
|
+
/** Whether a weight reads as bold — 600 and up, the same line the font
|
|
494
|
+
* registry draws between its regular and bold buckets. */
|
|
495
|
+
declare function isBoldWeight(w: number | string): boolean;
|
|
496
|
+
/** The face a run is set in — its family, weight and style, each falling
|
|
497
|
+
* back to the node's. Reads no font registry, so asking loads nothing. */
|
|
498
|
+
declare function resolveRunFace(run: StyledRun, style: Pick<ResolvedTextStyle, 'fontFamily' | 'fontWeight' | 'fontStyle'>): {
|
|
499
|
+
fontFamily: string;
|
|
500
|
+
fontWeight: number;
|
|
501
|
+
fontStyle: FontStyle;
|
|
502
|
+
};
|
|
394
503
|
/** Resolve each run's styling against the node's text style, filling in
|
|
395
504
|
* everything the run left inherited. `viewScale` resolves a run's own
|
|
396
505
|
* `{ px }` size or spacing; the inherited ones arrived already resolved on
|
|
397
506
|
* `style`. */
|
|
398
507
|
declare function resolveRuns(runs: readonly StyledRun[], style: ResolvedTextStyle, viewScale?: number): ResolvedRun[];
|
|
399
508
|
|
|
509
|
+
/** The three text decoration rules, in the order every tier paints them. */
|
|
510
|
+
type DecorationKind = 'underline' | 'strikethrough' | 'overline';
|
|
511
|
+
/**
|
|
512
|
+
* Decoration placement and weight for a face that states none, as fractions
|
|
513
|
+
* of the run's `fontSize`. Offsets are the *top* edge of the rule, measured
|
|
514
|
+
* down from the baseline — so the two rules that sit above it are negative.
|
|
515
|
+
*
|
|
516
|
+
* Derived, not measured: they apply to an atlas baked before `gen-font`
|
|
517
|
+
* recorded `faceMetrics`, a custom outline parser that reports none, and the
|
|
518
|
+
* canvas tier, which has no font tables to read.
|
|
519
|
+
*/
|
|
520
|
+
declare const DEFAULT_DECORATION_METRICS: Readonly<Record<DecorationKind, FaceRuleMetrics>>;
|
|
521
|
+
/**
|
|
522
|
+
* Where each rule sits for a face, in ems: the face's own underline and
|
|
523
|
+
* strikeout where it states them, the defaults where it does not. No font
|
|
524
|
+
* table places an overline, so it keeps the default offset and takes the
|
|
525
|
+
* underline's weight, as browsers draw it.
|
|
526
|
+
*
|
|
527
|
+
* Every text tier places its rules through this, so one face puts a rule in
|
|
528
|
+
* the same place whichever tier paints it.
|
|
529
|
+
*/
|
|
530
|
+
declare function decorationMetrics(face?: FaceMetrics): Readonly<Record<DecorationKind, FaceRuleMetrics>>;
|
|
531
|
+
|
|
400
532
|
/**
|
|
401
533
|
* The bidi contract, declared here and implemented elsewhere.
|
|
402
534
|
*
|
|
@@ -411,6 +543,7 @@ declare function resolveRuns(runs: readonly StyledRun[], style: ResolvedTextStyl
|
|
|
411
543
|
*/
|
|
412
544
|
/** Opaque to this package — whatever the engine needs to carry between calls. */
|
|
413
545
|
type BidiAnalysis = unknown;
|
|
546
|
+
/** One line's visual order, as {@link BidiResolver.reorder} returns it. */
|
|
414
547
|
interface BidiReordering {
|
|
415
548
|
/**
|
|
416
549
|
* Positions in the analysed sequence, in visual order, left to right.
|
|
@@ -420,6 +553,11 @@ interface BidiReordering {
|
|
|
420
553
|
/** Resolved embedding level per position in the line's range. */
|
|
421
554
|
levels: ArrayLike<number>;
|
|
422
555
|
}
|
|
556
|
+
/**
|
|
557
|
+
* A bidi engine, passed to `layoutRuns` as `opts.bidi`. `@weasel-js/bidi`'s
|
|
558
|
+
* `bidi` object satisfies it. `reorder`'s `start` / `end` index the code points
|
|
559
|
+
* `analyze` was given.
|
|
560
|
+
*/
|
|
423
561
|
interface BidiResolver {
|
|
424
562
|
analyze(codePoints: readonly number[], direction?: 'ltr' | 'rtl' | 'auto'): BidiAnalysis;
|
|
425
563
|
reorder(analysis: BidiAnalysis, start: number, end: number): BidiReordering;
|
|
@@ -427,9 +565,6 @@ interface BidiResolver {
|
|
|
427
565
|
mirror(cp: number): number | null;
|
|
428
566
|
}
|
|
429
567
|
|
|
430
|
-
/** The three text decoration rules, in the order every tier paints them. */
|
|
431
|
-
type DecorationKind = 'underline' | 'strikethrough' | 'overline';
|
|
432
|
-
|
|
433
568
|
/**
|
|
434
569
|
* Runs-aware MSDF layout. Walks `ResolvedRun[]` codepoint-by-codepoint,
|
|
435
570
|
* switching atlas per run via `resolveFontVariant`, applying kerning
|
|
@@ -439,21 +574,28 @@ type DecorationKind = 'underline' | 'strikethrough' | 'overline';
|
|
|
439
574
|
* so the renderer issues one draw call per atlas+color group.
|
|
440
575
|
*
|
|
441
576
|
* A run's `letterSpacing` (world units, so it does not scale with `fontSize`)
|
|
442
|
-
* is added to the advance *after* every
|
|
443
|
-
* last one on a line — the CSS `letter-spacing` rule, chosen so
|
|
444
|
-
* rendering the same text can be made to agree.
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* Word wrap is applied when `maxWidth` is finite: words
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
577
|
+
* is added to the advance *after* every grapheme cluster of that run,
|
|
578
|
+
* including the last one on a line — the CSS `letter-spacing` rule, chosen so
|
|
579
|
+
* a DOM overlay rendering the same text can be made to agree. The last code
|
|
580
|
+
* point of a cluster carries it, so a combining mark hangs off its base
|
|
581
|
+
* before the gap opens. Clusters are segmented per run. Trailing tracking
|
|
582
|
+
* therefore widens the measured line width and counts toward wrapping. Spaces
|
|
583
|
+
* are tracked like any other character; a newline is not (it consumes no
|
|
584
|
+
* advance).
|
|
585
|
+
*
|
|
586
|
+
* Word wrap is applied when `maxWidth` is finite: words — the text between
|
|
587
|
+
* UAX #14 break opportunities — are committed to a new line when they would
|
|
588
|
+
* exceed the current line width. Forced line breaks are emitted at UAX #14's
|
|
589
|
+
* hard breaks — `\n`, CR, CRLF as one, VT, FF, NEL, U+2028 and U+2029 — none
|
|
590
|
+
* of which lays out a cell. Every run on a line shares one baseline, sunk to
|
|
591
|
+
* clear whichever run reaches highest above it, so mixing sizes or faces aligns
|
|
592
|
+
* them the way inline text aligns everywhere else; line height is
|
|
593
|
+
* `max(fontSize * lineHeight)` across the line. A face that states its ascent
|
|
594
|
+
* and descent sits in its line the way CSS sets it — half the leading above the
|
|
595
|
+
* ascent, negative when the face is taller than the line, so its glyphs overflow
|
|
596
|
+
* the box rather than growing it. A run a relative size shrank
|
|
597
|
+
* measures at its `strutSize` for both, the way a CSS line keeps its parent's
|
|
598
|
+
* strut under a `<sup>`.
|
|
457
599
|
*
|
|
458
600
|
* A run may also sit off that shared baseline: `ResolvedRun.baselineShift`
|
|
459
601
|
* displaces it, which is what `script: 'super' | 'sub'` resolves to. The shift
|
|
@@ -519,6 +661,7 @@ interface LaidOutOutlineGlyph {
|
|
|
519
661
|
/** World units per em — the run's `fontSize`, since em space is unit-scale. */
|
|
520
662
|
scale: number;
|
|
521
663
|
}
|
|
664
|
+
/** Glyphs that share a resolved face, glyph source and paint — one draw call's worth. */
|
|
522
665
|
interface LaidOutGroup {
|
|
523
666
|
/** Resolved atlas family — may differ from the requested family when the
|
|
524
667
|
* cross-family fallback policy substituted a default. This is what the
|
|
@@ -590,7 +733,8 @@ interface LaidOutCell {
|
|
|
590
733
|
* stay in logical order and their x values do not. Sort on `x` for visual
|
|
591
734
|
* order; never assume `cells[i + 1].x` is this cell's right edge. */
|
|
592
735
|
x: number;
|
|
593
|
-
/** Width of the cell: its glyph's advance plus its run's tracking
|
|
736
|
+
/** Width of the cell: its glyph's advance, plus its run's tracking when it
|
|
737
|
+
* closes a grapheme cluster, plus a justified gap's share of the slack. */
|
|
594
738
|
advance: number;
|
|
595
739
|
/** Resolved bidi embedding level — even reads left-to-right. 0 with no
|
|
596
740
|
* engine, which is the same as saying the text was laid out logically. */
|
|
@@ -645,6 +789,7 @@ interface LaidOutLineBox {
|
|
|
645
789
|
*/
|
|
646
790
|
srcEnd: number;
|
|
647
791
|
}
|
|
792
|
+
/** What {@link layoutRuns} returns. Every coordinate is relative to the text's own top-left. */
|
|
648
793
|
interface LaidOutRuns {
|
|
649
794
|
groups: LaidOutGroup[];
|
|
650
795
|
/** Decoration rules, in line order; within a span, underline then
|
|
@@ -663,6 +808,7 @@ interface LaidOutRuns {
|
|
|
663
808
|
height: number;
|
|
664
809
|
};
|
|
665
810
|
}
|
|
811
|
+
/** Options for {@link layoutRuns}. */
|
|
666
812
|
interface LayoutRunsOpts {
|
|
667
813
|
/** Wrap width. `Infinity` never wraps. */
|
|
668
814
|
maxWidth: number;
|
|
@@ -676,9 +822,18 @@ interface LayoutRunsOpts {
|
|
|
676
822
|
lineHeight: number;
|
|
677
823
|
/**
|
|
678
824
|
* `start` / `end` resolve against `direction`; `left` / `right` are absolute
|
|
679
|
-
* and ignore it, the way CSS `text-align` treats the same
|
|
825
|
+
* and ignore it, the way CSS `text-align` treats the same values. `justify`
|
|
826
|
+
* is `justify: true` with the start edge.
|
|
680
827
|
*/
|
|
681
828
|
align: TextAlign;
|
|
829
|
+
/**
|
|
830
|
+
* Spread each line that wrapped across `alignWidth`, widening its word gaps
|
|
831
|
+
* (spaces between words; not leading or hanging trailing ones) by equal
|
|
832
|
+
* shares of the slack. A line that closes its paragraph, or has no gap, or
|
|
833
|
+
* no slack, keeps `align` — so `align` is CSS `text-align-last` here.
|
|
834
|
+
* Implied by `align: 'justify'`. Default `false`.
|
|
835
|
+
*/
|
|
836
|
+
justify?: boolean;
|
|
682
837
|
/**
|
|
683
838
|
* Bidi engine. Omit and the text lays out in logical order, which is correct
|
|
684
839
|
* for left-to-right text and wrong for right-to-left text — see the warning
|
|
@@ -713,6 +868,10 @@ interface LayoutRunsOpts {
|
|
|
713
868
|
*/
|
|
714
869
|
outlineMinSize?: number;
|
|
715
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* Lay out `runs` into draw groups, decoration rules and line boxes. Wrapping,
|
|
873
|
+
* baselines, tracking and decorations follow the rules in this file's module doc.
|
|
874
|
+
*/
|
|
716
875
|
declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts): LaidOutRuns;
|
|
717
876
|
|
|
718
877
|
/**
|
|
@@ -796,4 +955,4 @@ declare function cachedLayoutRuns(runs: readonly ResolvedRun[], opts: LayoutRuns
|
|
|
796
955
|
/** Test helper. Do not call from product code. */
|
|
797
956
|
declare function _resetLayoutCacheForTests(): void;
|
|
798
957
|
|
|
799
|
-
export {
|
|
958
|
+
export { smallCapsText as $, type TransformedRunText as A, type BidiAnalysis as B, cachedLayoutRuns as C, DEFAULT_DECORATION_METRICS as D, decorationMetrics as E, type FontVariantCaps as F, fontString as G, isBoldWeight as H, isSmallCapsLetter as I, layoutRuns as J, markdownToRuns as K, type LaidOutRuns as L, MARKDOWN_RUN_GRAMMAR as M, numericWeight as N, resolveAlign as O, resolveRunFace as P, resolveRuns as Q, type ResolvedTextStyle as R, type StyledRun as S, type TextStyle as T, resolveTextStyle as U, runsToMarkdown as V, runsToPlainText as W, scriptMetrics as X, scriptMetricsFor as Y, smallCapsScale as Z, smallCapsScaleFor as _, type ResolvedRun as a, toRuns as a0, transformRunTexts as a1, _resetLayoutCacheForTests as a2, type LayoutRunsOpts as b, type BidiReordering as c, type BidiResolver as d, DEFAULT_TEXT_STYLE as e, type DecorationKind as f, LAYOUT_CACHE_STRUCTURAL_LIMIT as g, LAYOUT_CACHE_VARIANT_LIMIT as h, type LaidOutCell as i, type LaidOutDecoration as j, type LaidOutGroup as k, type LaidOutLineBox as l, type LaidOutOutlineGlyph as m, type LaidOutQuad as n, type RunFlag as o, type RunGrammar as p, type RunMarker as q, type RunSourceMap as r, SCRIPT_METRICS as s, SMALL_CAPS_SCALE as t, type ScriptPreset as u, type SmallCapsText as v, type TextAlign as w, type TextDirection as x, type TextPaint as y, type TextTransform as z };
|
package/dist/test-seams.d.ts
CHANGED
package/dist/test-seams.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/text",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Typography for weasel: styled runs, style resolution, kerned glyph layout, wrap and measurement. No scene graph, no React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"./package.json": "./package.json"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@weasel-js/geom": "1.
|
|
24
|
-
"@weasel-js/paint": "1.
|
|
23
|
+
"@weasel-js/geom": "1.7.1",
|
|
24
|
+
"@weasel-js/paint": "1.7.1"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"test": "vitest run",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"provenance": true
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@weasel-js/bidi": "1.
|
|
53
|
+
"@weasel-js/bidi": "1.7.1"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@weasel-js/font": "1.
|
|
56
|
+
"@weasel-js/font": "1.7.1"
|
|
57
57
|
}
|
|
58
58
|
}
|