@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.
@@ -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; richer weight axes
55
- * (300/500/900) are out of scope for slice 1.
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 in
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. Same five values as CSS `text-align`, with
176
- * the same split between the relative pair and the absolute pair.
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 between words where they would pass the box width. Default
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, as fractions of the
374
- * inherited font size: `size` scales it, `shift` raises (positive) or lowers
375
- * (negative) the baseline.
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 — chosen because a drawing tool's users have those
379
- * numbers in their fingers already. They are not read from the font: the
380
- * `OS/2` table carries real `ySuperscript*` / `ySubscript*` metrics, but the
381
- * baked atlas tier has no slot for them (see `layoutRuns`'s note on the
382
- * decoration constants, which are derived for the same reason), and metrics
383
- * that applied on one glyph tier and not the other would reflow text as it
384
- * crossed the size threshold.
385
- *
386
- * Exported so a consumer building a character panel can show the percentages
387
- * it is about to apply. Override either half per run with `baselineShift` /
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 const SCRIPT_METRICS: Readonly<Record<'super' | 'sub', Readonly<{
391
- size: number;
392
- shift: number;
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 character of that run, including the
443
- * last one on a line — the CSS `letter-spacing` rule, chosen so a DOM overlay
444
- * rendering the same text can be made to agree. Trailing tracking therefore
445
- * widens the measured line width and counts toward wrapping. Spaces are
446
- * tracked like any other character; a newline is not (it consumes no advance).
447
- * One caveat against CSS: tracking is applied per *code point*, not per
448
- * grapheme cluster, so `e` + U+0301 takes tracking twice where CSS would
449
- * space the cluster once.
450
- *
451
- * Word wrap is applied when `maxWidth` is finite: words are committed to
452
- * a new line when they would exceed the current line width. Forced line
453
- * breaks are emitted for `\n` codepoints. Every run on a line shares one
454
- * baseline, sunk to clear the tallest run's ascent, so mixing sizes or faces
455
- * aligns them the way inline text aligns everywhere else; line height is
456
- * `max(fontSize * lineHeight)` across the line.
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 five values.
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 { resolveAlign as A, type BidiAnalysis as B, resolveRuns as C, DEFAULT_TEXT_STYLE as D, resolveTextStyle as E, runsToMarkdown as F, runsToPlainText as G, toRuns as H, transformRunTexts as I, type LaidOutRuns as L, MARKDOWN_RUN_GRAMMAR as M, type ResolvedTextStyle as R, type StyledRun as S, type TextStyle as T, _resetLayoutCacheForTests as _, type ResolvedRun as a, type LayoutRunsOpts as b, type BidiReordering as c, type BidiResolver as d, LAYOUT_CACHE_STRUCTURAL_LIMIT as e, LAYOUT_CACHE_VARIANT_LIMIT as f, type LaidOutCell as g, type LaidOutDecoration as h, type LaidOutGroup as i, type LaidOutLineBox as j, type LaidOutOutlineGlyph as k, type LaidOutQuad as l, type RunFlag as m, type RunGrammar as n, type RunMarker as o, type RunSourceMap as p, SCRIPT_METRICS as q, type TextAlign as r, type TextDirection as s, type TextPaint as t, type TextTransform as u, type TransformedRunText as v, cachedLayoutRuns as w, fontString as x, layoutRuns as y, markdownToRuns as z };
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 };
@@ -1,3 +1,3 @@
1
- export { _ as _resetLayoutCacheForTests } from './test-seams-CeRWeyMm.js';
1
+ export { a2 as _resetLayoutCacheForTests } from './test-seams-DbGu8K5F.js';
2
2
  import '@weasel-js/paint';
3
3
  import '@weasel-js/font';
@@ -1,3 +1,3 @@
1
- export { _resetLayoutCacheForTests } from './chunk-GNAAPRO5.js';
1
+ export { _resetLayoutCacheForTests } from './chunk-JQPOFIGT.js';
2
2
  //# sourceMappingURL=test-seams.js.map
3
3
  //# sourceMappingURL=test-seams.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/text",
3
- "version": "1.6.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.6.1",
24
- "@weasel-js/paint": "1.6.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.6.1"
53
+ "@weasel-js/bidi": "1.7.1"
54
54
  },
55
55
  "peerDependencies": {
56
- "@weasel-js/font": "1.6.1"
56
+ "@weasel-js/font": "1.7.1"
57
57
  }
58
58
  }