@flighthq/bitmaptext 0.2.1-next.841.373388f → 0.3.0-next.1032.e2b99fc

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,13 +1,12 @@
1
- import type { BitmapText, BitmapTextAlign, BitmapTextData, BitmapTextOptions, BitmapTextRuntime, GlyphSource, QuadBatch, Rectangle } from '@flighthq/types';
1
+ import type { BitmapText, BitmapTextAlign, BitmapTextData, BitmapTextOptions, BitmapTextPage, BitmapTextRuntime, GlyphSource, Rectangle } from '@flighthq/types/contract';
2
2
  export declare function computeBitmapTextLocalBoundsRectangle(out: Rectangle, source: Readonly<BitmapText>): void;
3
3
  export declare function createBitmapText(glyphSource: GlyphSource | null, options?: Readonly<BitmapTextOptions>): BitmapText;
4
4
  export declare function createBitmapTextData(data?: Readonly<Partial<BitmapTextData>>): BitmapTextData;
5
5
  export declare function createBitmapTextRuntime(): BitmapTextRuntime;
6
6
  export declare function getBitmapTextBounds(source: Readonly<BitmapText>): Rectangle;
7
- export declare function getBitmapTextQuadBatches(source: Readonly<BitmapText>): QuadBatch[];
7
+ export declare function getBitmapTextPages(source: Readonly<BitmapText>): readonly BitmapTextPage[];
8
8
  export declare function reserveBitmapText(target: BitmapText, glyphCapacity: number): void;
9
9
  export declare function setBitmapTextAlign(target: BitmapText, align: BitmapTextAlign): void;
10
- export declare function setBitmapTextColor(target: BitmapText, color: number): void;
11
10
  export declare function setBitmapTextGlyphSource(target: BitmapText, glyphSource: GlyphSource | null): void;
12
11
  export declare function setBitmapTextLetterSpacing(target: BitmapText, letterSpacing: number): void;
