@flighthq/textshaper 0.5.1-next.704.19c91ec → 0.5.1-next.730.f29a5aa

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/textshaper`. The `@f
13
13
  This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
14
14
 
15
15
  - [Flight project](https://github.com/flighthq/flight)
16
- - [Source for @flighthq/textshaper@0.5.1-next.704.19c91ec](https://github.com/flighthq/flight/tree/19c91ec3e569d6b3b471682726465a79fba9f8cb/packages/textshaper)
17
- - [License](https://github.com/flighthq/flight/blob/19c91ec3e569d6b3b471682726465a79fba9f8cb/LICENSE.md)
16
+ - [Source for @flighthq/textshaper@0.5.1-next.730.f29a5aa](https://github.com/flighthq/flight/tree/f29a5aab5db192284ce5cadf08ffae2649a598ea/packages/textshaper)
17
+ - [License](https://github.com/flighthq/flight/blob/f29a5aab5db192284ce5cadf08ffae2649a598ea/LICENSE.md)
@@ -1,7 +1,14 @@
1
- import type { BackendOperationExplanation, TextFormat, TextShaperBackend, TextShaperOperation } from '@flighthq/types/contract';
2
- export declare function explainTextShaperOperation(operation: TextShaperOperation): BackendOperationExplanation;
3
- export declare function getTextShaperBackend(): TextShaperBackend | null;
4
- export declare function hasTextShaperOperation(operation: TextShaperOperation): boolean;
5
- export declare function measureText(text: string, format: Readonly<TextFormat>): number;
1
+ import type { BackendOperationExplanation, HasTextShaper, TextFormat, TextShaperBackend, TextShaperOperation } from '@flighthq/types/contract';
2
+ export declare function explainTextShaperOperation(operation: TextShaperOperation, host?: HasTextShaper): BackendOperationExplanation;
3
+ export declare function getTextShaperBackend(host?: HasTextShaper): TextShaperBackend | null;
4
+ export declare function hasTextShaperOperation(operation: TextShaperOperation, host?: HasTextShaper): boolean;
5
+ export declare function measureText(text: string, format: Readonly<TextFormat>, host?: HasTextShaper): number;
6
+ /**
7
+ * Installs the backend used by calls that omit an explicit host; pass null to clear it. Last write
8
+ * wins and re-registration never throws.
9
+ *
10
+ * @deprecated Pass a HasTextShaper to the text-shaping operation. Retained for source compatibility
11
+ * until the legacy global path is removed.
12
+ */
6
13
  export declare function setTextShaperBackend(backend: TextShaperBackend | null): void;
7
14
  //# sourceMappingURL=textShaper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textShaper.d.ts","sourceRoot":"","sources":["../src/textShaper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAC3B,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAelC,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,mBAAmB,GAAG,2BAA2B,CAKtG;AAED,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAE/D;AAID,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAE9E;AAKD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAG9E;AAKD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAG5E"}
1
+ {"version":3,"file":"textShaper.d.ts","sourceRoot":"","sources":["../src/textShaper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAMlC,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,mBAAmB,EAC9B,IAAI,CAAC,EAAE,aAAa,GACnB,2BAA2B,CAM7B;AAKD,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAEnF;AAID,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAEpG;AAKD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,MAAM,CAIpG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAG5E"}
@@ -1,40 +1,40 @@
1
1
  import { _textShaperBackendHook } from './_textShaperHooks';
2
- // Returns the active text-shaper backend, or null when none has been registered. Unlike the
3
- // always-on platform capabilities (clipboard, storage), shaping has no light web default that lives
4
- // here: the canvas backend needs DOM + font-string computation, so it ships in
5
- // @flighthq/textshaper-canvas and is installed via setTextShaperBackend. This mirrors text-layout's
6
- // historical measure-provider, which was null until a renderer registered one — callers fall back to
7
- // leaving text unmeasured until a backend exists. A future @flighthq/textshaper-harfbuzz registers
8
- // the same way.
9
- // Which layer implements `operation`. This capability is a SINGLE NULLABLE SLOT — there is no host layer
10
- // and no sentinel — so the two honest answers are `'custom'` (a backend is installed and provides it) and
11
- // `'none'` (no backend is installed at all). Reporting `'sentinel'` here would name a fall-through object
12
- // that does not exist, and inventing a host layer would describe a precedence this package does not have.
13
- export function explainTextShaperOperation(operation) {
14
- if (_backend !== null && typeof _backend[operation] === 'function') {
15
- return { implemented: true, layer: 'custom', operation };
2
+ // Which layer implements `operation`. An explicit host provider wins over the legacy installed
3
+ // backend. There is no sentinel because this package has no light bundled shaper implementation.
4
+ export function explainTextShaperOperation(operation, host) {
5
+ const backend = getTextShaperBackend(host);
6
+ if (backend !== null && typeof backend[operation] === 'function') {
7
+ return { implemented: true, layer: host === undefined ? 'custom' : 'host', operation };
16
8
  }
17
9
  return { implemented: false, layer: 'none', operation };
18
10
  }
19
- export function getTextShaperBackend() {
20
- return _backend;
11
+ // Returns the explicit host's shaper when supplied, otherwise the legacy installed backend. Unlike
12
+ // text segmentation, shaping has no light bundled default: the canvas provider needs DOM and font
13
+ // string computation, so callers must compose it into a host or install it through the legacy path.
14
+ export function getTextShaperBackend(host) {
15
+ return host?.text.shaper ?? _backend;
21
16
  }
22
- // Whether an installed backend implements `operation`. False when nothing is installed, which for this
23
- // capability is also what the getter reports by returning null.
24
- export function hasTextShaperOperation(operation) {
25
- return explainTextShaperOperation(operation).implemented;
17
+ // Whether the selected backend implements `operation`. False when neither an explicit nor legacy
18
+ // provider supplies it.
19
+ export function hasTextShaperOperation(operation, host) {
20
+ return explainTextShaperOperation(operation, host).implemented;
26
21
  }
27
- // Measures `text` in `format` to its horizontal advance, in pixels, via the active backend. Returns
28
- // the sentinel -1 when no backend is registered (expected before setup), so callers can distinguish
29
- // "unmeasurable" from a real zero-width advance.
30
- export function measureText(text, format) {
31
- if (_backend === null)
22
+ // Measures `text` in `format` to its horizontal advance, in pixels, via the explicit host or legacy
23
+ // fallback. Returns the sentinel -1 when neither is available, distinguishing "unmeasurable" from a
24
+ // real zero-width advance.
25
+ export function measureText(text, format, host) {
26
+ const backend = getTextShaperBackend(host);
27
+ if (backend === null)
32
28
  return -1;
33
- return _backend.measureText(text, format);
29
+ return backend.measureText(text, format);
34
30
  }
35
- // Installs a text-shaper backend; pass null to clear it. Last write wins — registering over an
36
- // existing backend replaces it, which is how a host swaps the canvas default for HarfBuzz. Never
37
- // throws on re-registration.
31
+ /**
32
+ * Installs the backend used by calls that omit an explicit host; pass null to clear it. Last write
33
+ * wins and re-registration never throws.
34
+ *
35
+ * @deprecated Pass a HasTextShaper to the text-shaping operation. Retained for source compatibility
36
+ * until the legacy global path is removed.
37
+ */
38
38
  export function setTextShaperBackend(backend) {
39
39
  _backend = backend;
40
40
  _textShaperBackendHook?.(backend);
@@ -1 +1 @@
1
- {"version":3,"file":"textShaper.js","sourceRoot":"","sources":["../src/textShaper.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,4FAA4F;AAC5F,oGAAoG;AACpG,+EAA+E;AAC/E,oGAAoG;AACpG,qGAAqG;AACrG,mGAAmG;AACnG,gBAAgB;AAChB,yGAAyG;AACzG,0GAA0G;AAC1G,0GAA0G;AAC1G,0GAA0G;AAC1G,MAAM,UAAU,0BAA0B,CAAC,SAA8B;IACvE,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,CAAC;QACnE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uGAAuG;AACvG,gEAAgE;AAChE,MAAM,UAAU,sBAAsB,CAAC,SAA8B;IACnE,OAAO,0BAA0B,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC;AAC3D,CAAC;AAED,oGAAoG;AACpG,oGAAoG;AACpG,iDAAiD;AACjD,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAA4B;IACpE,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,+FAA+F;AAC/F,iGAAiG;AACjG,6BAA6B;AAC7B,MAAM,UAAU,oBAAoB,CAAC,OAAiC;IACpE,QAAQ,GAAG,OAAO,CAAC;IACnB,sBAAsB,EAAE,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,QAAQ,GAA6B,IAAI,CAAC"}
1
+ {"version":3,"file":"textShaper.js","sourceRoot":"","sources":["../src/textShaper.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,+FAA+F;AAC/F,iGAAiG;AACjG,MAAM,UAAU,0BAA0B,CACxC,SAA8B,EAC9B,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,CAAC;QACjE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IACzF,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED,mGAAmG;AACnG,kGAAkG;AAClG,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,IAAoB;IACvD,OAAO,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC;AACvC,CAAC;AAED,iGAAiG;AACjG,wBAAwB;AACxB,MAAM,UAAU,sBAAsB,CAAC,SAA8B,EAAE,IAAoB;IACzF,OAAO,0BAA0B,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC;AACjE,CAAC;AAED,oGAAoG;AACpG,oGAAoG;AACpG,2BAA2B;AAC3B,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAA4B,EAAE,IAAoB;IAC1F,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAiC;IACpE,QAAQ,GAAG,OAAO,CAAC;IACnB,sBAAsB,EAAE,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,QAAQ,GAA6B,IAAI,CAAC"}
@@ -1,6 +1,6 @@
1
- import type { ShapedRun, ShapeRunOptions, TextFormat, TextShaperCache } from '@flighthq/types/contract';
1
+ import type { HasTextShaper, ShapedRun, ShapeRunOptions, TextFormat, TextShaperCache } from '@flighthq/types/contract';
2
2
  export declare function clearTextShaperCache(cache: TextShaperCache): void;
3
3
  export declare function createTextShaperCache(): TextShaperCache;
4
4
  export declare function disposeTextShaperCache(cache: TextShaperCache): void;
5
- export declare function shapeTextRunCached(cache: TextShaperCache, text: string, format: Readonly<TextFormat>, options?: Readonly<ShapeRunOptions>): ShapedRun | null;
5
+ export declare function shapeTextRunCached(cache: TextShaperCache, text: string, format: Readonly<TextFormat>, options?: Readonly<ShapeRunOptions>, host?: HasTextShaper): ShapedRun | null;
6
6
  //# sourceMappingURL=textShaperCache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperCache.d.ts","sourceRoot":"","sources":["../src/textShaperCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAOxG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEjE;AAGD,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEnE;AAMD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,GAClC,SAAS,GAAG,IAAI,CAOlB"}
1
+ {"version":3,"file":"textShaperCache.d.ts","sourceRoot":"","sources":["../src/textShaperCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EAEV,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAQlC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEjE;AAGD,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEnE;AAOD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,EACnC,IAAI,CAAC,EAAE,aAAa,GACnB,SAAS,GAAG,IAAI,CASlB"}
@@ -1,3 +1,4 @@
1
+ import { getTextShaperBackend } from './textShaper';
1
2
  import { shapeTextRun } from './textShaperRun';
2
3
  // Clears all cached ShapedRuns from `cache`, releasing their references. The cache remains valid
3
4
  // for continued use after clearing. Does not release the cache object itself (use
@@ -18,17 +19,33 @@ export function disposeTextShaperCache(cache) {
18
19
  // Shapes `text` in `format` with `options`, returning a cached ShapedRun when an equivalent call
19
20
  // was made earlier in this cache's lifetime. Calls `shapeTextRun` on miss and stores the result.
20
21
  // Returns null when no backend is registered or the backend is advances-only (same as
21
- // `shapeTextRun`); null results are NOT cached so a later backend registration can succeed.
22
- export function shapeTextRunCached(cache, text, format, options) {
23
- const key = _makeCacheKey(text, format, options);
22
+ // `shapeTextRun`); null results are NOT cached so a later backend registration can succeed. Cache
23
+ // keys include provider identity so callers can safely share a cache while interleaving hosts.
24
+ export function shapeTextRunCached(cache, text, format, options, host) {
25
+ const backend = getTextShaperBackend(host);
26
+ if (backend === null)
27
+ return null;
28
+ const key = `${_getBackendCacheId(backend)}\x00${_makeCacheKey(text, format, options)}`;
24
29
  const existing = cache._entries.get(key);
25
30
  if (existing !== undefined)
26
31
  return existing;
27
- const result = shapeTextRun(text, format, options);
32
+ const result = shapeTextRun(text, format, options, host);
28
33
  if (result !== null)
29
34
  cache._entries.set(key, result);
30
35
  return result;
31
36
  }
37
+ // Backend identity is allocation state, not capability state: it only scopes cached values and
38
+ // never selects a provider. Weak keys avoid retaining host-provided backends after their lifetime.
39
+ const _backendCacheIds = new WeakMap();
40
+ let _nextBackendCacheId = 1;
41
+ function _getBackendCacheId(backend) {
42
+ const existing = _backendCacheIds.get(backend);
43
+ if (existing !== undefined)
44
+ return existing;
45
+ const id = _nextBackendCacheId++;
46
+ _backendCacheIds.set(backend, id);
47
+ return id;
48
+ }
32
49
  // Builds a stable cache key from the shaping parameters. The key encodes all fields that affect
33
50
  // the shaped output so distinct inputs do not collide. Format fields that are undefined are
34
51
  // omitted; options fields that are undefined are omitted.
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperCache.js","sourceRoot":"","sources":["../src/textShaperCache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,iGAAiG;AACjG,kFAAkF;AAClF,sCAAsC;AACtC,MAAM,UAAU,oBAAoB,CAAC,KAAsB;IACzD,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,qBAAqB;IACnC,OAAO,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;AACjC,CAAC;AAED,+FAA+F;AAC/F,mFAAmF;AACnF,iEAAiE;AACjE,MAAM,UAAU,sBAAsB,CAAC,KAAsB;IAC3D,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,iGAAiG;AACjG,iGAAiG;AACjG,sFAAsF;AACtF,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAChC,KAAsB,EACtB,IAAY,EACZ,MAA4B,EAC5B,OAAmC;IAEnC,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,IAAI;QAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gGAAgG;AAChG,4FAA4F;AAC5F,0DAA0D;AAC1D,SAAS,aAAa,CAAC,IAAY,EAAE,MAA4B,EAAE,OAAmC;IACpG,gGAAgG;IAChG,MAAM,GAAG,GAAG;QACV,MAAM,CAAC,IAAI,IAAI,EAAE;QACjB,MAAM,CAAC,IAAI,IAAI,EAAE;QACjB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,aAAa,IAAI,CAAC;KAC1B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACf,8BAA8B;IAC9B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QACpC,IAAI,GAAG,GAAG,GAAG,OAAO,MAAM,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,IAAI,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"textShaperCache.js","sourceRoot":"","sources":["../src/textShaperCache.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ShapedRun, TextFormat, TextItem, TextShaperOptions } from '@flighthq/types/contract';
1
+ import type { HasTextShaper, ShapedRun, TextFormat, TextItem, TextShaperOptions } from '@flighthq/types/contract';
2
2
  export declare function itemizeText(text: string, _format: Readonly<TextFormat>, options?: Readonly<TextShaperOptions>): readonly TextItem[];
3
- export declare function shapeTextRuns(text: string, format: Readonly<TextFormat>, options?: Readonly<TextShaperOptions>): readonly ShapedRun[];
3
+ export declare function shapeTextRuns(text: string, format: Readonly<TextFormat>, options?: Readonly<TextShaperOptions>, host?: HasTextShaper): readonly ShapedRun[];
4
4
  //# sourceMappingURL=textShaperItemize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperItemize.d.ts","sourceRoot":"","sources":["../src/textShaperItemize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAanG,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EAGZ,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GACpC,SAAS,QAAQ,EAAE,CAgDrB;AAQD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GACpC,SAAS,SAAS,EAAE,CAiBtB"}
1
+ {"version":3,"file":"textShaperItemize.d.ts","sourceRoot":"","sources":["../src/textShaperItemize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAalH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EAGZ,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GACpC,SAAS,QAAQ,EAAE,CAgDrB;AAQD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACrC,IAAI,CAAC,EAAE,aAAa,GACnB,SAAS,SAAS,EAAE,CAiBtB"}
@@ -70,7 +70,7 @@ _format, options) {
70
70
  //
71
71
  // This is the primary convenience entry point for multi-script strings: `itemizeText` handles the
72
72
  // script/direction split, then `shapeTextRun` produces glyph ids and positions for each sub-run.
73
- export function shapeTextRuns(text, format, options) {
73
+ export function shapeTextRuns(text, format, options, host) {
74
74
  if (text.length === 0)
75
75
  return [];
76
76
  const items = itemizeText(text, format, options);
@@ -84,7 +84,7 @@ export function shapeTextRuns(text, format, options) {
84
84
  direction: item.direction === 'TopToBottom' ? undefined : item.direction,
85
85
  script: item.script,
86
86
  };
87
- const run = shapeTextRun(sub, format, runOptions);
87
+ const run = shapeTextRun(sub, format, runOptions, host);
88
88
  if (run !== null)
89
89
  result.push(run);
90
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperItemize.js","sourceRoot":"","sources":["../src/textShaperItemize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"textShaperItemize.js","sourceRoot":"","sources":["../src/textShaperItemize.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import type { FontMetrics, GlyphExtents, ShapedRun, ShapeRunOptions, TextFormat } from '@flighthq/types/contract';
1
+ import type { FontMetrics, GlyphExtents, HasTextShaper, ShapedRun, ShapeRunOptions, TextFormat } from '@flighthq/types/contract';
2
2
  export declare function clearShapedRun(run: ShapedRun): ShapedRun;
3
3
  export declare function createShapedRun(): ShapedRun;
4
- export declare function getCodePointForGlyph(glyphId: number, _format: Readonly<TextFormat>): number;
5
- export declare function getFontMetrics(format: Readonly<TextFormat>): FontMetrics | null;
6
- export declare function getFontMetricsInto(format: Readonly<TextFormat>, out: FontMetrics): boolean;
7
- export declare function getFontUnitScale(format: Readonly<TextFormat>): number;
8
- export declare function getGlyphExtents(glyphId: number, _format: Readonly<TextFormat>): GlyphExtents | null;
9
- export declare function getGlyphExtentsBatch(glyphIds: ReadonlyArray<number>, _format: Readonly<TextFormat>, out: GlyphExtents[]): number;
10
- export declare function getGlyphExtentsInto(glyphId: number, _format: Readonly<TextFormat>, out: GlyphExtents): boolean;
11
- export declare function getGlyphIndexForCodePoint(codePoint: number, _format: Readonly<TextFormat>): number;
12
- export declare function getGlyphName(glyphId: number, _format: Readonly<TextFormat>): string;
13
- export declare function shapeTextRun(text: string, format: Readonly<TextFormat>, options?: ShapeRunOptions): ShapedRun | null;
14
- export declare function shapeTextRunInto(text: string, format: Readonly<TextFormat>, out: ShapedRun, options?: ShapeRunOptions): boolean;
4
+ export declare function getCodePointForGlyph(glyphId: number, _format: Readonly<TextFormat>, host?: HasTextShaper): number;
5
+ export declare function getFontMetrics(format: Readonly<TextFormat>, host?: HasTextShaper): FontMetrics | null;
6
+ export declare function getFontMetricsInto(format: Readonly<TextFormat>, out: FontMetrics, host?: HasTextShaper): boolean;
7
+ export declare function getFontUnitScale(format: Readonly<TextFormat>, host?: HasTextShaper): number;
8
+ export declare function getGlyphExtents(glyphId: number, _format: Readonly<TextFormat>, host?: HasTextShaper): GlyphExtents | null;
9
+ export declare function getGlyphExtentsBatch(glyphIds: ReadonlyArray<number>, _format: Readonly<TextFormat>, out: GlyphExtents[], host?: HasTextShaper): number;
10
+ export declare function getGlyphExtentsInto(glyphId: number, _format: Readonly<TextFormat>, out: GlyphExtents, host?: HasTextShaper): boolean;
11
+ export declare function getGlyphIndexForCodePoint(codePoint: number, _format: Readonly<TextFormat>, host?: HasTextShaper): number;
12
+ export declare function getGlyphName(glyphId: number, _format: Readonly<TextFormat>, host?: HasTextShaper): string;
13
+ export declare function shapeTextRun(text: string, format: Readonly<TextFormat>, options?: ShapeRunOptions, host?: HasTextShaper): ShapedRun | null;
14
+ export declare function shapeTextRunInto(text: string, format: Readonly<TextFormat>, out: ShapedRun, options?: ShapeRunOptions, host?: HasTextShaper): boolean;
15
15
  //# sourceMappingURL=textShaperRun.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperRun.d.ts","sourceRoot":"","sources":["../src/textShaperRun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAIlH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAQxD;AAED,wBAAgB,eAAe,IAAI,SAAS,CAS3C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAI3F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,WAAW,GAAG,IAAI,CAI/E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAY1F;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAKrE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY,GAAG,IAAI,CAInG;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,GAAG,EAAE,YAAY,EAAE,GAClB,MAAM,CAcR;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAQ9G;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAIlG;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,CAInF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAIpH;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAgBT"}
1
+ {"version":3,"file":"textShaperRun.d.ts","sourceRoot":"","sources":["../src/textShaperRun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACX,MAAM,0BAA0B,CAAC;AAIlC,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAQxD;AAED,wBAAgB,eAAe,IAAI,SAAS,CAS3C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,MAAM,CAIjH;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,IAAI,CAIrG;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAYhH;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,MAAM,CAK3F;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,IAAI,CAAC,EAAE,aAAa,GACnB,YAAY,GAAG,IAAI,CAIrB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,GAAG,EAAE,YAAY,EAAE,EACnB,IAAI,CAAC,EAAE,aAAa,GACnB,MAAM,CAcR;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAQT;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,IAAI,CAAC,EAAE,aAAa,GACnB,MAAM,CAIR;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,MAAM,CAIzG;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,eAAe,EACzB,IAAI,CAAC,EAAE,aAAa,GACnB,SAAS,GAAG,IAAI,CAIlB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC5B,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,eAAe,EACzB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAgBT"}
@@ -18,20 +18,20 @@ export function createShapedRun() {
18
18
  script: '',
19
19
  };
20
20
  }
21
- export function getCodePointForGlyph(glyphId, _format) {
22
- const backend = getTextShaperBackend();
21
+ export function getCodePointForGlyph(glyphId, _format, host) {
22
+ const backend = getTextShaperBackend(host);
23
23
  if (backend === null || !backend.getCodePointForGlyph)
24
24
  return -1;
25
25
  return backend.getCodePointForGlyph(glyphId);
26
26
  }
27
- export function getFontMetrics(format) {
28
- const backend = getTextShaperBackend();
27
+ export function getFontMetrics(format, host) {
28
+ const backend = getTextShaperBackend(host);
29
29
  if (backend === null || !backend.getFontMetrics)
30
30
  return null;
31
31
  return backend.getFontMetrics(format);
32
32
  }
33
- export function getFontMetricsInto(format, out) {
34
- const metrics = getFontMetrics(format);
33
+ export function getFontMetricsInto(format, out, host) {
34
+ const metrics = getFontMetrics(format, host);
35
35
  if (metrics === null)
36
36
  return false;
37
37
  out.ascent = metrics.ascent;
@@ -44,21 +44,21 @@ export function getFontMetricsInto(format, out) {
44
44
  out.xHeight = metrics.xHeight;
45
45
  return true;
46
46
  }
47
- export function getFontUnitScale(format) {
48
- const metrics = getFontMetrics(format);
47
+ export function getFontUnitScale(format, host) {
48
+ const metrics = getFontMetrics(format, host);
49
49
  if (metrics === null)
50
50
  return -1;
51
51
  const size = format.size ?? 12;
52
52
  return size / metrics.unitsPerEm;
53
53
  }
54
- export function getGlyphExtents(glyphId, _format) {
55
- const backend = getTextShaperBackend();
54
+ export function getGlyphExtents(glyphId, _format, host) {
55
+ const backend = getTextShaperBackend(host);
56
56
  if (backend === null || !backend.getGlyphExtents)
57
57
  return null;
58
58
  return backend.getGlyphExtents(glyphId);
59
59
  }
60
- export function getGlyphExtentsBatch(glyphIds, _format, out) {
61
- const backend = getTextShaperBackend();
60
+ export function getGlyphExtentsBatch(glyphIds, _format, out, host) {
61
+ const backend = getTextShaperBackend(host);
62
62
  if (backend === null || !backend.getGlyphExtents)
63
63
  return 0;
64
64
  let resolved = 0;
@@ -74,8 +74,8 @@ export function getGlyphExtentsBatch(glyphIds, _format, out) {
74
74
  }
75
75
  return resolved;
76
76
  }
77
- export function getGlyphExtentsInto(glyphId, _format, out) {
78
- const extents = getGlyphExtents(glyphId, _format);
77
+ export function getGlyphExtentsInto(glyphId, _format, out, host) {
78
+ const extents = getGlyphExtents(glyphId, _format, host);
79
79
  if (extents === null)
80
80
  return false;
81
81
  out.height = extents.height;
@@ -84,26 +84,26 @@ export function getGlyphExtentsInto(glyphId, _format, out) {
84
84
  out.yBearing = extents.yBearing;
85
85
  return true;
86
86
  }
87
- export function getGlyphIndexForCodePoint(codePoint, _format) {
88
- const backend = getTextShaperBackend();
87
+ export function getGlyphIndexForCodePoint(codePoint, _format, host) {
88
+ const backend = getTextShaperBackend(host);
89
89
  if (backend === null || !backend.getGlyphIndexForCodePoint)
90
90
  return -1;
91
91
  return backend.getGlyphIndexForCodePoint(codePoint);
92
92
  }
93
- export function getGlyphName(glyphId, _format) {
94
- const backend = getTextShaperBackend();
93
+ export function getGlyphName(glyphId, _format, host) {
94
+ const backend = getTextShaperBackend(host);
95
95
  if (backend === null || !backend.getGlyphName)
96
96
  return '';
97
97
  return backend.getGlyphName(glyphId);
98
98
  }
99
- export function shapeTextRun(text, format, options) {
100
- const backend = getTextShaperBackend();
99
+ export function shapeTextRun(text, format, options, host) {
100
+ const backend = getTextShaperBackend(host);
101
101
  if (backend === null || !backend.shapeRun)
102
102
  return null;
103
103
  return backend.shapeRun(text, format, options);
104
104
  }
105
- export function shapeTextRunInto(text, format, out, options) {
106
- const backend = getTextShaperBackend();
105
+ export function shapeTextRunInto(text, format, out, options, host) {
106
+ const backend = getTextShaperBackend(host);
107
107
  if (backend === null || !backend.shapeRun)
108
108
  return false;
109
109
  const result = backend.shapeRun(text, format, options);
@@ -1 +1 @@
1
- {"version":3,"file":"textShaperRun.js","sourceRoot":"","sources":["../src/textShaperRun.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"textShaperRun.js","sourceRoot":"","sources":["../src/textShaperRun.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,UAAU,cAAc,CAAC,GAAc;IAC3C,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC;IACrB,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC;IAC9B,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAChB,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC;IACnB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACtB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,CAAC;QACb,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,OAA6B,EAAE,IAAoB;IACvG,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB;QAAE,OAAO,CAAC,CAAC,CAAC;IACjE,OAAO,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAA4B,EAAE,IAAoB;IAC/E,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAA4B,EAAE,GAAgB,EAAE,IAAoB;IACrG,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAClC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC9B,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC9B,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAClD,GAAG,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACpD,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACpC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAA4B,EAAE,IAAoB;IACjF,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/B,OAAO,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,OAA6B,EAC7B,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAC9D,OAAO,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,QAA+B,EAC/B,OAA6B,EAC7B,GAAmB,EACnB,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe;QAAE,OAAO,CAAC,CAAC;IAC3D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;YACjB,QAAQ,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,OAA6B,EAC7B,GAAiB,EACjB,IAAoB;IAEpB,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC1B,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAChC,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAChC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,SAAiB,EACjB,OAA6B,EAC7B,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,yBAAyB;QAAE,OAAO,CAAC,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,OAA6B,EAAE,IAAoB;IAC/F,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IACzD,OAAO,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,MAA4B,EAC5B,OAAyB,EACzB,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,MAA4B,EAC5B,GAAc,EACd,OAAyB,EACzB,IAAoB;IAEpB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IACvC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACjC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACvB,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACnC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3B,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACpB,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/textshaper",
3
- "version": "0.5.1-next.704.19c91ec",
3
+ "version": "0.5.1-next.730.f29a5aa",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,9 +38,9 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/log": "0.5.1-next.704.19c91ec",
42
- "@flighthq/signals": "0.5.1-next.704.19c91ec",
43
- "@flighthq/types": "0.5.1-next.704.19c91ec"
41
+ "@flighthq/log": "0.5.1-next.730.f29a5aa",
42
+ "@flighthq/signals": "0.5.1-next.730.f29a5aa",
43
+ "@flighthq/types": "0.5.1-next.730.f29a5aa"
44
44
  },
45
45
  "devDependencies": {
46
46
  "typescript": "^5.3.0"
@@ -1,4 +1,4 @@
1
- import type { TextShaperBackend, TextShaperOperation } from '@flighthq/types/contract';
1
+ import type { HasTextShaper, TextFormat, TextShaperBackend, TextShaperOperation } from '@flighthq/types/contract';
2
2
 
3
3
  import {
4
4
  explainTextShaperOperation,
@@ -39,9 +39,27 @@ describe('explainTextShaperOperation', () => {
39
39
  setTextShaperBackend({ ...partialBackend(), [operation]: () => undefined } as TextShaperBackend);
40
40
  expect(explainTextShaperOperation(operation)).toEqual({ implemented: true, layer: 'custom', operation });
41
41
  });
42
+
43
+ it('reports an explicitly supplied provider as the host layer', () => {
44
+ const operation = OPTIONAL_OPERATIONS[0];
45
+ const backend = { ...partialBackend(), [operation]: () => undefined } as TextShaperBackend;
46
+ setTextShaperBackend(partialBackend());
47
+ expect(explainTextShaperOperation(operation, shaperHost(backend))).toEqual({
48
+ implemented: true,
49
+ layer: 'host',
50
+ operation,
51
+ });
52
+ });
42
53
  });
43
54
 
44
55
  describe('getTextShaperBackend', () => {
56
+ it('returns an explicit host provider ahead of the legacy backend', () => {
57
+ const legacy: TextShaperBackend = { measureText: () => 1 };
58
+ const explicit: TextShaperBackend = { measureText: () => 2 };
59
+ setTextShaperBackend(legacy);
60
+ expect(getTextShaperBackend(shaperHost(explicit))).toBe(explicit);
61
+ });
62
+
45
63
  it('returns null before a backend is set', () => {
46
64
  expect(getTextShaperBackend()).toBeNull();
47
65
  });
@@ -73,6 +91,25 @@ const OPTIONAL_OPERATIONS: readonly TextShaperOperation[] = [
73
91
  ];
74
92
 
75
93
  describe('measureText', () => {
94
+ it('accepts an optional explicit shaper host without breaking the existing signature', () => {
95
+ expectTypeOf(measureText).toEqualTypeOf<
96
+ (text: string, format: Readonly<TextFormat>, host?: HasTextShaper) => number
97
+ >();
98
+ });
99
+
100
+ it('gives an explicit host precedence over the legacy installed backend', () => {
101
+ setTextShaperBackend({ measureText: () => 99 });
102
+ expect(measureText('abc', {}, shaperHost({ measureText: (text) => text.length }))).toBe(3);
103
+ });
104
+
105
+ it('isolates callers that interleave different explicit hosts', () => {
106
+ const first = shaperHost({ measureText: () => 1 });
107
+ const second = shaperHost({ measureText: () => 2 });
108
+ expect(measureText('x', {}, first)).toBe(1);
109
+ expect(measureText('x', {}, second)).toBe(2);
110
+ expect(measureText('x', {}, first)).toBe(1);
111
+ });
112
+
76
113
  it('returns -1 when no backend is registered', () => {
77
114
  expect(measureText('hello', {})).toBe(-1);
78
115
  });
@@ -107,3 +144,7 @@ function partialBackend(): TextShaperBackend {
107
144
  measureText: (() => undefined) as never,
108
145
  } as TextShaperBackend;
109
146
  }
147
+
148
+ function shaperHost(shaper: TextShaperBackend): HasTextShaper {
149
+ return { text: { shaper } };
150
+ }
@@ -1,4 +1,4 @@
1
- import type { ShapedRun, TextShaperBackend } from '@flighthq/types/contract';
1
+ import type { HasTextShaper, ShapedRun, TextShaperBackend } from '@flighthq/types/contract';
2
2
 
3
3
  import { setTextShaperBackend } from './textShaper';
4
4
  import {
@@ -82,6 +82,15 @@ describe('disposeTextShaperCache', () => {
82
82
  });
83
83
 
84
84
  describe('shapeTextRunCached', () => {
85
+ it('keeps cache entries isolated when callers interleave explicit hosts', () => {
86
+ const cache = createTextShaperCache();
87
+ const first = _hostWithAdvance(1);
88
+ const second = _hostWithAdvance(2);
89
+ expect(shapeTextRunCached(cache, 'hi', {}, undefined, first)?.advanceWidth).toBe(1);
90
+ expect(shapeTextRunCached(cache, 'hi', {}, undefined, second)?.advanceWidth).toBe(2);
91
+ expect(shapeTextRunCached(cache, 'hi', {}, undefined, first)?.advanceWidth).toBe(1);
92
+ });
93
+
85
94
  it('returns null when no backend is set', () => {
86
95
  const cache = createTextShaperCache();
87
96
  expect(shapeTextRunCached(cache, 'hi', {})).toBeNull();
@@ -159,3 +168,14 @@ describe('shapeTextRunCached', () => {
159
168
  expect(cache._entries.size).toBe(1);
160
169
  });
161
170
  });
171
+
172
+ function _hostWithAdvance(advanceWidth: number): HasTextShaper {
173
+ return {
174
+ text: {
175
+ shaper: {
176
+ measureText: () => advanceWidth,
177
+ shapeRun: () => ({ ..._stubRun, advanceWidth }),
178
+ },
179
+ },
180
+ };
181
+ }
@@ -1,4 +1,4 @@
1
- import type { ShapedRun, ShapeRunOptions, TextFormat } from '@flighthq/types/contract';
1
+ import type { HasTextShaper, ShapedRun, ShapeRunOptions, TextFormat } from '@flighthq/types/contract';
2
2
 
3
3
  import { setTextShaperBackend } from './textShaper';
4
4
  import { itemizeText, shapeTextRuns } from './textShaperItemize';
@@ -78,6 +78,12 @@ describe('itemizeText', () => {
78
78
  });
79
79
 
80
80
  describe('shapeTextRuns', () => {
81
+ it('threads an explicit host to every shaped item', () => {
82
+ const host: HasTextShaper = { text: { shaper: _makeShapingBackend() } };
83
+ setTextShaperBackend({ measureText: () => 0 });
84
+ expect(shapeTextRuns('ABسلام', {}, undefined, host)).toHaveLength(2);
85
+ });
86
+
81
87
  it('returns empty array for empty string', () => {
82
88
  expect(shapeTextRuns('', {})).toEqual([]);
83
89
  });
@@ -1,4 +1,4 @@
1
- import type { FontMetrics, GlyphExtents, ShapedRun, TextShaperBackend } from '@flighthq/types/contract';
1
+ import type { FontMetrics, GlyphExtents, HasTextShaper, ShapedRun, TextShaperBackend } from '@flighthq/types/contract';
2
2
 
3
3
  import { setTextShaperBackend } from './textShaper';
4
4
  import {
@@ -290,6 +290,12 @@ describe('getGlyphName', () => {
290
290
  });
291
291
 
292
292
  describe('shapeTextRun', () => {
293
+ it('uses the explicitly supplied host instead of the legacy installed backend', () => {
294
+ setTextShaperBackend({ measureText: () => 0 });
295
+ const host: HasTextShaper = { text: { shaper: _makeFullBackend() } };
296
+ expect(shapeTextRun('ab', {}, undefined, host)?.glyphCount).toBe(2);
297
+ });
298
+
293
299
  it('returns null when no backend is set', () => {
294
300
  expect(shapeTextRun('hi', {})).toBeNull();
295
301
  });