@flighthq/bitmaptext 0.2.1-next.841.373388f → 0.3.0-edge.1516.1b4fb2b

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, setTextureSource } 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({ dimension: '2d', source: image });
179
+ }
180
+ else {
181
+ setTextureSource(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-edge.1516.1b4fb2b",
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-edge.1516.1b4fb2b",
40
+ "@flighthq/geometry": "0.3.0-edge.1516.1b4fb2b",
41
+ "@flighthq/node": "0.3.0-edge.1516.1b4fb2b",
42
+ "@flighthq/texture": "0.3.0-edge.1516.1b4fb2b",
43
+ "@flighthq/textureatlas": "0.3.0-edge.1516.1b4fb2b",
44
+ "@flighthq/types": "0.3.0-edge.1516.1b4fb2b"
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, Image } 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,
@@ -23,7 +21,7 @@ import {
23
21
  } from './bitmapText';
24
22
  import { updateBitmapText } from './updateBitmapText';
25
23
 
26
- // A single-page glyph source: A/B are 6x8, a space advances 5, and page 0 is a stub `ImageResource`.
24
+ // A single-page glyph source: A/B are 6x8, a space advances 5, and page 0 is a stub `Image`.
27
25
  function createTestGlyphSource(): GlyphSource {
28
26
  const entries = new Map<number, GlyphEntry>();
29
27
  const add = (cp: number, x: number): void => {
@@ -32,7 +30,7 @@ function createTestGlyphSource(): GlyphSource {
32
30
  add(0x41, 0); // A
33
31
  add(0x42, 6); // B
34
32
  entries.set(0x20, { advance: 5, bearingX: 0, bearingY: 0, height: 0, page: 0, width: 0, x: 0, y: 0 }); // space
35
- const image = {} as ImageResource;
33
+ const image = {} as Image;
36
34
  return {
37
35
  getGlyphAtlasImage: (page = 0) => (page === 0 ? image : null),
38
36
  getGlyphEntry: (cp) => entries.get(cp) ?? null,
@@ -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,17 +3,17 @@ 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 { getTextureSource } from '@flighthq/texture/contract';
8
+ import type { GlyphEntry, GlyphSource, Image } from '@flighthq/types/contract';
9
9
  import { describe, expect, it } from 'vitest';
10
10
 
11
- import { createBitmapText, getBitmapTextBounds, getBitmapTextQuadBatches, setBitmapTextColor } from './bitmapText';
11
+ import { createBitmapText, getBitmapTextBounds, getBitmapTextPages } from './bitmapText';
12
12
  import { updateBitmapText } from './updateBitmapText';
13
13
 
14
14
  // A deterministic single-page glyph source: every visible glyph is 6x8 with advance 10 and bearingY 8
15
15
  // (so line tops sit at y=0), a space advances 5 with no pixels, and the pair (A, B) kerns by -2. All
16
- // glyphs live on page 0, whose atlas image is a stub `ImageResource`.
16
+ // glyphs live on page 0, whose atlas image is a stub `Image`.
17
17
  function createTestGlyphSource(): GlyphSource {
18
18
  const entries = new Map<number, GlyphEntry>();
19
19
  const add = (cp: number, x: number): void => {
@@ -23,7 +23,7 @@ function createTestGlyphSource(): GlyphSource {
23
23
  add(0x42, 6); // B
24
24
  entries.set(0x20, { advance: 5, bearingX: 0, bearingY: 0, height: 0, page: 0, width: 0, x: 0, y: 0 }); // space
25
25
  const kerning = new Map<number, number>([[(0x41 << 16) | 0x42, -2]]);
26
- const image = {} as ImageResource;
26
+ const image = {} as Image;
27
27
  return {
28
28
  getGlyphAtlasImage: (page = 0) => (page === 0 ? image : null),
29
29
  getGlyphEntry: (cp) => entries.get(cp) ?? null,
@@ -33,9 +33,9 @@ function createTestGlyphSource(): GlyphSource {
33
33
  }
34
34
 
35
35
  // A two-page glyph source: 'A' lives on page 0, 'B' on page 1, each page a DISTINCT stub image.
36
- function createTwoPageGlyphSource(): { source: GlyphSource; page0Image: ImageResource; page1Image: ImageResource } {
37
- const page0Image = {} as ImageResource;
38
- const page1Image = {} as ImageResource;
36
+ function createTwoPageGlyphSource(): { source: GlyphSource; page0Image: Image; page1Image: Image } {
37
+ const page0Image = {} as Image;
38
+ const page1Image = {} as Image;
39
39
  const entries = new Map<number, GlyphEntry>([
40
40
  [0x41, { advance: 10, bearingX: 0, bearingY: 8, height: 8, page: 0, width: 6, x: 0, y: 0 }], // A → page 0
41
41
  [0x42, { advance: 10, bearingX: 0, bearingY: 8, height: 8, page: 1, width: 6, x: 3, y: 0 }], // B → page 1
@@ -59,9 +59,9 @@ describe('updateBitmapText', () => {
59
59
  const atlas = createGlyphAtlas({ fontFamily: 'unavailable', fontSize: 24, height: 256, width: 256 });
60
60
  const text = createBitmapText(createGlyphSourceFromGlyphAtlas(atlas), { text: 'Hi' });
61
61
  updateBitmapText(text);
62
- const batches = getBitmapTextQuadBatches(text);
63
- expect(batches.length).toBeGreaterThan(0);
64
- expect(batches[0]!.data.instanceCount).toBe(2);
62
+ const pages = getBitmapTextPages(text);
63
+ expect(pages.length).toBeGreaterThan(0);
64
+ expect(pages[0]!.instanceCount).toBe(2);
65
65
  } finally {
66
66
  setGlyphRasterizerBackend(null);
67
67
  }
@@ -70,63 +70,63 @@ describe('updateBitmapText', () => {
70
70
  it('places each glyph at its cumulative advance, applying kerning', () => {
71
71
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB' });
72
72
  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
73
+ const page = getBitmapTextPages(text)[0]!;
74
+ expect(page.instanceCount).toBe(2);
75
+ expect(page.transforms[0]).toBe(0); // A.x
76
+ expect(page.transforms[1]).toBe(0); // A.y
77
+ expect(page.transforms[2]).toBe(8); // B.x = 10 (advance) - 2 (kerning)
78
+ expect(page.transforms[3]).toBe(0); // B.y
79
79
  });
80
80
 
81
81
  it('builds one atlas region per distinct glyph and references it by id', () => {
82
82
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB' });
83
83
  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
84
+ const page = getBitmapTextPages(text)[0]!;
85
+ expect(page.atlas.regions).toHaveLength(2);
86
+ expect(page.ids[0]).toBe(0);
87
+ expect(page.ids[1]).toBe(1);
88
+ expect(page.atlas.regions[0].x).toBe(0); // A rect
89
+ expect(page.atlas.regions[1].x).toBe(6); // B rect
90
90
  });
91
91
 
92
92
  it('reuses one region for repeated codepoints', () => {
93
93
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA' });
94
94
  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);
95
+ const page = getBitmapTextPages(text)[0]!;
96
+ expect(page.instanceCount).toBe(2);
97
+ expect(page.atlas.regions).toHaveLength(1);
98
+ expect(page.ids[0]).toBe(0);
99
+ expect(page.ids[1]).toBe(0);
100
100
  });
101
101
 
102
102
  it('starts a new line at the metric line advance on an explicit newline', () => {
103
103
  const text = createBitmapText(createTestGlyphSource(), { text: 'A\nB' });
104
104
  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)
105
+ const page = getBitmapTextPages(text)[0]!;
106
+ expect(page.instanceCount).toBe(2);
107
+ expect(page.transforms[0]).toBe(0); // line 0 A.x
108
+ expect(page.transforms[1]).toBe(0); // line 0 A.y
109
+ expect(page.transforms[2]).toBe(0); // line 1 B.x
110
+ expect(page.transforms[3]).toBe(10); // line 1 B.y = 1 * (8 + 2 + 0)
111
111
  });
112
112
 
113
113
  it('scales the line advance by lineHeight', () => {
114
114
  const text = createBitmapText(createTestGlyphSource(), { text: 'A\nB', lineHeight: 2 });
115
115
  updateBitmapText(text);
116
- const data = getBitmapTextQuadBatches(text)[0]!.data;
117
- expect(data.transforms[3]).toBe(20); // 2 * (8 + 2 + 0)
116
+ const page = getBitmapTextPages(text)[0]!;
117
+ expect(page.transforms[3]).toBe(20); // 2 * (8 + 2 + 0)
118
118
  });
119
119
 
120
120
  it('word-wraps at a word boundary when the width is exceeded', () => {
121
121
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA', wrapWidth: 30 });
122
122
  updateBitmapText(text);
123
- const data = getBitmapTextQuadBatches(text)[0]!.data;
124
- expect(data.instanceCount).toBe(4);
123
+ const page = getBitmapTextPages(text)[0]!;
124
+ expect(page.instanceCount).toBe(4);
125
125
  let firstLine = 0;
126
126
  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++;
127
+ for (let i = 0; i < page.instanceCount; i++) {
128
+ if (page.transforms[i * 2 + 1] === 0) firstLine++;
129
+ else if (page.transforms[i * 2 + 1] === 10) secondLine++;
130
130
  }
131
131
  expect(firstLine).toBe(2);
132
132
  expect(secondLine).toBe(2);
@@ -135,62 +135,62 @@ describe('updateBitmapText', () => {
135
135
  it('keeps words on one line and honors space advance when no wrap is set', () => {
136
136
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA' });
137
137
  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);
138
+ const page = getBitmapTextPages(text)[0]!;
139
+ expect(page.instanceCount).toBe(4);
140
+ for (let i = 0; i < page.instanceCount; i++) expect(page.transforms[i * 2 + 1]).toBe(0);
141
+ expect(page.transforms[4]).toBe(25); // third glyph: word1 width 20 + space 5
142
+ expect(page.transforms[6]).toBe(35);
143
143
  });
144
144
 
145
145
  it('offsets a line for center alignment', () => {
146
146
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', wrapWidth: 100, align: 'center' });
147
147
  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
148
+ const page = getBitmapTextPages(text)[0]!;
149
+ expect(page.transforms[0]).toBe(41); // (100 - 18) / 2
150
+ expect(page.transforms[2]).toBe(49); // 41 + 8
151
151
  });
152
152
 
153
153
  it('offsets a line for right alignment', () => {
154
154
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', wrapWidth: 100, align: 'right' });
155
155
  updateBitmapText(text);
156
- const data = getBitmapTextQuadBatches(text)[0]!.data;
157
- expect(data.transforms[0]).toBe(82); // 100 - 18
156
+ const page = getBitmapTextPages(text)[0]!;
157
+ expect(page.transforms[0]).toBe(82); // 100 - 18
158
158
  });
159
159
 
160
160
  it('stretches inter-word gaps for justify on non-final lines', () => {
161
161
  const text = createBitmapText(createTestGlyphSource(), { text: 'AA AA AA', wrapWidth: 50, align: 'justify' });
162
162
  updateBitmapText(text);
163
- const data = getBitmapTextQuadBatches(text)[0]!.data;
163
+ const page = getBitmapTextPages(text)[0]!;
164
164
  // 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);
165
+ expect(page.transforms[4]).toBe(30);
166
+ expect(page.transforms[6]).toBe(40);
167
167
  // Line 1 = trailing "AA" (paragraph end) stays left.
168
168
  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]);
169
+ for (let i = 0; i < page.instanceCount; i++)
170
+ if (page.transforms[i * 2 + 1] === 10) line1.push(page.transforms[i * 2]);
171
171
  expect(line1).toEqual([0, 10]);
172
172
  });
173
173
 
174
174
  it('omits a missing glyph with no quad and no advance', () => {
175
175
  const text = createBitmapText(createTestGlyphSource(), { text: 'A?B' });
176
176
  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)
177
+ const page = getBitmapTextPages(text)[0]!;
178
+ expect(page.instanceCount).toBe(2);
179
+ expect(page.transforms[0]).toBe(0); // A
180
+ expect(page.transforms[2]).toBe(8); // B placed as if '?' were absent (10 - 2 kerning)
181
181
  });
182
182
 
183
183
  it('adds letterSpacing after each glyph advance', () => {
184
184
  const text = createBitmapText(createTestGlyphSource(), { text: 'AB', letterSpacing: 1 });
185
185
  updateBitmapText(text);
186
- const data = getBitmapTextQuadBatches(text)[0]!.data;
187
- expect(data.transforms[2]).toBe(9); // 10 + 1 (spacing) - 2 (kerning)
186
+ const page = getBitmapTextPages(text)[0]!;
187
+ expect(page.transforms[2]).toBe(9); // 10 + 1 (spacing) - 2 (kerning)
188
188
  });
189
189
 
190
- it('lays out an empty string as an empty batch without throwing', () => {
190
+ it('lays out an empty string as an empty page without throwing', () => {
191
191
  const text = createBitmapText(createTestGlyphSource(), { text: '' });
192
192
  expect(() => updateBitmapText(text)).not.toThrow();
193
- expect(getBitmapTextQuadBatches(text)[0]!.data.instanceCount).toBe(0);
193
+ expect(getBitmapTextPages(text)[0]!.instanceCount).toBe(0);
194
194
  const bounds = getBitmapTextBounds(text);
195
195
  expect(bounds.width).toBe(0);
196
196
  expect(bounds.height).toBe(0);
@@ -206,47 +206,32 @@ describe('updateBitmapText', () => {
206
206
  expect(bounds.height).toBe(8);
207
207
  });
208
208
 
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', () => {
209
+ it('produces exactly one page bound to the page-0 image for a single-page source', () => {
225
210
  const source = createTestGlyphSource();
226
211
  const text = createBitmapText(source, { text: 'AB' });
227
212
  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));
213
+ const pages = getBitmapTextPages(text);
214
+ expect(pages).toHaveLength(1);
215
+ expect(pages[0].instanceCount).toBe(2);
216
+ expect(getTextureSource(pages[0].atlas.texture!)).toBe(source.getGlyphAtlasImage(0));
232
217
  });
233
218
 
234
- it('partitions glyphs into one QuadBatch per page, each bound to its own page image', () => {
219
+ it('partitions glyphs into one page per glyph-atlas page, each bound to its own page image', () => {
235
220
  const { source, page0Image, page1Image } = createTwoPageGlyphSource();
236
221
  const text = createBitmapText(source, { text: 'AB' });
237
222
  updateBitmapText(text);
238
- const batches = getBitmapTextQuadBatches(text);
239
- expect(batches).toHaveLength(2);
223
+ const pages = getBitmapTextPages(text);
224
+ expect(pages).toHaveLength(2);
240
225
 
241
226
  // 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;
227
+ const page0 = pages[0];
228
+ const page1 = pages[1];
244
229
  expect(page0.instanceCount).toBe(1);
245
230
  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
231
+ expect(getTextureSource(page0.atlas.texture!)).toBe(page0Image);
232
+ expect(getTextureSource(page1.atlas.texture!)).toBe(page1Image);
233
+ expect(page0.atlas.regions[0].x).toBe(0); // A's rect on page 0
234
+ expect(page1.atlas.regions[0].x).toBe(3); // B's rect on page 1
250
235
  expect(page0.transforms[0]).toBe(0); // A at pen origin
251
236
  expect(page1.transforms[0]).toBe(10); // B after A's advance (no kerning)
252
237
  });