@weasel-js/text 1.9.4 → 1.10.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/README.md +12 -10
- package/dist/{chunk-VZNK3C6F.js → chunk-EFPJZYNI.js} +361 -695
- package/dist/chunk-EFPJZYNI.js.map +1 -0
- package/dist/index.d.ts +513 -62
- package/dist/index.js +791 -21
- package/dist/index.js.map +1 -1
- package/dist/{test-seams-Czz9ua7X.d.ts → test-seams-CuLNcDew.d.ts} +191 -351
- package/dist/test-seams.d.ts +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +6 -5
- package/dist/chunk-VZNK3C6F.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ScreenLength,
|
|
2
|
-
import { FaceMetrics, FontStyle,
|
|
1
|
+
import { ScreenLength, Fill, Stroke } from '@weasel-js/paint';
|
|
2
|
+
import { FaceMetrics, FontStyle, ResolveResult, GlyphMetrics, BmFont, BmFontChar } from '@weasel-js/font';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* CSS `text-transform` over styled runs: `uppercase`, `lowercase` and
|
|
@@ -115,7 +115,7 @@ interface StyledRun {
|
|
|
115
115
|
fontSize?: ScreenLength;
|
|
116
116
|
/** This run's ink. `null` is no fill at all, leaving the glyphs to `stroke`
|
|
117
117
|
* alone; absent inherits the node's. */
|
|
118
|
-
fill?:
|
|
118
|
+
fill?: Fill | null;
|
|
119
119
|
/** Outline over this run's glyphs. Overrides the node's own `data.stroke`;
|
|
120
120
|
* absent inherits it. Only painted on the outline tier. */
|
|
121
121
|
stroke?: Stroke;
|
|
@@ -216,15 +216,12 @@ declare function runsToMarkdown(runs: readonly StyledRun[], grammar?: RunGrammar
|
|
|
216
216
|
declare function markdownToRuns(input: string, grammar?: RunGrammar): StyledRun[];
|
|
217
217
|
|
|
218
218
|
/**
|
|
219
|
-
* Typography for `TextPose` and friends.
|
|
220
|
-
* pass `{}` or override the few they care about. Defaults live in
|
|
219
|
+
* Typography for `TextPose` and friends. Defaults live in
|
|
221
220
|
* `DEFAULT_TEXT_STYLE` and are applied at render/measure time, never written
|
|
222
221
|
* back to the pose.
|
|
223
222
|
*
|
|
224
|
-
* Paint
|
|
225
|
-
*
|
|
226
|
-
* kind uses; `resolveTextStyle` takes them as its second argument and
|
|
227
|
-
* `StyledRun.fill` / `.stroke` override them per range.
|
|
223
|
+
* Paint does not live here. A text node carries its fill and stroke in
|
|
224
|
+
* `data.fill` / `data.stroke`, the slots every other node kind uses.
|
|
228
225
|
*/
|
|
229
226
|
|
|
230
227
|
/**
|
|
@@ -238,12 +235,9 @@ type TextAlign = 'left' | 'center' | 'right' | 'start' | 'end' | 'justify';
|
|
|
238
235
|
type TextDirection = 'ltr' | 'rtl';
|
|
239
236
|
/**
|
|
240
237
|
* Collapse a possibly reading-order-relative alignment to an absolute edge.
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* the geometry. `justify` collapses to the start edge, which
|
|
245
|
-
* is where it sets every line it does not spread; whether to spread is carried
|
|
246
|
-
* separately, as `LayoutRunsOpts.justify`.
|
|
238
|
+
* `justify` collapses to the start edge, which is where it sets every line it
|
|
239
|
+
* does not spread; whether to spread is carried separately, as
|
|
240
|
+
* `LayoutRunsOpts.justify`.
|
|
247
241
|
*/
|
|
248
242
|
declare function resolveAlign(align: TextAlign, direction: TextDirection): 'left' | 'center' | 'right';
|
|
249
243
|
/** User-facing text style. All fields optional; defaults applied at render time via `resolveTextStyle`. */
|
|
@@ -310,9 +304,8 @@ interface TextStyle {
|
|
|
310
304
|
fontVariantCaps?: FontVariantCaps;
|
|
311
305
|
/**
|
|
312
306
|
* Set the node's text as a superscript or subscript — the default every run
|
|
313
|
-
* inherits
|
|
314
|
-
*
|
|
315
|
-
* Absent is ordinary text.
|
|
307
|
+
* inherits. The lines keep the height and baseline the unscripted text would
|
|
308
|
+
* have had. Absent is ordinary text.
|
|
316
309
|
*/
|
|
317
310
|
script?: 'super' | 'sub';
|
|
318
311
|
}
|
|
@@ -330,7 +323,7 @@ interface ResolvedTextStyle {
|
|
|
330
323
|
wrap: boolean;
|
|
331
324
|
/** `null` is an explicit no-fill, the way it is on every other node kind:
|
|
332
325
|
* outline-only text, painted by its stroke alone. */
|
|
333
|
-
fill:
|
|
326
|
+
fill: Fill | null;
|
|
334
327
|
caretColor: string;
|
|
335
328
|
selectionBackground: string | null;
|
|
336
329
|
selectionColor: string | null;
|
|
@@ -348,27 +341,19 @@ interface ResolvedTextStyle {
|
|
|
348
341
|
}
|
|
349
342
|
/** Default resolved style used when a `TextPose` omits `style`. */
|
|
350
343
|
declare const DEFAULT_TEXT_STYLE: ResolvedTextStyle;
|
|
351
|
-
/**
|
|
352
|
-
* The paint a text node hands its glyphs — `data.fill` and `data.stroke`,
|
|
353
|
-
* read straight off the node. Runs inherit these when they name none of
|
|
354
|
-
* their own.
|
|
355
|
-
*/
|
|
344
|
+
/** The paint a text node hands its glyphs — `data.fill` and `data.stroke`. Runs inherit these when they name none of their own. */
|
|
356
345
|
interface TextPaint {
|
|
357
346
|
/** `null` is an explicit no-fill and absent takes the default black — the
|
|
358
347
|
* reading every other node kind gives `data.fill`. Unfilled text paints
|
|
359
348
|
* through its stroke and nothing else, so it needs one to be visible. */
|
|
360
|
-
fill?:
|
|
349
|
+
fill?: Fill | null;
|
|
361
350
|
/**
|
|
362
|
-
* Outline painted over the glyph fill. Absent means no outline
|
|
363
|
-
* no such thing as a default text stroke.
|
|
351
|
+
* Outline painted over the glyph fill. Absent means no outline.
|
|
364
352
|
*
|
|
365
|
-
* Only glyphs on the outline tier are stroked:
|
|
366
|
-
* `textOutlineMinScreenSize` a glyph is a
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
* stroke, and it renders unstroked rather than approximated. `width` is in
|
|
370
|
-
* world units, like every other stroke in the kit — it does not scale with
|
|
371
|
-
* `fontSize`.
|
|
353
|
+
* Only glyphs on the outline tier are stroked: below
|
|
354
|
+
* `textOutlineMinScreenSize` a glyph is a sampled distance field with no
|
|
355
|
+
* geometry to stroke, and it renders unstroked. `width` is in world units —
|
|
356
|
+
* it does not scale with `fontSize`.
|
|
372
357
|
*/
|
|
373
358
|
stroke?: Stroke | null;
|
|
374
359
|
}
|
|
@@ -377,10 +362,7 @@ interface TextPaint {
|
|
|
377
362
|
* taking the glyph paint from the node rather than from the style.
|
|
378
363
|
*
|
|
379
364
|
* `scale` is the view scale any `{ px }` size resolves against — the same
|
|
380
|
-
* mean-of-the-axes factor `resolveStrokeWidth` takes.
|
|
381
|
-
* here, at the entry to layout, rather than at draw time: a screen-pixel size
|
|
382
|
-
* changes the glyph advances, the wrap points and the measured bounds, and
|
|
383
|
-
* everything downstream of `ResolvedTextStyle` reads a plain world number.
|
|
365
|
+
* mean-of-the-axes factor `resolveStrokeWidth` takes.
|
|
384
366
|
*/
|
|
385
367
|
declare function resolveTextStyle(style?: TextStyle, paint?: TextPaint, scale?: number): ResolvedTextStyle;
|
|
386
368
|
/** Build a CSS `font` shorthand suitable for `ctx.font`. */
|
|
@@ -388,35 +370,17 @@ declare function fontString(s: ResolvedTextStyle): string;
|
|
|
388
370
|
|
|
389
371
|
/**
|
|
390
372
|
* Apply node-level `ResolvedTextStyle` defaults to each `StyledRun`,
|
|
391
|
-
* producing a
|
|
392
|
-
* layout and draw never re-resolve defaults — `ResolvedRun` is the
|
|
393
|
-
* canonical shape the renderer consumes.
|
|
394
|
-
*
|
|
395
|
-
* `bold`/`italic` toggles on a run are folded into `fontWeight`/`fontStyle`:
|
|
396
|
-
* `bold: true` → fontWeight 700, `italic: true` → fontStyle 'italic'. A run's
|
|
397
|
-
* own numeric `fontWeight` is the primitive `bold` is a preset over, so it
|
|
398
|
-
* wins over both the flag and the node weight.
|
|
399
|
-
* Explicit `fontFamily` / `fontSize` / `fill` / `letterSpacing` on the run
|
|
400
|
-
* override the node-level value (`letterSpacing: 0` on a run is an override,
|
|
401
|
-
* not an absence — it zeroes inherited tracking).
|
|
373
|
+
* producing a `ResolvedRun` with every styling field set.
|
|
402
374
|
*
|
|
403
|
-
* `
|
|
404
|
-
* `
|
|
405
|
-
*
|
|
406
|
-
*
|
|
375
|
+
* `bold`/`italic` on a run fold into `fontWeight`/`fontStyle`; a run's own
|
|
376
|
+
* numeric `fontWeight` wins over both the flag and the node weight.
|
|
377
|
+
* `letterSpacing: 0` on a run is an override, not an absence — it zeroes
|
|
378
|
+
* inherited tracking. The decorations are *additive*: a run can turn one on
|
|
379
|
+
* but never off, so they resolve as `run.x || style.x`.
|
|
407
380
|
*
|
|
408
|
-
* `script`
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* that superscripts exist — it places a run against a baseline and an offset.
|
|
412
|
-
*
|
|
413
|
-
* `textTransform` is applied here too, so `text` is what gets drawn. When a
|
|
414
|
-
* transform changes a length, `srcMap` says which source characters each
|
|
415
|
-
* drawn one came from; see `textTransform.ts`.
|
|
416
|
-
*
|
|
417
|
-
* `fontVariantCaps: 'small-caps'` is applied after it, over the transformed
|
|
418
|
-
* text: lowercase becomes capitals, and `sizeMap` gives those their smaller
|
|
419
|
-
* size. See `smallCaps.ts`.
|
|
381
|
+
* `script` folds into the two primitives it is a preset over, and comes out
|
|
382
|
+
* as one world-unit `baselineShift` and a final `fontSize`. `textTransform`
|
|
383
|
+
* is applied here, then small caps over the transformed text.
|
|
420
384
|
*/
|
|
421
385
|
|
|
422
386
|
/** A run with every style resolved against the node's text style — no
|
|
@@ -441,7 +405,7 @@ interface ResolvedRun {
|
|
|
441
405
|
/** `null` is an explicit no-fill: the glyphs are painted by `stroke` alone,
|
|
442
406
|
* which only the outline tier can do. Nothing is emitted for a run with
|
|
443
407
|
* neither. */
|
|
444
|
-
fill:
|
|
408
|
+
fill: Fill | null;
|
|
445
409
|
/** Outline over this run's glyphs, or absent for none. Painted only on the
|
|
446
410
|
* outline tier — a distance field has no geometry to stroke. */
|
|
447
411
|
stroke?: Stroke;
|
|
@@ -455,11 +419,8 @@ interface ResolvedRun {
|
|
|
455
419
|
overline: boolean;
|
|
456
420
|
/**
|
|
457
421
|
* How far this run sits off the line's shared baseline, in world units;
|
|
458
|
-
* positive raises. 0 for ordinary text.
|
|
459
|
-
*
|
|
460
|
-
* Already multiplied out against the inherited font size, and already
|
|
461
|
-
* carrying whatever `script` asked for — layout adds it to a baseline and
|
|
462
|
-
* asks nothing about where it came from.
|
|
422
|
+
* positive raises. 0 for ordinary text. Already carries whatever `script`
|
|
423
|
+
* asked for.
|
|
463
424
|
*/
|
|
464
425
|
baselineShift: number;
|
|
465
426
|
/**
|
|
@@ -479,11 +440,8 @@ type ScriptPreset = Readonly<{
|
|
|
479
440
|
* What `script: 'super'` and `script: 'sub'` expand to for a face that states
|
|
480
441
|
* no script metrics of its own, as fractions of the inherited font size:
|
|
481
442
|
* `size` scales it, `shift` raises (positive) or lowers (negative) the
|
|
482
|
-
* baseline.
|
|
483
|
-
*
|
|
484
|
-
* These are Adobe's defaults — InDesign and Illustrator ship 58.3% size and
|
|
485
|
-
* 33.3% position for both. A face that carries `OS/2` script metrics uses
|
|
486
|
-
* those instead; {@link scriptMetricsFor} is what a run actually gets.
|
|
443
|
+
* baseline. These are Adobe's defaults. A face that carries `OS/2` script
|
|
444
|
+
* metrics uses those instead; {@link scriptMetricsFor} is what a run gets.
|
|
487
445
|
*/
|
|
488
446
|
declare const SCRIPT_METRICS: Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
489
447
|
/** The script presets for a face: its own `OS/2` values where it states
|
|
@@ -491,10 +449,8 @@ declare const SCRIPT_METRICS: Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
|
491
449
|
declare function scriptMetrics(face?: FaceMetrics): Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
492
450
|
/**
|
|
493
451
|
* The script presets a run set in `(family, weight, style)` gets — resolved
|
|
494
|
-
* through the font registry exactly as layout resolves the run
|
|
495
|
-
*
|
|
496
|
-
* the canvas draws with. Override either half per run with `baselineShift` /
|
|
497
|
-
* `fontScale`.
|
|
452
|
+
* through the font registry exactly as layout resolves the run. Override
|
|
453
|
+
* either half per run with `baselineShift` / `fontScale`.
|
|
498
454
|
*/
|
|
499
455
|
declare function scriptMetricsFor(family: string, weight: number, style: FontStyle): Readonly<Record<'super' | 'sub', ScriptPreset>>;
|
|
500
456
|
/** A `TextStyle.fontWeight` as a number: the CSS keywords `bold` and
|
|
@@ -516,29 +472,6 @@ declare function resolveRunFace(run: StyledRun, style: Pick<ResolvedTextStyle, '
|
|
|
516
472
|
* `style`. */
|
|
517
473
|
declare function resolveRuns(runs: readonly StyledRun[], style: ResolvedTextStyle, viewScale?: number): ResolvedRun[];
|
|
518
474
|
|
|
519
|
-
/** The three text decoration rules, in the order every tier paints them. */
|
|
520
|
-
type DecorationKind = 'underline' | 'strikethrough' | 'overline';
|
|
521
|
-
/**
|
|
522
|
-
* Decoration placement and weight for a face that states none, as fractions
|
|
523
|
-
* of the run's `fontSize`. Offsets are the *top* edge of the rule, measured
|
|
524
|
-
* down from the baseline — so the two rules that sit above it are negative.
|
|
525
|
-
*
|
|
526
|
-
* Derived, not measured: they apply to an atlas baked before `gen-font`
|
|
527
|
-
* recorded `faceMetrics`, a custom outline parser that reports none, and the
|
|
528
|
-
* canvas tier, which has no font tables to read.
|
|
529
|
-
*/
|
|
530
|
-
declare const DEFAULT_DECORATION_METRICS: Readonly<Record<DecorationKind, FaceRuleMetrics>>;
|
|
531
|
-
/**
|
|
532
|
-
* Where each rule sits for a face, in ems: the face's own underline and
|
|
533
|
-
* strikeout where it states them, the defaults where it does not. No font
|
|
534
|
-
* table places an overline, so it keeps the default offset and takes the
|
|
535
|
-
* underline's weight, as browsers draw it.
|
|
536
|
-
*
|
|
537
|
-
* Every text tier places its rules through this, so one face puts a rule in
|
|
538
|
-
* the same place whichever tier paints it.
|
|
539
|
-
*/
|
|
540
|
-
declare function decorationMetrics(face?: FaceMetrics): Readonly<Record<DecorationKind, FaceRuleMetrics>>;
|
|
541
|
-
|
|
542
475
|
/**
|
|
543
476
|
* The bidi contract, declared here and implemented elsewhere.
|
|
544
477
|
*
|
|
@@ -578,152 +511,85 @@ interface BidiResolver {
|
|
|
578
511
|
baseLevel(analysis: BidiAnalysis): number;
|
|
579
512
|
}
|
|
580
513
|
|
|
514
|
+
/** Options for `layoutRuns`. */
|
|
515
|
+
interface LayoutRunsOpts {
|
|
516
|
+
/** Wrap width. `Infinity` never wraps. */
|
|
517
|
+
maxWidth: number;
|
|
518
|
+
/**
|
|
519
|
+
* Width of the box `center` / `right` resolve within, with `x = 0` its left
|
|
520
|
+
* edge. Default `maxWidth`. Separate from it so a box can align text it does
|
|
521
|
+
* not wrap. When both are infinite a line anchors on its own width instead:
|
|
522
|
+
* `x = 0` is its midpoint (`center`) or right edge (`right`).
|
|
523
|
+
*/
|
|
524
|
+
alignWidth?: number;
|
|
525
|
+
lineHeight: number;
|
|
526
|
+
/**
|
|
527
|
+
* `start` / `end` resolve against `direction`; `left` / `right` are absolute
|
|
528
|
+
* and ignore it, the way CSS `text-align` treats the same values. `justify`
|
|
529
|
+
* is `justify: true` with the start edge.
|
|
530
|
+
*/
|
|
531
|
+
align: TextAlign;
|
|
532
|
+
/**
|
|
533
|
+
* Spread each line that wrapped across `alignWidth`, widening its word gaps
|
|
534
|
+
* (spaces between words; not leading or hanging trailing ones) by equal
|
|
535
|
+
* shares of the slack. A line that closes its paragraph, or has no gap, or
|
|
536
|
+
* no slack, keeps `align` — so `align` is CSS `text-align-last` here.
|
|
537
|
+
* Implied by `align: 'justify'`. Default `false`.
|
|
538
|
+
*/
|
|
539
|
+
justify?: boolean;
|
|
540
|
+
/**
|
|
541
|
+
* Bidi engine. Default: the one given to `registerBidi`. With neither, the
|
|
542
|
+
* text lays out in logical order, which is correct for left-to-right text
|
|
543
|
+
* and wrong for right-to-left text — see the warning this emits when it
|
|
544
|
+
* detects the latter without one.
|
|
545
|
+
*/
|
|
546
|
+
bidi?: BidiResolver;
|
|
547
|
+
/**
|
|
548
|
+
* Reading direction: the base direction of the bidi analysis, and what
|
|
549
|
+
* `start` / `end` resolve against. Default `'auto'`, each paragraph's own
|
|
550
|
+
* first strong character, which only an engine can find: with none, `'auto'`
|
|
551
|
+
* reads left to right.
|
|
552
|
+
*/
|
|
553
|
+
direction?: TextDirection | 'auto';
|
|
554
|
+
/**
|
|
555
|
+
* Distance between tab stops, in spaces of the tab's own run (its advance
|
|
556
|
+
* plus the run's tracking), as CSS `tab-size` counts it. A tab advances to
|
|
557
|
+
* the next stop from the start of its line. Default 8.
|
|
558
|
+
*/
|
|
559
|
+
tabSize?: number;
|
|
560
|
+
}
|
|
561
|
+
|
|
581
562
|
/**
|
|
582
|
-
* Runs-aware
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
* run
|
|
586
|
-
* `(family, resolvedWeight, resolvedStyle, syntheticBold, syntheticItalic, fillKey)`
|
|
587
|
-
* so the renderer issues one draw call per atlas+color group.
|
|
563
|
+
* Runs-aware text layout: wraps `ResolvedRun[]` into lines and places every
|
|
564
|
+
* glyph on them. What to draw for the result — which glyphs share a draw,
|
|
565
|
+
* which tier paints each, where the decoration rules go — is `paintRuns`'.
|
|
566
|
+
* Nothing here reads a run's paint, so recoloring text never lays it out again.
|
|
588
567
|
*
|
|
589
568
|
* A run's `letterSpacing` (world units, so it does not scale with `fontSize`)
|
|
590
569
|
* is added to the advance *after* every grapheme cluster of that run,
|
|
591
|
-
* including the last one on a line — the CSS `letter-spacing` rule
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
* before the gap opens. Clusters are segmented per run. Trailing tracking
|
|
595
|
-
* therefore widens the measured line width and counts toward wrapping. Spaces
|
|
596
|
-
* are tracked like any other character; a newline is not (it consumes no
|
|
597
|
-
* advance).
|
|
570
|
+
* including the last one on a line — the CSS `letter-spacing` rule. Trailing
|
|
571
|
+
* tracking therefore widens the measured line width and counts toward
|
|
572
|
+
* wrapping. Spaces are tracked like any other character; a newline is not.
|
|
598
573
|
*
|
|
599
|
-
* Word wrap is applied when `maxWidth` is finite
|
|
600
|
-
*
|
|
601
|
-
* exceed the current line width. Forced line breaks are emitted at UAX #14's
|
|
602
|
-
* hard breaks — `\n`, CR, CRLF as one, VT, FF, NEL, U+2028 and U+2029 — none
|
|
574
|
+
* Word wrap is applied when `maxWidth` is finite, at UAX #14 break
|
|
575
|
+
* opportunities. Forced line breaks are emitted at UAX #14's hard breaks, none
|
|
603
576
|
* of which lays out a cell. Every run on a line shares one baseline, sunk to
|
|
604
|
-
* clear whichever run reaches highest above it
|
|
605
|
-
* them the way inline text aligns everywhere else; line height is
|
|
577
|
+
* clear whichever run reaches highest above it; line height is
|
|
606
578
|
* `max(fontSize * lineHeight)` across the line. A face that states its ascent
|
|
607
579
|
* and descent sits in its line the way CSS sets it — half the leading above the
|
|
608
580
|
* ascent, negative when the face is taller than the line, so its glyphs overflow
|
|
609
581
|
* the box rather than growing it. A run a relative size shrank
|
|
610
|
-
* measures at its `strutSize` for both
|
|
611
|
-
* strut under a `<sup>`.
|
|
612
|
-
*
|
|
613
|
-
* A run may also sit off that shared baseline: `ResolvedRun.baselineShift`
|
|
614
|
-
* displaces it, which is what `script: 'super' | 'sub'` resolves to. The shift
|
|
615
|
-
* moves the run's glyphs, its outline geometry and its own decoration rules
|
|
616
|
-
* together, and deliberately does not feed back into the line's baseline or
|
|
617
|
-
* its height — a superscript rides on the line rather than reflowing it.
|
|
618
|
-
*
|
|
619
|
-
* Underline, strikethrough and overline come out on a second channel,
|
|
620
|
-
* `decorations` —
|
|
621
|
-
* solid rectangles, not textured glyphs, so they cannot ride in a group's
|
|
622
|
-
* `quads` (which upload UVs into an MSDF program). They are accumulated
|
|
623
|
-
* during the same per-line pen walk that emits quads, *not* reconstructed
|
|
624
|
-
* from quad extents afterwards: quads exist only for glyphs with ink, so a
|
|
625
|
-
* decorated span's spaces would punch holes in a rule derived from them.
|
|
582
|
+
* measures at its `strutSize` for both.
|
|
626
583
|
*
|
|
627
|
-
*
|
|
584
|
+
* `ResolvedRun.baselineShift` displaces a run off that shared baseline. The
|
|
585
|
+
* shift moves the run's glyphs and its own decoration rules together, and does
|
|
586
|
+
* not feed back into the line's baseline or its height.
|
|
628
587
|
*
|
|
629
|
-
* Every coordinate out of here is measured from the text's own top-left
|
|
630
|
-
*
|
|
631
|
-
*
|
|
632
|
-
* the position in its key and miss on every frame of the drag — and it costs
|
|
633
|
-
* the caller one addition per vertex, inside loops already walking every one.
|
|
634
|
-
* Alignment, wrapping, tracking and decoration placement all read widths and
|
|
635
|
-
* pen deltas, never an absolute coordinate, so the translation is exact.
|
|
588
|
+
* Every coordinate out of here is measured from the text's own top-left: the
|
|
589
|
+
* caller translates. That is what lets a text node be dragged without
|
|
590
|
+
* re-laying out.
|
|
636
591
|
*/
|
|
637
592
|
|
|
638
|
-
/** One textured glyph quad, origin-relative — see the header. */
|
|
639
|
-
interface LaidOutQuad {
|
|
640
|
-
x0: number;
|
|
641
|
-
y0: number;
|
|
642
|
-
x1: number;
|
|
643
|
-
y1: number;
|
|
644
|
-
u0: number;
|
|
645
|
-
v0: number;
|
|
646
|
-
u1: number;
|
|
647
|
-
v1: number;
|
|
648
|
-
/** Y coordinate of the line's baseline (penY at quad emission). Used by the
|
|
649
|
-
* synthetic-italic vertex skew so above-baseline vertices lean right. */
|
|
650
|
-
baselineY: number;
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* One glyph the renderer should tessellate rather than sample: real font
|
|
654
|
-
* outline geometry, for text large enough that a distance field shows the
|
|
655
|
-
* raster it was reconstructed from.
|
|
656
|
-
*
|
|
657
|
-
* `d` is em-space SVG path data straight from `@weasel-js/font`'s outline
|
|
658
|
-
* registry — 1 unit is 1 em, y grows down, origin on the baseline at the pen.
|
|
659
|
-
* Placing it is therefore a uniform scale by `scale` (world units per em)
|
|
660
|
-
* followed by a translate to `(x, baselineY)`, and nothing here depends on
|
|
661
|
-
* zoom: the same glyph at the same size in two places is the same geometry
|
|
662
|
-
* twice, which is what lets the renderer tessellate it once and cache it.
|
|
663
|
-
*
|
|
664
|
-
* `key` identifies that cached tessellation — face identity plus codepoint,
|
|
665
|
-
* assembled here because layout is where both are in hand.
|
|
666
|
-
*/
|
|
667
|
-
interface LaidOutOutlineGlyph {
|
|
668
|
-
d: string;
|
|
669
|
-
key: string;
|
|
670
|
-
/** Pen position: where em-space x = 0 lands, in world units. */
|
|
671
|
-
x: number;
|
|
672
|
-
/** The line's baseline: where em-space y = 0 lands, in world units. */
|
|
673
|
-
baselineY: number;
|
|
674
|
-
/** World units per em — the run's `fontSize`, since em space is unit-scale. */
|
|
675
|
-
scale: number;
|
|
676
|
-
}
|
|
677
|
-
/** Glyphs that share a resolved face, glyph source and paint — one draw call's worth. */
|
|
678
|
-
interface LaidOutGroup {
|
|
679
|
-
/** Resolved atlas family — may differ from the requested family when the
|
|
680
|
-
* cross-family fallback policy substituted a default. This is what the
|
|
681
|
-
* renderer looks the atlas up by, so it must be the one that resolves. */
|
|
682
|
-
family: string;
|
|
683
|
-
/** Resolved variant — matches the registered atlas and the texture-cache key. */
|
|
684
|
-
weight: number;
|
|
685
|
-
style: FontStyle;
|
|
686
|
-
/** Gap between the request and the resolved match. Drives shader uniforms. */
|
|
687
|
-
synthetic: {
|
|
688
|
-
bold: boolean;
|
|
689
|
-
italic: boolean;
|
|
690
|
-
};
|
|
691
|
-
/** Which glyph source (and therefore shader/texture) this group binds:
|
|
692
|
-
* baked MSDF atlas, the runtime canvas-SDF dynamic atlas, or tessellated
|
|
693
|
-
* font outlines. */
|
|
694
|
-
source: 'atlas' | 'canvas' | 'outline';
|
|
695
|
-
/** Dynamic-atlas page index for 'canvas' groups; 0 for the others. */
|
|
696
|
-
page: number;
|
|
697
|
-
/** `null` for an unfilled run: the group's glyphs are painted by `stroke`
|
|
698
|
-
* alone. Only ever null on an `'outline'` group carrying a stroke, since
|
|
699
|
-
* nothing else can put ink down without a fill. */
|
|
700
|
-
fill: FillStyle | null;
|
|
701
|
-
/** Outline painted over the glyphs, or absent for none. Only ever set on
|
|
702
|
-
* an `'outline'` group — the SDF tiers have no geometry to stroke, which
|
|
703
|
-
* is why a stroke pulls its run onto the outline tier at any size. A run
|
|
704
|
-
* the tier cannot serve at all (no registered outlines, synthetic bold)
|
|
705
|
-
* stays on the atlas and carries the request no further. */
|
|
706
|
-
stroke?: Stroke;
|
|
707
|
-
/** Textured glyph quads. Always empty for an `'outline'` group. */
|
|
708
|
-
quads: LaidOutQuad[];
|
|
709
|
-
/** Outline geometry. Always empty for an `'atlas'` / `'canvas'` group —
|
|
710
|
-
* the two channels are exclusive, since the group is also the draw call
|
|
711
|
-
* and one draw call binds one program. */
|
|
712
|
-
glyphs: LaidOutOutlineGlyph[];
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* One decoration rule: an axis-aligned solid rectangle in the same world
|
|
716
|
-
* space as `LaidOutQuad`. Never spans a line break, and carries the fill of
|
|
717
|
-
* the run(s) it decorates so the rule follows the text colour.
|
|
718
|
-
*/
|
|
719
|
-
interface LaidOutDecoration {
|
|
720
|
-
kind: DecorationKind;
|
|
721
|
-
x0: number;
|
|
722
|
-
y0: number;
|
|
723
|
-
x1: number;
|
|
724
|
-
y1: number;
|
|
725
|
-
fill: FillStyle;
|
|
726
|
-
}
|
|
727
593
|
/**
|
|
728
594
|
* One advance cell: a single code point's slot on a line.
|
|
729
595
|
*
|
|
@@ -740,7 +606,7 @@ interface LaidOutCell {
|
|
|
740
606
|
/** One past that source character — `srcIndex + 2` for an astral one. */
|
|
741
607
|
srcEnd: number;
|
|
742
608
|
cp: number;
|
|
743
|
-
/** Left edge of the cell, post-alignment, origin-relative
|
|
609
|
+
/** Left edge of the cell, post-alignment, origin-relative.
|
|
744
610
|
*
|
|
745
611
|
* **Not monotonic across `cells`** once a bidi engine reorders a line: cells
|
|
746
612
|
* stay in logical order and their x values do not. Sort on `x` for visual
|
|
@@ -756,6 +622,8 @@ interface LaidOutCell {
|
|
|
756
622
|
* Whether this code point can put ink on the page. False for a space and
|
|
757
623
|
* for a code point no tier could serve — each of which still holds its
|
|
758
624
|
* slot. A zero-advance combining mark is `true`: it inks without advancing.
|
|
625
|
+
* An emoji drawn as one color glyph inks from its cluster's closing code
|
|
626
|
+
* point, which holds the whole advance; the ones before it are `false`.
|
|
759
627
|
*
|
|
760
628
|
* A property of the character and the face, not of this call: it does not
|
|
761
629
|
* change when a dynamic bake lands or the outline threshold is crossed. A
|
|
@@ -771,15 +639,43 @@ interface LaidOutCell {
|
|
|
771
639
|
clusterEnd: boolean;
|
|
772
640
|
}
|
|
773
641
|
/**
|
|
774
|
-
* One
|
|
642
|
+
* One code point where the pen put it, with what a painter needs to draw it:
|
|
643
|
+
* the tier that serves it and its record there. Carries no paint.
|
|
644
|
+
*/
|
|
645
|
+
interface PlacedGlyph {
|
|
646
|
+
/** Index of its run in the runs laid out. */
|
|
647
|
+
run: number;
|
|
648
|
+
cp: number;
|
|
649
|
+
/** The glyph's own size, which small caps sets below its run's. */
|
|
650
|
+
fontSize: number;
|
|
651
|
+
/** The tier serving the glyph, which is not its run's own when the code
|
|
652
|
+
* point escalated to the dynamic tier, and that tier's metrics. */
|
|
653
|
+
resolved: ResolveResult;
|
|
654
|
+
metrics: GlyphMetrics;
|
|
655
|
+
/** The atlas to sample and the glyph's record in it. Both null on the
|
|
656
|
+
* outline tier and for a slot with nothing to draw. A dynamic glyph's
|
|
657
|
+
* record gains its atlas rect in place when its bake lands. */
|
|
658
|
+
font: BmFont | null;
|
|
659
|
+
glyph: BmFontChar | null;
|
|
660
|
+
/** Pen position: the left edge of the glyph's slot. */
|
|
661
|
+
x: number;
|
|
662
|
+
/** Its line's baseline, raised by its run's `baselineShift`. */
|
|
663
|
+
baselineY: number;
|
|
664
|
+
/** The glyph's own advance. */
|
|
665
|
+
advance: number;
|
|
666
|
+
/** How far the pen moved past it: `advance`, its run's tracking, and a
|
|
667
|
+
* justified gap's share of the slack. */
|
|
668
|
+
step: number;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* One laid-out line's box.
|
|
775
672
|
*
|
|
776
673
|
* `[x0, x1]` is the line's own advance width *after* alignment — not the
|
|
777
674
|
* wrap box — so a short centered line reports the span it actually occupies.
|
|
778
|
-
* `[y0, y1]` is the full line box: `y0` is the pen's line top,
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
* box, not an ink bounding box.
|
|
675
|
+
* `[y0, y1]` is the full line box: `y0` is the pen's line top, and the box is
|
|
676
|
+
* as tall as its tallest run's `lineHeight` times that run's size, or the
|
|
677
|
+
* larger size a shrunken run inherited. Ink can escape it vertically; this is
|
|
678
|
+
* the typographic box, not an ink bounding box.
|
|
783
679
|
*
|
|
784
680
|
* Emitted for every line including empty ones, so indices line up with the
|
|
785
681
|
* wrap. An empty line has `x0 === x1`.
|
|
@@ -792,16 +688,18 @@ interface LaidOutLineBox {
|
|
|
792
688
|
/** The line's baseline, for callers placing carets or rules against it. */
|
|
793
689
|
baselineY: number;
|
|
794
690
|
/**
|
|
795
|
-
* One cell per code point on this line,
|
|
796
|
-
* line covers has exactly one, drawn or not; only a newline has none,
|
|
797
|
-
* it separates cells rather than being one. The code points are the
|
|
798
|
-
* ones, after `textTransform`, so an uppercased `ß` has two cells.
|
|
691
|
+
* One cell per code point on this line, in logical order. Every code point
|
|
692
|
+
* the line covers has exactly one, drawn or not; only a newline has none,
|
|
693
|
+
* since it separates cells rather than being one. The code points are the
|
|
694
|
+
* drawn ones, after `textTransform`, so an uppercased `ß` has two cells.
|
|
799
695
|
*
|
|
800
696
|
* A caret stop is a cell's `x`, and the stop closing the line is `x1` /
|
|
801
697
|
* `srcEnd` — there is one more stop than cell, except that cells sharing a
|
|
802
698
|
* source span have no stop between them.
|
|
803
699
|
*/
|
|
804
700
|
cells: LaidOutCell[];
|
|
701
|
+
/** The same code points as placed glyphs, in visual order, left to right. */
|
|
702
|
+
glyphs: PlacedGlyph[];
|
|
805
703
|
/**
|
|
806
704
|
* Source offset just past this line's last cell — the closing caret stop's
|
|
807
705
|
* index, and the only source offset a blank line carries.
|
|
@@ -810,93 +708,22 @@ interface LaidOutLineBox {
|
|
|
810
708
|
}
|
|
811
709
|
/** What {@link layoutRuns} returns. Every coordinate is relative to the text's own top-left. */
|
|
812
710
|
interface LaidOutRuns {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
* strikethrough then overline. Empty when nothing is decorated. */
|
|
816
|
-
decorations: LaidOutDecoration[];
|
|
817
|
-
/** Per-line boxes in layout order. Lets a caller reason about where the
|
|
818
|
-
* text actually sits inside its wrap box without re-running the wrap —
|
|
819
|
-
* `textLineBoxes` builds the text silhouette from these, so picking and
|
|
820
|
-
* painting cannot drift apart. */
|
|
711
|
+
/** Per-line boxes in layout order: where the text actually sits inside its
|
|
712
|
+
* wrap box. */
|
|
821
713
|
lines: LaidOutLineBox[];
|
|
822
|
-
/** The text's
|
|
714
|
+
/** The text's box. `width` is the widest line measured to its last
|
|
823
715
|
* non-space cell — a trailing space hangs past the aligned edge, so a
|
|
824
|
-
* block wrapped at `maxWidth` never reports wider than it.
|
|
716
|
+
* block wrapped at `maxWidth` never reports wider than it. `height` is the
|
|
717
|
+
* line boxes stacked. Not an ink box: a decoration rule, or a run shifted
|
|
718
|
+
* off the baseline, can fall outside it. */
|
|
825
719
|
bounds: {
|
|
826
720
|
width: number;
|
|
827
721
|
height: number;
|
|
828
722
|
};
|
|
829
723
|
}
|
|
830
|
-
/** Options for {@link layoutRuns}. */
|
|
831
|
-
interface LayoutRunsOpts {
|
|
832
|
-
/** Wrap width. `Infinity` never wraps. */
|
|
833
|
-
maxWidth: number;
|
|
834
|
-
/**
|
|
835
|
-
* Width of the box `center` / `right` resolve within, with `x = 0` its left
|
|
836
|
-
* edge. Default `maxWidth`. Separate from it so a box can align text it does
|
|
837
|
-
* not wrap. When both are infinite a line anchors on its own width instead:
|
|
838
|
-
* `x = 0` is its midpoint (`center`) or right edge (`right`).
|
|
839
|
-
*/
|
|
840
|
-
alignWidth?: number;
|
|
841
|
-
lineHeight: number;
|
|
842
|
-
/**
|
|
843
|
-
* `start` / `end` resolve against `direction`; `left` / `right` are absolute
|
|
844
|
-
* and ignore it, the way CSS `text-align` treats the same values. `justify`
|
|
845
|
-
* is `justify: true` with the start edge.
|
|
846
|
-
*/
|
|
847
|
-
align: TextAlign;
|
|
848
|
-
/**
|
|
849
|
-
* Spread each line that wrapped across `alignWidth`, widening its word gaps
|
|
850
|
-
* (spaces between words; not leading or hanging trailing ones) by equal
|
|
851
|
-
* shares of the slack. A line that closes its paragraph, or has no gap, or
|
|
852
|
-
* no slack, keeps `align` — so `align` is CSS `text-align-last` here.
|
|
853
|
-
* Implied by `align: 'justify'`. Default `false`.
|
|
854
|
-
*/
|
|
855
|
-
justify?: boolean;
|
|
856
|
-
/**
|
|
857
|
-
* Bidi engine. Default: the one given to `registerBidi`. With neither, the
|
|
858
|
-
* text lays out in logical order, which is correct for left-to-right text
|
|
859
|
-
* and wrong for right-to-left text — see the warning this emits when it
|
|
860
|
-
* detects the latter without one.
|
|
861
|
-
*/
|
|
862
|
-
bidi?: BidiResolver;
|
|
863
|
-
/**
|
|
864
|
-
* Reading direction: the base direction of the bidi analysis, and what
|
|
865
|
-
* `start` / `end` resolve against. Default `'auto'`, each paragraph's own
|
|
866
|
-
* first strong character, which only an engine can find: with none, `'auto'`
|
|
867
|
-
* reads left to right.
|
|
868
|
-
*/
|
|
869
|
-
direction?: TextDirection | 'auto';
|
|
870
|
-
/**
|
|
871
|
-
* Distance between tab stops, in spaces of the tab's own run (its advance
|
|
872
|
-
* plus the run's tracking), as CSS `tab-size` counts it. A tab advances to
|
|
873
|
-
* the next stop from the start of its line. Default 8.
|
|
874
|
-
*/
|
|
875
|
-
tabSize?: number;
|
|
876
|
-
/**
|
|
877
|
-
* World-space `fontSize` at or above which glyphs are emitted as outline
|
|
878
|
-
* geometry, when the resolved face has outlines registered. Omit (the
|
|
879
|
-
* default) to keep every glyph on its SDF tier.
|
|
880
|
-
*
|
|
881
|
-
* A *world* size rather than a screen size because layout knows nothing
|
|
882
|
-
* about the view; `drawText` divides its screen-pixel threshold by the view
|
|
883
|
-
* scale before calling, so zooming in lowers the world size that qualifies.
|
|
884
|
-
*
|
|
885
|
-
* This is a rendering switch only. Advances, kerning, wrapping and
|
|
886
|
-
* baselines are identical either way — the outline tier changes what a
|
|
887
|
-
* glyph looks like, never where it sits — so measurement callers
|
|
888
|
-
* (`measureTextBounds`, `textLineBoxes`) leave it unset and still agree
|
|
889
|
-
* with the paint, and crossing the threshold cannot reflow text.
|
|
890
|
-
*
|
|
891
|
-
* Ignored for a family that resolved to the outline tier because it has no
|
|
892
|
-
* atlas: there the geometry is not an upgrade over another rendering, it is
|
|
893
|
-
* the only one, so the threshold has nothing to choose between.
|
|
894
|
-
*/
|
|
895
|
-
outlineMinSize?: number;
|
|
896
|
-
}
|
|
897
724
|
/**
|
|
898
|
-
* Lay out `runs` into
|
|
899
|
-
*
|
|
725
|
+
* Lay out `runs` into lines of placed glyphs. Wrapping, baselines and tracking
|
|
726
|
+
* follow the rules in this file's module doc.
|
|
900
727
|
*/
|
|
901
728
|
declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts): LaidOutRuns;
|
|
902
729
|
|
|
@@ -906,11 +733,10 @@ declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts):
|
|
|
906
733
|
* behind picking, and caret hit-testing all answer from this.
|
|
907
734
|
*
|
|
908
735
|
* `layoutRuns` is the most expensive derivation in the kit — it walks every
|
|
909
|
-
* codepoint, resolves a face per run, measures, wraps, aligns, and places
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
* 25.9 for 200 wrapped paragraphs.
|
|
913
|
-
* budget spent before a single triangle is drawn.
|
|
736
|
+
* codepoint, resolves a face per run, measures, wraps, aligns, and places
|
|
737
|
+
* every glyph — and `drawText` ran it per text command per frame. Measured,
|
|
738
|
+
* when it also built the draw groups: 2.0 ms/frame for 200 short labels, 9.3
|
|
739
|
+
* for 1000, and 25.9 for 200 wrapped paragraphs.
|
|
914
740
|
*
|
|
915
741
|
* ### Two keys, tried in order
|
|
916
742
|
*
|
|
@@ -928,30 +754,23 @@ declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts):
|
|
|
928
754
|
* second: an identity hit never pays for it.
|
|
929
755
|
*
|
|
930
756
|
* Under either, one entry per distinct `(maxWidth, alignWidth, lineHeight,
|
|
931
|
-
* align,
|
|
932
|
-
* origin-relative geometry and `drawText` translates at
|
|
933
|
-
* dragged across the page keeps hitting the same entry.
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
* `outlineMinSize` is derived from the view scale, so recording it literally
|
|
938
|
-
* would miss on every frame of a zoom. It reaches `layoutRuns` through exactly
|
|
939
|
-
* one comparison (`run.fontSize < min`, in `outlineFor`), so what the layout
|
|
940
|
-
* actually depends on is *which runs clear the bar* — and since the test is a
|
|
941
|
-
* plain `>=` on size, that set is pinned by how many of the distinct run sizes
|
|
942
|
-
* clear it. Recording that count is exact, not a quantization: the entry stays
|
|
943
|
-
* valid across every zoom that doesn't cross a glyph size, and is dropped the
|
|
944
|
-
* moment one does.
|
|
757
|
+
* align, direction, bidi engine, tab size)`. Position is deliberately absent:
|
|
758
|
+
* `layoutRuns` emits origin-relative geometry and `drawText` translates at
|
|
759
|
+
* upload, so a text node dragged across the page keeps hitting the same entry.
|
|
760
|
+
* So is everything that only changes what is drawn — a run's fill, stroke and
|
|
761
|
+
* decorations, the outline threshold — which `cachedPaintRuns` keys on
|
|
762
|
+
* instead. Two runs arrays that differ only there share one layout.
|
|
945
763
|
*
|
|
946
764
|
* ### What the keys cannot see
|
|
947
765
|
*
|
|
948
766
|
* The font set. A face landing changes metrics with no change to the runs, so
|
|
949
|
-
* every lookup compares `
|
|
950
|
-
*
|
|
951
|
-
* everything when it moves.
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
*
|
|
767
|
+
* every lookup compares `faceGeneration()` — advanced by a registration, a
|
|
768
|
+
* load, a fallback policy, and the dynamic atlas measuring a face again or
|
|
769
|
+
* emptying its pages — and drops everything when it moves. A deferred bake
|
|
770
|
+
* landing does not advance it: that fills in a glyph record the layout
|
|
771
|
+
* already holds, and moves no pen. Polled rather than subscribed: a
|
|
772
|
+
* module-load subscription is a cross-package side effect that makes importing
|
|
773
|
+
* this package require the font package's whole surface.
|
|
955
774
|
*
|
|
956
775
|
* ### Bounds
|
|
957
776
|
*
|
|
@@ -981,4 +800,25 @@ declare function cachedLayoutRuns(runs: readonly ResolvedRun[], opts: LayoutRuns
|
|
|
981
800
|
/** Test helper. Do not call from product code. */
|
|
982
801
|
declare function _resetLayoutCacheForTests(): void;
|
|
983
802
|
|
|
984
|
-
|
|
803
|
+
/**
|
|
804
|
+
* Where the bidi engine arrives. This package cannot import one (see
|
|
805
|
+
* `bidiSeam.ts`), and most callers of `layoutRuns` are kit code a consumer
|
|
806
|
+
* never touches, so the consumer registers it once and every layout finds it.
|
|
807
|
+
*/
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Give every text layout a bidi engine: `registerBidi(bidi)`, with `bidi`
|
|
811
|
+
* from `@weasel-js/bidi`. `layoutRuns` uses it whenever its options carry
|
|
812
|
+
* none. Pass `null`, or call the function returned, to take it out again.
|
|
813
|
+
*/
|
|
814
|
+
declare function registerBidi(engine: BidiResolver | null): () => void;
|
|
815
|
+
/**
|
|
816
|
+
* The direction `text`'s first paragraph reads in: `direction` when it states
|
|
817
|
+
* one, otherwise its first strong character's. Finding that takes an engine,
|
|
818
|
+
* so with none registered the answer is `'ltr'`.
|
|
819
|
+
*/
|
|
820
|
+
declare function paragraphDirection(text: string, direction?: TextDirection | 'auto', engine?: BidiResolver | null): TextDirection;
|
|
821
|
+
/** Test helper. Do not call from product code. */
|
|
822
|
+
declare function _resetBidiWarningForTests(): void;
|
|
823
|
+
|
|
824
|
+
export { _resetLayoutCacheForTests as $, markdownToRuns as A, type BidiAnalysis as B, numericWeight as C, DEFAULT_TEXT_STYLE as D, paragraphDirection as E, type FontVariantCaps as F, registerBidi as G, resolveAlign as H, resolveRunFace as I, resolveRuns as J, resolveTextStyle as K, type LaidOutRuns as L, MARKDOWN_RUN_GRAMMAR as M, runsToMarkdown as N, runsToPlainText as O, type PlacedGlyph as P, scriptMetrics as Q, type ResolvedTextStyle as R, type StyledRun as S, type TextStyle as T, scriptMetricsFor as U, smallCapsScale as V, smallCapsScaleFor as W, smallCapsText as X, toRuns as Y, transformRunTexts as Z, _resetBidiWarningForTests as _, type ResolvedRun as a, type LayoutRunsOpts as b, type TextPaint as c, type BidiReordering as d, type BidiResolver as e, LAYOUT_CACHE_STRUCTURAL_LIMIT as f, LAYOUT_CACHE_VARIANT_LIMIT as g, type LaidOutCell as h, type LaidOutLineBox as i, type RunFlag as j, type RunGrammar as k, type RunMarker as l, type RunSourceMap as m, SCRIPT_METRICS as n, SMALL_CAPS_SCALE as o, type ScriptPreset as p, type SmallCapsText as q, type TextAlign as r, type TextDirection as s, type TextTransform as t, type TransformedRunText as u, cachedLayoutRuns as v, fontString as w, isBoldWeight as x, isSmallCapsLetter as y, layoutRuns as z };
|