13
12
  export declare function setBitmapTextLineHeight(target: BitmapText, lineHeight: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"bitmapText.d.ts","sourceRoot":"","sources":["../src/bitmapText.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EAGX,SAAS,EACT,SAAS,EACV,MAAM,iBAAiB,CAAC;AAQzB,wBAAgB,qCAAqC,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAWxG;AAQD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAenH;AAED,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAU7F;AAED,wBAAgB,uBAAuB,IAAI,iBAAiB,CAK3D;AAID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,CAI3E;AAID,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,EAAE,CAElF;AAKD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAGjF;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAEnF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE1E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAElG;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAE1F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAEpF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAExE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEzF"}
1
+ {"version":3,"file":"bitmapText.d.ts","sourceRoot":"","sources":["../src/bitmapText.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,WAAW,EAGX,SAAS,EACV,MAAM,0BAA0B,CAAC;AASlC,wBAAgB,qCAAqC,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAWxG;AASD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAanH;AAED,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAS7F;AAED,wBAAgB,uBAAuB,IAAI,iBAAiB,CAK3D;AAID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,CAI3E;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,cAAc,EAAE,CAE1F;AAKD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAMjF;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAEnF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAElG;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAE1F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAEpF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAExE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEzF"}
@@ -1,11 +1,10 @@
1
- import { copyRectangle, createRectangle } from '@flighthq/geometry';
2
- import { addNodeChild } from '@flighthq/node';
3
- import { createNode2D, createNode2DRuntime, getNode2DRuntime } from '@flighthq/scene2d';
4
- import { createQuadBatch, reserveQuadBatch } from '@flighthq/sprite';
5
- import { createTextureAtlas } from '@flighthq/textureatlas';
6
- import { BitmapTextKind } from '@flighthq/types';
7
- // White (`0xRRGGBBAA` all-ones) — the untinted default; the backing batch stays material-free at this value.
8
- const BITMAP_TEXT_DEFAULT_COLOR = 0xffffffff;
1
+ import { copyRectangle, createRectangle, reserveFloat32Array, reserveUint16Array } from '@flighthq/geometry/contract';
2
+ import { createNode2D, createNode2DRuntime, getNode2DRuntime } from '@flighthq/scene2d/contract';
3
+ import { createTextureAtlas } from '@flighthq/textureatlas/contract';
4
+ import { BitmapTextKind } from '@flighthq/types/contract';
5
+ // Two floats (x, y) per glyph quad — the vector2 (translation-only) transform stride the BitmapText
6
+ // renderer reads. Kept internal so callers never hand-write i*2.
7
+ const BITMAP_TEXT_TRANSFORM_STRIDE = 2;
9
8
  // Writes the laid-out text extent (cached by `updateBitmapText`) into `out`, or a zero rectangle when
10
9
  // the text has not been laid out yet. Alias-safe: `out` may be the cached rectangle.
11
10
  export function computeBitmapTextLocalBoundsRectangle(out, source) {
@@ -21,27 +20,25 @@ export function computeBitmapTextLocalBoundsRectangle(out, source) {
21
20
  copyRectangle(out, bounds);
22
21
  }
23
22
  // Allocates a BitmapText display node bound to `glyphSource` for both layout AND pixels. The
24
- // `GlyphSource` seam now pairs its glyph geometry (rects, advances, kerning, metrics) with the
25
- // backing atlas image(s) those rects sample (`getGlyphAtlasImage(page)`), so no separate image is
26
- // supplied. The node owns one backing QuadBatch child per glyph-atlas page; a single-page source
27
- // yields exactly one (page 0), created eagerly here. Call `updateBitmapText` to lay out the current
28
- // `text`, which sets each page batch's atlas image and grows the set for a multi-page source.
23
+ // `GlyphSource` seam pairs its glyph geometry (rects, advances, kerning, metrics) with the backing atlas
24
+ // image(s) those rects sample (`getGlyphAtlasImage(page)`), so no separate image is supplied. The node
25
+ // owns one `BitmapTextPage` per glyph-atlas page a single-page source yields exactly one (page 0),
26
+ // created eagerly here and draws them itself through the registered BitmapText renderer. Call
27
+ // `updateBitmapText` to lay out the current `text`, which binds each page's atlas image and grows the set
28
+ // for a multi-page source.
29
29
  export function createBitmapText(glyphSource, options) {
30
30
  const bitmapText = createNode2D(BitmapTextKind, undefined, createBitmapTextData, createBitmapTextRuntime);
31
31
  const data = bitmapText.data;
32
32
  data.glyphSource = glyphSource;
33
33
  if (options !== undefined)
34
34
  applyBitmapTextOptions(data, options);
35
- const quadBatch = createQuadBatch({ data: { atlas: createTextureAtlas() } });
36
35
  const runtime = getNode2DRuntime(bitmapText);
37
- runtime.quadBatches.push(quadBatch);
38
- addNodeChild(bitmapText, quadBatch);
36
+ runtime.pages.push(createBitmapTextPage());
39
37
  return bitmapText;
40
38
  }
41
39
  export function createBitmapTextData(data) {
42
40
  return {
43
41
  align: data?.align ?? 'left',
44
- color: data?.color ?? BITMAP_TEXT_DEFAULT_COLOR,
45
42
  glyphSource: data?.glyphSource ?? null,
46
43
  letterSpacing: data?.letterSpacing ?? 0,
47
44
  lineHeight: data?.lineHeight ?? 1,
@@ -52,7 +49,7 @@ export function createBitmapTextData(data) {
52
49
  export function createBitmapTextRuntime() {
53
50
  const runtime = createNode2DRuntime(defaultMethods);
54
51
  runtime.localBoundsRectangle = null;
55
- runtime.quadBatches = [];
52
+ runtime.pages = [];
56
53
  return runtime;
57
54
  }
58
55
  // Allocates a fresh Rectangle holding the laid-out text extent. Use
@@ -62,26 +59,25 @@ export function getBitmapTextBounds(source) {
62
59
  computeBitmapTextLocalBoundsRectangle(out, source);
63
60
  return out;
64
61
  }
65
- // The backing QuadBatches the node lays glyph quads into the renderable children, one per
66
- // glyph-atlas page in page order. A single-page source yields exactly one; empty before construction.
67
- export function getBitmapTextQuadBatches(source) {
68
- return getNode2DRuntime(source).quadBatches;
62
+ // The glyph-quad pages the node draws — one per glyph-atlas page in page order. A single-page source
63
+ // yields exactly one; the array is never empty after construction.
64
+ export function getBitmapTextPages(source) {
65
+ return getNode2DRuntime(source).pages;
69
66
  }
70
- // Grows each backing page QuadBatch to hold at least `glyphCapacity` glyph quads without reallocating
71
- // during layout. Optional — `updateBitmapText` auto-grows — but avoids incremental reallocation for
72
- // large strings. Reserving every page's batch over-allocates for multi-page text but never under-sizes.
67
+ // Grows each page's quad arrays to hold at least `glyphCapacity` glyph quads without reallocating during
68
+ // layout. Optional — `updateBitmapText` auto-grows — but avoids incremental reallocation for large
69
+ // strings. Reserving every page over-allocates for multi-page text but never under-sizes.
73
70
  export function reserveBitmapText(target, glyphCapacity) {
74
71
  const runtime = getNode2DRuntime(target);
75
- for (const quadBatch of runtime.quadBatches)
76
- reserveQuadBatch(quadBatch, glyphCapacity);
72
+ for (const page of runtime.pages) {
73
+ page.ids = reserveUint16Array(page.ids, glyphCapacity);
74
+ page.transforms = reserveFloat32Array(page.transforms, glyphCapacity * BITMAP_TEXT_TRANSFORM_STRIDE);
75
+ }
77
76
  }
78
- // The setters below mutate node data only; call `updateBitmapText` afterward to re-lay-out the batch.
77
+ // The setters below mutate node data only; call `updateBitmapText` afterward to re-lay-out the pages.
79
78
  export function setBitmapTextAlign(target, align) {
80
79
  target.data.align = align;
81
80
  }
82
- export function setBitmapTextColor(target, color) {
83
- target.data.color = color;
84
- }
85
81
  export function setBitmapTextGlyphSource(target, glyphSource) {
86
82
  target.data.glyphSource = glyphSource;
87
83
  }
@@ -100,8 +96,6 @@ export function setBitmapTextWrapWidth(target, wrapWidth) {
100
96
  function applyBitmapTextOptions(data, options) {
101
97
  if (options.align !== undefined)
102
98
  data.align = options.align;
103
- if (options.color !== undefined)
104
- data.color = options.color;
105
99
  if (options.letterSpacing !== undefined)
106
100
  data.letterSpacing = options.letterSpacing;
107
101
  if (options.lineHeight !== undefined)
@@ -116,6 +110,10 @@ function copyLocalBoundsRectangle(out, source) {
116
110
  if (runtime.localBoundsRectangle !== null)
117
111
  copyRectangle(out, runtime.localBoundsRectangle);
118
112
  }
113
+ // Allocates an empty page bound to a fresh atlas. Its image and regions are set by `updateBitmapText`.
114
+ function createBitmapTextPage() {
115
+ return { atlas: createTextureAtlas(), ids: new Uint16Array(), instanceCount: 0, transforms: new Float32Array() };
116
+ }
119
117
  const defaultMethods = {
120
118
  computeLocalBoundsRectangle: copyLocalBoundsRectangle,
121
119
  };
@@ -1 +1 @@
1
- {"version":3,"file":"bitmapText.js","sourceRoot":"","sources":["../src/bitmapText.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitmapText.js","sourceRoot":"","sources":["../src/bitmapText.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './bitmapText';
2
+ export * from './updateBitmapText';
3
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './bitmapText';
2
+ export * from './updateBitmapText';
3
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export * from './bitmapText';
2
- export * from './updateBitmapText';
1
+ export { computeBitmapTextLocalBoundsRectangle, createBitmapText, getBitmapTextBounds, getBitmapTextPages, reserveBitmapText, setBitmapTextAlign, setBitmapTextGlyphSource, setBitmapTextLetterSpacing, setBitmapTextLineHeight, setBitmapTextText, setBitmapTextWrapWidth, updateBitmapText, } from './contract';
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qCAAqC,EACrC,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
- export * from './bitmapText';
2
- export * from './updateBitmapText';
1
+ export { computeBitmapTextLocalBoundsRectangle, createBitmapText, getBitmapTextBounds, getBitmapTextPages, reserveBitmapText, setBitmapTextAlign, setBitmapTextGlyphSource, setBitmapTextLetterSpacing, setBitmapTextLineHeight, setBitmapTextText, setBitmapTextWrapWidth, updateBitmapText, } from './contract';
3
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qCAAqC,EACrC,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
@@ -1,3 +1,3 @@
1
- import type { BitmapText } from '@flighthq/types';
1
+ import type { BitmapText } from '@flighthq/types/contract';
2
2
  export declare function updateBitmapText(bitmapText: BitmapText): void;
3
3
  //# sourceMappingURL=updateBitmapText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateBitmapText.d.ts","sourceRoot":"","sources":["../src/updateBitmapText.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,UAAU,EAQX,MAAM,iBAAiB,CAAC;AAiBzB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CA4E7D"}
1
+ {"version":3,"file":"updateBitmapText.d.ts","sourceRoot":"","sources":["../src/updateBitmapText.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,UAAU,EAOX,MAAM,0BAA0B,CAAC;AAgBlC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CA2E7D"}
@@ -1,35 +1,30 @@
1
- import { createColorTransformAdjustment } from '@flighthq/adjustments';
2
- import { createRectangle } from '@flighthq/geometry';
3
- import { createColorTransform } from '@flighthq/materials';
4
- import { addNodeChild, invalidateNodeLocalBounds } from '@flighthq/node';
5
- import { getNode2DRuntime, setNode2DColorAdjustments } from '@flighthq/scene2d';
6
- import { appendQuadBatchInstance, clearQuadBatch, createQuadBatch } from '@flighthq/sprite';
7
- import { addTextureAtlasRegion, createTextureAtlas } from '@flighthq/textureatlas';
8
- // White (`0xRRGGBBAA` all-ones) leaves the backing batch material-free — the untinted path.
9
- const BITMAP_TEXT_DEFAULT_COLOR = 0xffffffff;
1
+ import { createRectangle, reserveFloat32Array, reserveUint16Array } from '@flighthq/geometry/contract';
2
+ import { invalidateNodeLocalBounds } from '@flighthq/node/contract';
3
+ import { getNode2DRuntime } from '@flighthq/scene2d/contract';
4
+ import { createTexture, setTextureImage } from '@flighthq/texture/contract';
5
+ import { addTextureAtlasRegion, createTextureAtlas } from '@flighthq/textureatlas/contract';
6
+ const BITMAP_TEXT_TRANSFORM_STRIDE = 2;
10
7
  const CARRIAGE_RETURN = 0x0d;
11
8
  const SPACE = 0x20;
12
- // Lays out `bitmapText`'s current string and rewrites its backing QuadBatches: one quad per visible
13
- // glyph, partitioned by the glyph's atlas page into one QuadBatch per page, positioned by the glyph
14
- // source's advances and kerning, broken on explicit newlines and (when `wrapWidth` is set) at word
15
- // boundaries, stacked by the metric line advance, and aligned per line. Each page batch's atlas image
16
- // is bound from `getGlyphAtlasImage(page)` and its regions rebuilt from that page's encountered glyph
17
- // rects each call, so a dynamic glyph source whose rects shift between layouts stays correct. A
18
- // single-page source produces exactly one batch (page 0). A page whose `getGlyphAtlasImage` returns
19
- // null cannot be sampled, so its glyphs are skipped. Missing glyphs (`getGlyphEntry` → null) are
20
- // omitted entirely no quad and no advance since a null entry carries no advance to honor. Bounds
21
- // span every drawn glyph across all pages.
9
+ // Lays out `bitmapText`'s current string and rewrites its `BitmapTextPage` quads: one quad per visible
10
+ // glyph, partitioned by the glyph's atlas page into one page's quads, positioned by the glyph source's
11
+ // advances and kerning, broken on explicit newlines and (when `wrapWidth` is set) at word boundaries,
12
+ // stacked by the metric line advance, and aligned per line. Each page's atlas Texture is bound from
13
+ // `getGlyphAtlasImage(page)` and its regions rebuilt from that page's encountered glyph rects each call,
14
+ // so a dynamic glyph source whose rects shift between layouts stays correct. A single-page source produces
15
+ // exactly one page (page 0). A page whose `getGlyphAtlasImage` returns null cannot be sampled, so its
16
+ // glyphs are skipped. Missing glyphs (`getGlyphEntry` → null) are omitted entirely — no quad and no
17
+ // advance. Bounds span every drawn glyph across all pages. Tint is the node's own color-adjustment stack,
18
+ // not touched here.
22
19
  export function updateBitmapText(bitmapText) {
23
20
  const data = bitmapText.data;
24
21
  const runtime = getNode2DRuntime(bitmapText);
25
22
  const bounds = ensureBoundsRectangle(runtime);
26
- // Clear and recolor every existing page batch; pages with glyphs this layout are refilled below,
27
- // pages that fall silent stay as empty children drawing nothing.
28
- for (const quadBatch of runtime.quadBatches) {
29
- clearQuadBatch(quadBatch);
30
- if (quadBatch.data.atlas !== null)
31
- quadBatch.data.atlas.regions.length = 0;
32
- applyBitmapTextColor(quadBatch, data.color);
23
+ // Clear every existing page; pages with glyphs this layout are refilled below, pages that fall silent
24
+ // stay as empty pages drawing nothing.
25
+ for (const page of runtime.pages) {
26
+ page.instanceCount = 0;
27
+ page.atlas.regions.length = 0;
33
28
  }
34
29
  const glyphSource = data.glyphSource;
35
30
  if (glyphSource === null || data.text.length === 0) {
@@ -65,18 +60,18 @@ export function updateBitmapText(bitmapText) {
65
60
  const word = line.words[wi];
66
61
  for (const glyph of word.glyphs) {
67
62
  const entry = glyph.entry;
68
- const page = ensureBitmapTextPageBatch(bitmapText, runtime, glyphSource, data.color, pages, entry.page);
69
- if (page === null)
63
+ const context = ensureBitmapTextPage(runtime, glyphSource, pages, entry.page);
64
+ if (context === null)
70
65
  continue;
71
66
  const quadX = penX + glyph.penWithinWord + entry.bearingX;
72
67
  const quadY = baselineY - entry.bearingY;
73
- let regionId = page.regionByCodepoint.get(glyph.codepoint);
68
+ let regionId = context.regionByCodepoint.get(glyph.codepoint);
74
69
  if (regionId === undefined) {
75
- addTextureAtlasRegion(page.atlas, entry.x, entry.y, entry.width, entry.height);
76
- regionId = page.atlas.regions.length - 1;
77
- page.regionByCodepoint.set(glyph.codepoint, regionId);
70
+ addTextureAtlasRegion(context.page.atlas, entry.x, entry.y, entry.width, entry.height);
71
+ regionId = context.page.atlas.regions.length - 1;
72
+ context.regionByCodepoint.set(glyph.codepoint, regionId);
78
73
  }
79
- appendQuadBatchInstance(page.quadBatch, regionId, quadX, quadY);
74
+ appendBitmapTextPageQuad(context.page, regionId, quadX, quadY);
80
75
  if (quadX < minX)
81
76
  minX = quadX;
82
77
  if (quadY < minY)
@@ -100,22 +95,21 @@ export function updateBitmapText(bitmapText) {
100
95
  }
101
96
  invalidateNodeLocalBounds(bitmapText);
102
97
  }
103
- // Sets (or clears) the backing batch's node-level color transform from a packed-RGBA color, as a
104
- // single-entry color-adjustment stack on the batch's runtime slot. White clears it. Every glyph of the
105
- // batch shares this one tint (whole-batch, not per-glyph), so it resolves to one value and folds into the
106
- // glyph draw as a single whole-batch color-transform uniform.
107
- function applyBitmapTextColor(quadBatch, color) {
108
- if (color === BITMAP_TEXT_DEFAULT_COLOR) {
109
- setNode2DColorAdjustments(quadBatch, null);
110
- return;
98
+ // Appends one glyph quad (region id + vector2 pen position) to `page`, auto-growing its arrays. The
99
+ // page-local twin of `appendQuadBatchInstance`, over plain owned arrays rather than a QuadBatch node.
100
+ function appendBitmapTextPageQuad(page, id, x, y) {
101
+ const index = page.instanceCount;
102
+ const capacity = Math.min(page.ids.length, (page.transforms.length / BITMAP_TEXT_TRANSFORM_STRIDE) | 0);
103
+ if (index >= capacity) {
104
+ const next = Math.max(index + 1, capacity * 2, 8);
105
+ page.ids = reserveUint16Array(page.ids, next);
106
+ page.transforms = reserveFloat32Array(page.transforms, next * BITMAP_TEXT_TRANSFORM_STRIDE);
111
107
  }
112
- const colorTransform = createColorTransform({
113
- redMultiplier: ((color >>> 24) & 0xff) / 255,
114
- greenMultiplier: ((color >>> 16) & 0xff) / 255,
115
- blueMultiplier: ((color >>> 8) & 0xff) / 255,
116
- alphaMultiplier: (color & 0xff) / 255,
117
- });
118
- setNode2DColorAdjustments(quadBatch, [createColorTransformAdjustment(colorTransform)]);
108
+ page.ids[index] = id;
109
+ const o = index * BITMAP_TEXT_TRANSFORM_STRIDE;
110
+ page.transforms[o] = x;
111
+ page.transforms[o + 1] = y;
112
+ page.instanceCount = index + 1;
119
113
  }
120
114
  // Measures one paragraph (a newline-free run) into words separated by whitespace gaps. Intra-word
121
115
  // kerning and letter spacing are baked into each glyph's `penWithinWord` and the word width; kerning
@@ -161,30 +155,34 @@ function buildBitmapTextWords(glyphSource, paragraph, letterSpacing) {
161
155
  flush();
162
156
  return tokens;
163
157
  }
164
- // Ensures a backing QuadBatch exists for glyph-atlas `page` (page-indexed in `runtime.quadBatches`,
165
- // growing and parenting fresh batches as needed) and binds it to that page's atlas image, returning
166
- // the per-layout page context (batch + atlas + region cache). Returns null when the page has no atlas
167
- // image to sample — its glyphs are then skipped. Newly grown gap pages get an empty batch bound to
168
- // their own image; the common single-page source touches only page 0 (created by `createBitmapText`).
169
- function ensureBitmapTextPageBatch(bitmapText, runtime, glyphSource, color, pages, page) {
158
+ // Ensures a `BitmapTextPage` exists for glyph-atlas `page` (page-indexed in `runtime.pages`, growing fresh
159
+ // pages as needed) and binds it to that page's atlas image, returning the per-layout page context (page +
160
+ // region cache). Returns null when the page has no atlas image to sample — its glyphs are then skipped.
161
+ function ensureBitmapTextPage(runtime, glyphSource, pages, page) {
170
162
  const cached = pages.get(page);
171
163
  if (cached !== undefined)
172
164
  return cached;
173
165
  const image = glyphSource.getGlyphAtlasImage(page);
174
166
  if (image === null)
175
167
  return null;
176
- while (runtime.quadBatches.length <= page) {
177
- const created = createQuadBatch({ data: { atlas: createTextureAtlas() } });
178
- applyBitmapTextColor(created, color);
179
- runtime.quadBatches.push(created);
180
- addNodeChild(bitmapText, created);
168
+ while (runtime.pages.length <= page) {
169
+ runtime.pages.push({
170
+ atlas: createTextureAtlas(),
171
+ ids: new Uint16Array(),
172
+ instanceCount: 0,
173
+ transforms: new Float32Array(),
174
+ });
175
+ }
176
+ const pageData = runtime.pages[page];
177
+ if (pageData.atlas.texture === null) {
178
+ pageData.atlas.texture = createTexture({ storage: { dimension: '2d', image } });
179
+ }
180
+ else {
181
+ setTextureImage(pageData.atlas.texture, image);
181
182
  }
182
- const quadBatch = runtime.quadBatches[page];
183
- const atlas = quadBatch.data.atlas;
184
- atlas.image = image;
185
- const pageBatch = { atlas, quadBatch, regionByCodepoint: new Map() };
186
- pages.set(page, pageBatch);
187
- return pageBatch;
183
+ const context = { page: pageData, regionByCodepoint: new Map() };
184
+ pages.set(page, context);
185
+ return context;
188
186
  }
189
187
  function ensureBoundsRectangle(runtime) {
190
188
  if (runtime.localBoundsRectangle === null)
@@ -1 +1 @@
1
- {"version":3,"file":"updateBitmapText.js","sourceRoot":"","sources":["../src/updateBitmapText.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"updateBitmapText.js","sourceRoot":"","sources":["../src/updateBitmapText.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/bitmaptext",
3
- "version": "0.2.1-next.841.373388f",
3
+ "version": "0.3.0-next.1032.e2b99fc",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -13,6 +13,10 @@
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
15
  "default": "./dist/index.js"
16
+ },
17
+ "./contract": {
18
+ "types": "./dist/contract.d.ts",
19
+ "default": "./dist/contract.js"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -32,14 +36,12 @@
32
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
33
37
  },
34
38
  "dependencies": {
35
- "@flighthq/adjustments": "0.2.1-next.841.373388f",
36
- "@flighthq/scene2d": "0.2.1-next.841.373388f",
37
- "@flighthq/geometry": "0.2.1-next.841.373388f",
38
- "@flighthq/materials": "0.2.1-next.841.373388f",
39
- "@flighthq/node": "0.2.1-next.841.373388f",
40
- "@flighthq/sprite": "0.2.1-next.841.373388f",
41
- "@flighthq/textureatlas": "0.2.1-next.841.373388f",
42
- "@flighthq/types": "0.2.1-next.841.373388f"
39
+ "@flighthq/scene2d": "0.3.0-next.1032.e2b99fc",
40
+ "@flighthq/geometry": "0.3.0-next.1032.e2b99fc",
41
+ "@flighthq/node": "0.3.0-next.1032.e2b99fc",
42
+ "@flighthq/texture": "0.3.0-next.1032.e2b99fc",
43
+ "@flighthq/textureatlas": "0.3.0-next.1032.e2b99fc",
44
+ "@flighthq/types": "0.3.0-next.1032.e2b99fc"
43
45
  },
44
46
  "devDependencies": {
45
47
  "@flighthq/glyphatlas": "*",
@@ -1,8 +1,7 @@
1
- import { createRectangle } from '@flighthq/geometry';
2
- import { getNode2DRuntime } from '@flighthq/scene2d';
3
- import { getQuadBatchCapacity } from '@flighthq/sprite';
4
- import type { BitmapTextRuntime, GlyphEntry, GlyphSource, ImageResource } from '@flighthq/types';
5
- import { BitmapTextKind } from '@flighthq/types';
1
+ import { createRectangle } from '@flighthq/geometry/contract';
2
+ import { getNode2DRuntime } from '@flighthq/scene2d/contract';
3
+ import type { BitmapTextRuntime, GlyphEntry, GlyphSource, ImageResource } from '@flighthq/types/contract';
4
+ import { BitmapTextKind } from '@flighthq/types/contract';
6
5
  import { describe, expect, it } from 'vitest';
7
6
 
8
7
  import {
@@ -11,10 +10,9 @@ import {
11
10
  createBitmapTextData,
12
11
  createBitmapTextRuntime,
13
12
  getBitmapTextBounds,
14
- getBitmapTextQuadBatches,
13
+ getBitmapTextPages,
15
14
  reserveBitmapText,
16
15
  setBitmapTextAlign,
17
- setBitmapTextColor,
18
16
  setBitmapTextGlyphSource,
19
17
  setBitmapTextLetterSpacing,
20
18
  setBitmapTextLineHeight,
@@ -73,25 +71,23 @@ describe('computeBitmapTextLocalBoundsRectangle', () => {
73
71
  });
74
72
 
75
73
  describe('createBitmapText', () => {
76
- it('creates a BitmapText node with a backing QuadBatch child', () => {
74
+ it('creates a BitmapText leaf owning one page and no child nodes', () => {
77
75
  const text = createBitmapText(createTestGlyphSource());
78
76
  expect(text.kind).toBe(BitmapTextKind);
79
- const batches = getBitmapTextQuadBatches(text);
80
- expect(batches).toHaveLength(1);
81
- expect(getNode2DRuntime(text).children).toContain(batches[0]);
77
+ expect(getBitmapTextPages(text)).toHaveLength(1);
78
+ const children = getNode2DRuntime(text).children;
79
+ expect(children == null || children.length === 0).toBe(true);
82
80
  });
83
81
 
84
82
  it('applies construction options to node data', () => {
85
83
  const text = createBitmapText(createTestGlyphSource(), {
86
84
  align: 'center',
87
- color: 0xff0000ff,
88
85
  letterSpacing: 2,
89
86
  lineHeight: 1.5,
90
87
  text: 'Hi',
91
88
  wrapWidth: 120,
92
89
  });
93
90
  expect(text.data.align).toBe('center');
94
- expect(text.data.color).toBe(0xff0000ff);
95
91
  expect(text.data.letterSpacing).toBe(2);
96
92
  expect(text.data.lineHeight).toBe(1.5);
97
93
  expect(text.data.text).toBe('Hi');
@@ -106,10 +102,9 @@ describe('createBitmapText', () => {
106
102
  });
107
103
 
108
104
  describe('createBitmapTextData', () => {
109
- it('defaults to left-aligned white empty unwrapped text', () => {
105
+ it('defaults to left-aligned empty unwrapped text', () => {
110
106
  const data = createBitmapTextData();
111
107
  expect(data.align).toBe('left');
112
- expect(data.color).toBe(0xffffffff);
113
108
  expect(data.glyphSource).toBeNull();
114
109
  expect(data.letterSpacing).toBe(0);
115
110
  expect(data.lineHeight).toBe(1);
@@ -126,10 +121,10 @@ describe('createBitmapTextData', () => {
126
121
  });
127
122
 
128
123
  describe('createBitmapTextRuntime', () => {
129
- it('starts with null bounds and no page batches', () => {
124
+ it('starts with null bounds and no pages', () => {
130
125
  const runtime = createBitmapTextRuntime();
131
126
  expect(runtime.localBoundsRectangle).toBeNull();
132
- expect(runtime.quadBatches).toEqual([]);
127
+ expect(runtime.pages).toEqual([]);
133
128
  });
134
129
  });
135
130
 
@@ -145,20 +140,22 @@ describe('getBitmapTextBounds', () => {
145
140
  });
146
141
  });
147
142
 
148
- describe('getBitmapTextQuadBatches', () => {
149
- it('returns the backing batches in page order, matching the node children', () => {
143
+ describe('getBitmapTextPages', () => {
144
+ it('returns the owned pages in page order', () => {
150
145
  const text = createBitmapText(createTestGlyphSource());
151
- const batches = getBitmapTextQuadBatches(text);
152
- expect(batches).toHaveLength(1);
153
- expect(batches[0]).toBe(getNode2DRuntime(text).children![0]);
146
+ const pages = getBitmapTextPages(text);
147
+ expect(pages).toHaveLength(1);
148
+ expect(pages[0].instanceCount).toBe(0);
154
149
  });
155
150
  });
156
151
 
157
152
  describe('reserveBitmapText', () => {
158
- it('grows the backing quad batch capacity', () => {
153
+ it('grows each page quad-array capacity', () => {
159
154
  const text = createBitmapText(createTestGlyphSource());
160
155
  reserveBitmapText(text, 64);
161
- expect(getQuadBatchCapacity(getBitmapTextQuadBatches(text)[0]!)).toBeGreaterThanOrEqual(64);
156
+ const page = getBitmapTextPages(text)[0];
157
+ expect(page.ids.length).toBeGreaterThanOrEqual(64);
158
+ expect(page.transforms.length).toBeGreaterThanOrEqual(128);
162
159
  });
163
160
  });
164
161
 
@@ -170,14 +167,6 @@ describe('setBitmapTextAlign', () => {
170
167
  });
171
168
  });
172
169
 
173
- describe('setBitmapTextColor', () => {
174
- it('mutates the color field', () => {
175
- const text = createBitmapText(createTestGlyphSource());
176
- setBitmapTextColor(text, 0x00ff00ff);
177
- expect(text.data.color).toBe(0x00ff00ff);
178
- });
179
- });
180
-
181
170
  describe('setBitmapTextGlyphSource', () => {
182
171
  it('rebinds the glyph source', () => {
183
172
  const text = createBitmapText(createTestGlyphSource());
@@ -3,12 +3,11 @@ import {
3
3
  createGlyphSourceFromGlyphAtlas,
4
4
  createStubGlyphRasterizerBackend,
5
5
  setGlyphRasterizerBackend,
6
- } from '@flighthq/glyphatlas';
7
- import { getNode2DColorAdjustments } from '@flighthq/scene2d';
8
- import type { ColorTransformAdjustment, GlyphEntry, GlyphSource, ImageResource } from '@flighthq/types';
6
+ } from '@flighthq/glyphatlas/contract';
7
+ import type { GlyphEntry, GlyphSource, ImageResource } from '@flighthq/types/contract';
9
8
  import { describe, expect, it } from 'vitest';
10
9
 
11
- import { createBitmapText, getBitmapTextBounds, getBitmapTextQuadBatches, setBitmapTextColor } from './bitmapText';
10
+ import { createBitmapText, getBitmapTextBounds, getBitmapTextPages } from './bitmapText';
12
11
  import { updateBitmapText } from './updateBitmapText';
13
12
 
14
13
  // A deterministic single-page glyph source: every visible glyph is 6x8 with advance 10 and bearingY 8
@@ -59,9 +58,9 @@ describe('updateBitmapText', () => {
59
58
  const atlas = createGlyphAtlas({ fontFamily: 'unavailable', fontSize: 24, height: 256, width: 256 });
60
59
  const text = createBitmapText(createGlyphSourceFromGlyphAtlas(atlas), { text: 'Hi' });
61
60
  updateBitmapText(text);
62
- const batches = getBitmapTextQuadBatches(text);
63
- expect(batches.length).toBeGreaterThan(0);
64
- expect(batches[0]!.data.instanceCount).toBe(2);
61
+ const pages = getBitmapTextPages(text);
62
+ expect(pages.length).toBeGreaterThan(0);
63
+ expect(pages[0]!.instanceCount).toBe(2);
65
64
  } finally {
66
65
  setGlyphRasterizerBackend(null);
67
66
  }
@@ -70,63 +69,63 @@ describe('updateBitmapText', () => {
70
69
  it('places each glyph at its cumulative advance, applying kerning', () => {
71
70
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB' });
72
71
  updateBitmapText(text);
73
- const data = getBitmapTextQuadBatches(text)[0]!.data;
74
- expect(data.instanceCount).toBe(2);
75
- expect(data.transforms[0]).toBe(0); // A.x
76
- expect(data.transforms[1]).toBe(0); // A.y
77
- expect(data.transforms[2]).toBe(8); // B.x = 10 (advance) - 2 (kerning)
78
- expect(data.transforms[3]).toBe(0); // B.y
72
+ const page = getBitmapTextPages(text)[0]!;
73
+ expect(page.instanceCount).toBe(2);
74
+ expect(page.transforms[0]).toBe(0); // A.x
75
+ expect(page.transforms[1]).toBe(0); // A.y
76
+ expect(page.transforms[2]).toBe(8); // B.x = 10 (advance) - 2 (kerning)
77
+ expect(page.transforms[3]).toBe(0); // B.y
79
78
  });
80
79
 
81
80
  it('builds one atlas region per distinct glyph and references it by id', () => {
82
81
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB' });
83
82
  updateBitmapText(text);
84
- const data = getBitmapTextQuadBatches(text)[0]!.data;
85
- expect(data.atlas!.regions).toHaveLength(2);
86
- expect(data.ids[0]).toBe(0);
87
- expect(data.ids[1]).toBe(1);
88
- expect(data.atlas!.regions[0].x).toBe(0); // A rect
89
- expect(data.atlas!.regions[1].x).toBe(6); // B rect
83
+ const page = getBitmapTextPages(text)[0]!;
84
+ expect(page.atlas.regions).toHaveLength(2);
85
+ expect(page.ids[0]).toBe(0);
86
+ expect(page.ids[1]).toBe(1);
87
+ expect(page.atlas.regions[0].x).toBe(0); // A rect
88
+ expect(page.atlas.regions[1].x).toBe(6); // B rect
90
89
  });
91
90
 
92
91
  it('reuses one region for repeated codepoints', () => {
93
92
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA' });
94
93
  updateBitmapText(text);
95
- const data = getBitmapTextQuadBatches(text)[0]!.data;
96
- expect(data.instanceCount).toBe(2);
97
- expect(data.atlas!.regions).toHaveLength(1);
98
- expect(data.ids[0]).toBe(0);
99
- expect(data.ids[1]).toBe(0);
94
+ const page = getBitmapTextPages(text)[0]!;
95
+ expect(page.instanceCount).toBe(2);
96
+ expect(page.atlas.regions).toHaveLength(1);
97
+ expect(page.ids[0]).toBe(0);
98
+ expect(page.ids[1]).toBe(0);
100
99
  });
101
100
 
102
101
  it('starts a new line at the metric line advance on an explicit newline', () => {
103
102
  const text = createBitmapText(createTestGlyphSource(), { text: 'A\nB' });
104
103
  updateBitmapText(text);
105
- const data = getBitmapTextQuadBatches(text)[0]!.data;
106
- expect(data.instanceCount).toBe(2);
107
- expect(data.transforms[0]).toBe(0); // line 0 A.x
108
- expect(data.transforms[1]).toBe(0); // line 0 A.y
109
- expect(data.transforms[2]).toBe(0); // line 1 B.x
110
- expect(data.transforms[3]).toBe(10); // line 1 B.y = 1 * (8 + 2 + 0)
104
+ const page = getBitmapTextPages(text)[0]!;
105
+ expect(page.instanceCount).toBe(2);
106
+ expect(page.transforms[0]).toBe(0); // line 0 A.x
107
+ expect(page.transforms[1]).toBe(0); // line 0 A.y
108
+ expect(page.transforms[2]).toBe(0); // line 1 B.x
109
+ expect(page.transforms[3]).toBe(10); // line 1 B.y = 1 * (8 + 2 + 0)
111
110
  });
112
111
 
113
112
  it('scales the line advance by lineHeight', () => {
114
113
  const text = createBitmapText(createTestGlyphSource(), { text: 'A\nB', lineHeight: 2 });
115
114
  updateBitmapText(text);
116
- const data = getBitmapTextQuadBatches(text)[0]!.data;
117
- expect(data.transforms[3]).toBe(20); // 2 * (8 + 2 + 0)
115
+ const page = getBitmapTextPages(text)[0]!;
116
+ expect(page.transforms[3]).toBe(20); // 2 * (8 + 2 + 0)
118
117
  });
119
118
 
120
119
  it('word-wraps at a word boundary when the width is exceeded', () => {
121
120
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA', wrapWidth: 30 });
122
121
  updateBitmapText(text);
123
- const data = getBitmapTextQuadBatches(text)[0]!.data;
124
- expect(data.instanceCount).toBe(4);
122
+ const page = getBitmapTextPages(text)[0]!;
123
+ expect(page.instanceCount).toBe(4);
125
124
  let firstLine = 0;
126
125
  let secondLine = 0;
127
- for (let i = 0; i < data.instanceCount; i++) {
128
- if (data.transforms[i * 2 + 1] === 0) firstLine++;
129
- else if (data.transforms[i * 2 + 1] === 10) secondLine++;
126
+ for (let i = 0; i < page.instanceCount; i++) {
127
+ if (page.transforms[i * 2 + 1] === 0) firstLine++;
128
+ else if (page.transforms[i * 2 + 1] === 10) secondLine++;
130
129
  }
131
130
  expect(firstLine).toBe(2);
132
131
  expect(secondLine).toBe(2);
@@ -135,62 +134,62 @@ describe('updateBitmapText', () => {
135
134
  it('keeps words on one line and honors space advance when no wrap is set', () => {
136
135
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA' });
137
136
  updateBitmapText(text);
138
- const data = getBitmapTextQuadBatches(text)[0]!.data;
139
- expect(data.instanceCount).toBe(4);
140
- for (let i = 0; i < data.instanceCount; i++) expect(data.transforms[i * 2 + 1]).toBe(0);
141
- expect(data.transforms[4]).toBe(25); // third glyph: word1 width 20 + space 5
142
- expect(data.transforms[6]).toBe(35);
137
+ const page = getBitmapTextPages(text)[0]!;
138
+ expect(page.instanceCount).toBe(4);
139
+ for (let i = 0; i < page.instanceCount; i++) expect(page.transforms[i * 2 + 1]).toBe(0);
140
+ expect(page.transforms[4]).toBe(25); // third glyph: word1 width 20 + space 5
141
+ expect(page.transforms[6]).toBe(35);
143
142
  });
144
143
 
145
144
  it('offsets a line for center alignment', () => {
146
145
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', wrapWidth: 100, align: 'center' });
147
146
  updateBitmapText(text);
148
- const data = getBitmapTextQuadBatches(text)[0]!.data;
149
- expect(data.transforms[0]).toBe(41); // (100 - 18) / 2
150
- expect(data.transforms[2]).toBe(49); // 41 + 8
147
+ const page = getBitmapTextPages(text)[0]!;
148
+ expect(page.transforms[0]).toBe(41); // (100 - 18) / 2
149
+ expect(page.transforms[2]).toBe(49); // 41 + 8
151
150
  });
152
151
 
153
152
  it('offsets a line for right alignment', () => {
154
153
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', wrapWidth: 100, align: 'right' });
155
154
  updateBitmapText(text);
156
- const data = getBitmapTextQuadBatches(text)[0]!.data;
157
- expect(data.transforms[0]).toBe(82); // 100 - 18
155
+ const page = getBitmapTextPages(text)[0]!;
156
+ expect(page.transforms[0]).toBe(82); // 100 - 18
158
157
  });
159
158
 
160
159
  it('stretches inter-word gaps for justify on non-final lines', () => {
161
160
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA AA', wrapWidth: 50, align: 'justify' });
162
161
  updateBitmapText(text);
163
- const data = getBitmapTextQuadBatches(text)[0]!.data;
162
+ const page = getBitmapTextPages(text)[0]!;
164
163
  // Line 0 = "AA AA" justified to 50: gap 5 grows by (50 - 45) / 1 = 5, so word 2 starts at 30.
165
- expect(data.transforms[4]).toBe(30);
166
- expect(data.transforms[6]).toBe(40);
164
+ expect(page.transforms[4]).toBe(30);
165
+ expect(page.transforms[6]).toBe(40);
167
166
  // Line 1 = trailing "AA" (paragraph end) stays left.
168
167
  const line1 = [];
169
- for (let i = 0; i < data.instanceCount; i++)
170
- if (data.transforms[i * 2 + 1] === 10) line1.push(data.transforms[i * 2]);
168
+ for (let i = 0; i < page.instanceCount; i++)
169
+ if (page.transforms[i * 2 + 1] === 10) line1.push(page.transforms[i * 2]);
171
170
  expect(line1).toEqual([0, 10]);
172
171
  });
173
172
 
174
173
  it('omits a missing glyph with no quad and no advance', () => {
175
174
  const text = createBitmapText(createTestGlyphSource(), { text: 'A?B' });
176
175
  updateBitmapText(text);
177
- const data = getBitmapTextQuadBatches(text)[0]!.data;
178
- expect(data.instanceCount).toBe(2);
179
- expect(data.transforms[0]).toBe(0); // A
180
- expect(data.transforms[2]).toBe(8); // B placed as if '?' were absent (10 - 2 kerning)
176
+ const page = getBitmapTextPages(text)[0]!;
177
+ expect(page.instanceCount).toBe(2);
178
+ expect(page.transforms[0]).toBe(0); // A
179
+ expect(page.transforms[2]).toBe(8); // B placed as if '?' were absent (10 - 2 kerning)
181
180
  });
182
181
 
183
182
  it('adds letterSpacing after each glyph advance', () => {
184
183
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', letterSpacing: 1 });
185
184
  updateBitmapText(text);
186
- const data = getBitmapTextQuadBatches(text)[0]!.data;
187
- expect(data.transforms[2]).toBe(9); // 10 + 1 (spacing) - 2 (kerning)
185
+ const page = getBitmapTextPages(text)[0]!;
186
+ expect(page.transforms[2]).toBe(9); // 10 + 1 (spacing) - 2 (kerning)
188
187
  });
189
188
 
190
- it('lays out an empty string as an empty batch without throwing', () => {
189
+ it('lays out an empty string as an empty page without throwing', () => {
191
190
  const text = createBitmapText(createTestGlyphSource(), { text: '' });
192
191
  expect(() => updateBitmapText(text)).not.toThrow();
193
- expect(getBitmapTextQuadBatches(text)[0]!.data.instanceCount).toBe(0);
192
+ expect(getBitmapTextPages(text)[0]!.instanceCount).toBe(0);
194
193
  const bounds = getBitmapTextBounds(text);
195
194
  expect(bounds.width).toBe(0);
196
195
  expect(bounds.height).toBe(0);
@@ -206,47 +205,32 @@ describe('updateBitmapText', () => {
206
205
  expect(bounds.height).toBe(8);
207
206
  });
208
207
 
209
- it('sets a whole-batch color-transform tint only for non-white colors', () => {
210
- const text = createBitmapText(createTestGlyphSource(), { text: 'AB' });
211
- updateBitmapText(text);
212
- expect(getNode2DColorAdjustments(getBitmapTextQuadBatches(text)[0]!)).toBeNull();
213
- setBitmapTextColor(text, 0xff0000ff);
214
- updateBitmapText(text);
215
- // One color-transform adjustment on the batch's runtime slot — a single whole-batch tint, not per-glyph.
216
- const adjustments = getNode2DColorAdjustments(getBitmapTextQuadBatches(text)[0]!);
217
- expect(adjustments).not.toBeNull();
218
- expect(adjustments!).toHaveLength(1);
219
- const colorTransform = (adjustments![0] as ColorTransformAdjustment).colorTransform;
220
- expect(colorTransform.redMultiplier).toBe(1);
221
- expect(colorTransform.greenMultiplier).toBe(0);
222
- });
223
-
224
- it('produces exactly one batch bound to the page-0 image for a single-page source', () => {
208
+ it('produces exactly one page bound to the page-0 image for a single-page source', () => {
225
209
  const source = createTestGlyphSource();
226
210
  const text = createBitmapText(source, { text: 'AB' });
227
211
  updateBitmapText(text);
228
- const batches = getBitmapTextQuadBatches(text);
229
- expect(batches).toHaveLength(1);
230
- expect(batches[0].data.instanceCount).toBe(2);
231
- expect(batches[0].data.atlas!.image).toBe(source.getGlyphAtlasImage(0));
212
+ const pages = getBitmapTextPages(text);
213
+ expect(pages).toHaveLength(1);
214
+ expect(pages[0].instanceCount).toBe(2);
215
+ expect(pages[0].atlas.texture?.storage.image).toBe(source.getGlyphAtlasImage(0));
232
216
  });
233
217
 
234
- it('partitions glyphs into one QuadBatch per page, each bound to its own page image', () => {
218
+ it('partitions glyphs into one page per glyph-atlas page, each bound to its own page image', () => {
235
219
  const { source, page0Image, page1Image } = createTwoPageGlyphSource();
236
220
  const text = createBitmapText(source, { text: 'AB' });
237
221
  updateBitmapText(text);
238
- const batches = getBitmapTextQuadBatches(text);
239
- expect(batches).toHaveLength(2);
222
+ const pages = getBitmapTextPages(text);
223
+ expect(pages).toHaveLength(2);
240
224
 
241
225
  // Page 0 holds 'A' only, sampling page0Image; page 1 holds 'B' only, sampling page1Image.
242
- const page0 = batches[0].data;
243
- const page1 = batches[1].data;
226
+ const page0 = pages[0];
227
+ const page1 = pages[1];
244
228
  expect(page0.instanceCount).toBe(1);
245
229
  expect(page1.instanceCount).toBe(1);
246
- expect(page0.atlas!.image).toBe(page0Image);
247
- expect(page1.atlas!.image).toBe(page1Image);
248
- expect(page0.atlas!.regions[0].x).toBe(0); // A's rect on page 0
249
- expect(page1.atlas!.regions[0].x).toBe(3); // B's rect on page 1
230
+ expect(page0.atlas.texture?.storage.image).toBe(page0Image);
231
+ expect(page1.atlas.texture?.storage.image).toBe(page1Image);
232
+ expect(page0.atlas.regions[0].x).toBe(0); // A's rect on page 0
233
+ expect(page1.atlas.regions[0].x).toBe(3); // B's rect on page 1
250
234
  expect(page0.transforms[0]).toBe(0); // A at pen origin
251
235
  expect(page1.transforms[0]).toBe(10); // B after A's advance (no kerning)
252
236
  });