text-shaper 0.1.1 → 0.1.3

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.
Files changed (77) hide show
  1. package/README.md +1 -0
  2. package/dist/aat/state-machine.d.ts +18 -6
  3. package/dist/buffer/glyph-buffer.d.ts +35 -1
  4. package/dist/buffer/unicode-buffer.d.ts +2 -0
  5. package/dist/fluent/bitmap-builder.d.ts +146 -0
  6. package/dist/fluent/index.d.ts +102 -0
  7. package/dist/fluent/path-builder.d.ts +230 -0
  8. package/dist/fluent/pipe.d.ts +200 -0
  9. package/dist/fluent/types.d.ts +93 -0
  10. package/dist/font/face.d.ts +2 -0
  11. package/dist/font/font.d.ts +14 -0
  12. package/dist/font/tables/cff.d.ts +3 -1
  13. package/dist/font/tables/colr.d.ts +4 -1
  14. package/dist/font/tables/fvar.d.ts +3 -1
  15. package/dist/font/tables/glyf.d.ts +13 -0
  16. package/dist/font/tables/gpos.d.ts +9 -1
  17. package/dist/font/tables/gsub.d.ts +11 -0
  18. package/dist/font/tables/gvar.d.ts +10 -1
  19. package/dist/font/tables/head.d.ts +5 -0
  20. package/dist/font/tables/hhea.d.ts +5 -0
  21. package/dist/font/tables/loca.d.ts +3 -0
  22. package/dist/font/tables/maxp.d.ts +5 -0
  23. package/dist/font/tables/name.d.ts +5 -0
  24. package/dist/font/tables/os2.d.ts +5 -0
  25. package/dist/font/tables/post.d.ts +5 -0
  26. package/dist/index.d.ts +12 -5
  27. package/dist/index.js +12 -10
  28. package/dist/index.js.map +104 -93
  29. package/dist/layout/justify.d.ts +15 -2
  30. package/dist/layout/structures/class-def.d.ts +61 -8
  31. package/dist/layout/structures/coverage.d.ts +57 -10
  32. package/dist/layout/structures/device.d.ts +26 -5
  33. package/dist/layout/structures/layout-common.d.ts +18 -3
  34. package/dist/layout/structures/set-digest.d.ts +59 -0
  35. package/dist/perf/benchmark-runner-eksh2b26.js +0 -0
  36. package/dist/perf/benchmark-runner.html +517 -0
  37. package/dist/perf/comparison-tests.js +22676 -0
  38. package/dist/perf/comparison-tests.js.map +111 -0
  39. package/dist/perf/cpu/cpu-perf.js +21920 -0
  40. package/dist/perf/cpu/cpu-perf.js.map +108 -0
  41. package/dist/perf/gpu/webgl-perf.js +470 -0
  42. package/dist/perf/gpu/webgl-perf.js.map +11 -0
  43. package/dist/perf/gpu/webgpu-perf.js +442 -0
  44. package/dist/perf/gpu/webgpu-perf.js.map +11 -0
  45. package/dist/perf/index.html +258 -0
  46. package/dist/perf/module-loader.js +18 -0
  47. package/dist/perf/utils/perf-utils.js +170 -0
  48. package/dist/perf/utils/perf-utils.js.map +10 -0
  49. package/dist/raster/asymmetric-stroke.d.ts +61 -0
  50. package/dist/raster/bitmap-utils.d.ts +124 -0
  51. package/dist/raster/blur.d.ts +11 -0
  52. package/dist/raster/cascade-blur.d.ts +44 -0
  53. package/dist/raster/cell.d.ts +24 -0
  54. package/dist/raster/fixed-point.d.ts +1 -1
  55. package/dist/raster/gradient.d.ts +15 -0
  56. package/dist/raster/gray-raster.d.ts +7 -1
  57. package/dist/raster/lcd-filter.d.ts +15 -0
  58. package/dist/raster/msdf.d.ts +135 -0
  59. package/dist/raster/outline-decompose.d.ts +16 -17
  60. package/dist/raster/rasterize.d.ts +19 -2
  61. package/dist/raster/sdf.d.ts +3 -0
  62. package/dist/raster/stroker.d.ts +3 -0
  63. package/dist/raster/types.d.ts +24 -0
  64. package/dist/render/outline-transform.d.ts +169 -0
  65. package/dist/render/path.d.ts +56 -1
  66. package/dist/shaper/complex/arabic.d.ts +1 -0
  67. package/dist/shaper/shape-plan.d.ts +11 -8
  68. package/dist/shaper/shaper.d.ts +61 -3
  69. package/dist/unicode/bidi/brackets.d.ts +15 -0
  70. package/dist/unicode/bidi/char-types.d.ts +4 -0
  71. package/dist/unicode/bidi/embedding-levels.d.ts +3 -0
  72. package/dist/unicode/bidi/mirroring.d.ts +10 -0
  73. package/dist/unicode/bidi/reordering.d.ts +15 -0
  74. package/dist/unicode/normalize.d.ts +23 -0
  75. package/dist/unicode/script.d.ts +17 -0
  76. package/dist/unicode/segmentation.d.ts +18 -0
  77. package/package.json +12 -3
@@ -64,10 +64,16 @@ export interface JustifyAdjustment {
64
64
  }
65
65
  /**
66
66
  * Calculate current line width from glyph buffer
67
+ * @param buffer - The glyph buffer to measure
68
+ * @returns Total line width in font units (sum of all xAdvance values)
67
69
  */
68
70
  export declare function calculateLineWidth(buffer: GlyphBuffer): number;
69
71
  /**
70
72
  * Justify a shaped glyph buffer to fit a target width
73
+ * @param font - The font containing JSTF and glyph metrics
74
+ * @param buffer - The shaped glyph buffer to justify (modified in place)
75
+ * @param options - Justification options including target width and mode
76
+ * @returns Result containing success status, final width, and applied adjustments
71
77
  */
72
78
  export declare function justify(font: Font, buffer: GlyphBuffer, options: JustifyOptions): JustifyResult;
73
79
  /**
@@ -78,11 +84,18 @@ export interface LineBreakResult {
78
84
  breakPoints: number[];
79
85
  }
80
86
  /**
81
- * Break shaped text into lines at a given width
82
- * Uses simple greedy algorithm
87
+ * Break shaped text into lines at a given width using simple greedy algorithm
88
+ * @param buffer - The shaped glyph buffer to break into lines
89
+ * @param maxWidth - Maximum line width in font units
90
+ * @param spaceGlyph - Optional glyph ID of space character for word boundary detection
91
+ * @returns Object containing array of line buffers and break point indices
83
92
  */
84
93
  export declare function breakIntoLines(buffer: GlyphBuffer, maxWidth: number, spaceGlyph?: GlyphId): LineBreakResult;
85
94
  /**
86
95
  * Justify all lines in a paragraph to the same width
96
+ * @param font - The font containing JSTF and glyph metrics
97
+ * @param lines - Array of glyph buffers representing lines (modified in place)
98
+ * @param options - Justification options including target width and mode
99
+ * @returns Array of justification results, one per line
87
100
  */
88
101
  export declare function justifyParagraph(font: Font, lines: GlyphBuffer[], options: JustifyOptions): JustifyResult[];
@@ -1,15 +1,68 @@
1
1
  import type { Reader } from "../../font/binary/reader.ts";
2
- import type { GlyphId } from "../../types.ts";
3
- /** Class Definition table - maps glyph IDs to class values */
4
- export interface ClassDef {
5
- /** Get class for a glyph ID (returns 0 if not defined) */
2
+ import type { GlyphId, uint16 } from "../../types.ts";
3
+ /** Class range record for Format 2 */
4
+ interface ClassRangeRecord {
5
+ startGlyphId: GlyphId;
6
+ endGlyphId: GlyphId;
7
+ classValue: uint16;
8
+ }
9
+ /**
10
+ * Class Definition table - maps glyph IDs to class values.
11
+ *
12
+ * IMPORTANT: This is a unified class (not interface + implementations) to ensure
13
+ * monomorphic call sites in V8. Polymorphic calls can be 7-8x slower!
14
+ */
15
+ export declare class ClassDef {
16
+ private readonly startGlyphId;
17
+ private readonly classValueArray;
18
+ private readonly ranges;
19
+ private readonly glyphMap;
20
+ private readonly isEmpty;
21
+ private constructor();
22
+ /**
23
+ * Create an empty ClassDef
24
+ * @returns Empty ClassDef instance where all glyphs return class 0
25
+ */
26
+ static empty(): ClassDef;
27
+ /**
28
+ * Create Format 1 ClassDef (array of class values)
29
+ * @param startGlyphId - First glyph ID in the range
30
+ * @param classValueArray - Array of class values indexed by (glyphId - startGlyphId)
31
+ * @returns ClassDef instance using array lookup
32
+ */
33
+ static format1(startGlyphId: GlyphId, classValueArray: Uint16Array): ClassDef;
34
+ /**
35
+ * Create Format 2 ClassDef (ranges)
36
+ * @param ranges - Array of range records mapping glyph ranges to class values
37
+ * @returns ClassDef instance using hash map (for small tables) or binary search (for large tables)
38
+ */
39
+ static format2(ranges: ClassRangeRecord[]): ClassDef;
40
+ /**
41
+ * Get class for a glyph ID
42
+ * @param glyphId - The glyph ID to look up
43
+ * @returns Class value for the glyph, or 0 if not defined
44
+ */
6
45
  get(glyphId: GlyphId): number;
7
- /** Get all glyphs in a specific class */
46
+ /**
47
+ * Get all glyphs in a specific class
48
+ * @param classValue - The class value to search for
49
+ * @returns Array of all glyph IDs assigned to this class
50
+ */
8
51
  glyphsInClass(classValue: number): GlyphId[];
9
52
  }
10
- /** Singleton empty ClassDef */
53
+ /** Singleton empty ClassDef for external use */
11
54
  export declare const EMPTY_CLASS_DEF: ClassDef;
12
- /** Parse a Class Definition table */
55
+ /**
56
+ * Parse a Class Definition table from binary data
57
+ * @param reader - Binary reader positioned at class definition table start
58
+ * @returns Parsed ClassDef instance (Format 1 or Format 2)
59
+ */
13
60
  export declare function parseClassDef(reader: Reader): ClassDef;
14
- /** Parse ClassDef from offset, or return empty if offset is 0 */
61
+ /**
62
+ * Parse ClassDef from offset, or return empty if offset is 0
63
+ * @param reader - Binary reader positioned at parent table
64
+ * @param offset - Offset from reader's current position to class definition table
65
+ * @returns Parsed ClassDef instance, or empty ClassDef if offset is 0
66
+ */
15
67
  export declare function parseClassDefAt(reader: Reader, offset: number): ClassDef;
68
+ export {};
@@ -1,17 +1,64 @@
1
1
  import type { Reader } from "../../font/binary/reader.ts";
2
- import type { GlyphId } from "../../types.ts";
3
- /** Coverage table - maps glyph IDs to coverage indices */
4
- export interface Coverage {
5
- /** Get coverage index for a glyph ID, or null if not covered */
2
+ import type { GlyphId, uint16 } from "../../types.ts";
3
+ /** Range record for Format 2 */
4
+ interface RangeRecord {
5
+ startGlyphId: GlyphId;
6
+ endGlyphId: GlyphId;
7
+ startCoverageIndex: uint16;
8
+ }
9
+ /**
10
+ * Coverage table - maps glyph IDs to coverage indices.
11
+ *
12
+ * IMPORTANT: This is a unified class (not interface + implementations) to ensure
13
+ * monomorphic call sites in V8. Polymorphic calls can be 7-8x slower!
14
+ */
15
+ export declare class Coverage {
16
+ private readonly glyphMap;
17
+ private readonly ranges;
18
+ private readonly glyphArray;
19
+ readonly size: number;
20
+ private constructor();
21
+ /**
22
+ * Create Format 1 coverage (individual glyphs)
23
+ * @param glyphArray - Array of glyph IDs to cover
24
+ * @returns Coverage instance using hash map for O(1) lookup
25
+ */
26
+ static format1(glyphArray: Uint16Array): Coverage;
27
+ /**
28
+ * Create Format 2 coverage (ranges)
29
+ * @param ranges - Array of range records defining covered glyph ranges
30
+ * @returns Coverage instance using binary search for range lookup
31
+ */
32
+ static format2(ranges: RangeRecord[]): Coverage;
33
+ /**
34
+ * Get coverage index for a glyph ID
35
+ * @param glyphId - The glyph ID to look up
36
+ * @returns Coverage index (0-based) if glyph is covered, null otherwise
37
+ */
6
38
  get(glyphId: GlyphId): number | null;
7
- /** Check if glyph is covered */
39
+ /**
40
+ * Check if glyph is covered
41
+ * @param glyphId - The glyph ID to check
42
+ * @returns True if the glyph is in this coverage table
43
+ */
8
44
  covers(glyphId: GlyphId): boolean;
9
- /** Get all covered glyph IDs */
45
+ /**
46
+ * Get all covered glyph IDs
47
+ * @returns Array of all glyph IDs in this coverage table
48
+ */
10
49
  glyphs(): GlyphId[];
11
- /** Number of covered glyphs */
12
- readonly size: number;
13
50
  }
14
- /** Parse a Coverage table */
51
+ /**
52
+ * Parse a Coverage table from binary data
53
+ * @param reader - Binary reader positioned at coverage table start
54
+ * @returns Parsed coverage instance (Format 1 or Format 2)
55
+ */
15
56
  export declare function parseCoverage(reader: Reader): Coverage;
16
- /** Parse Coverage from offset (creates sub-reader) */
57
+ /**
58
+ * Parse Coverage from offset (creates sub-reader)
59
+ * @param reader - Binary reader positioned at parent table
60
+ * @param offset - Offset from reader's current position to coverage table
61
+ * @returns Parsed coverage instance
62
+ */
17
63
  export declare function parseCoverageAt(reader: Reader, offset: number): Coverage;
64
+ export {};
@@ -18,20 +18,38 @@ export interface VariationIndexTable {
18
18
  }
19
19
  /** Combined type - can be either Device or VariationIndex */
20
20
  export type DeviceOrVariationIndex = DeviceTable | VariationIndexTable;
21
- /** Check if this is a VariationIndex table */
21
+ /**
22
+ * Check if this is a VariationIndex table
23
+ * @param table - The device or variation index table to check
24
+ * @returns True if the table is a VariationIndex table, false if it's a Device table
25
+ */
22
26
  export declare function isVariationIndexTable(table: DeviceOrVariationIndex): table is VariationIndexTable;
23
- /** Parse Device or VariationIndex table at offset */
27
+ /**
28
+ * Parse Device or VariationIndex table at offset
29
+ * @param reader - Binary reader positioned at the parent table
30
+ * @param offset - Offset from reader's current position to the device table
31
+ * @returns Parsed device or variation index table, or null if offset is 0
32
+ */
24
33
  export declare function parseDeviceAt(reader: Reader, offset: number): DeviceOrVariationIndex | null;
25
- /** Parse Device or VariationIndex table */
34
+ /**
35
+ * Parse Device or VariationIndex table
36
+ * @param reader - Binary reader positioned at the device table start
37
+ * @returns Parsed device or variation index table
38
+ */
26
39
  export declare function parseDevice(reader: Reader): DeviceOrVariationIndex;
27
40
  /**
28
41
  * Get delta adjustment for a specific PPEM size
29
- * Returns 0 if the size is outside the table's range
42
+ * @param device - The device table to query
43
+ * @param ppem - Pixels per em size to get delta for
44
+ * @returns Delta adjustment value, or 0 if PPEM is outside the table's range
30
45
  */
31
46
  export declare function getDeviceDelta(device: DeviceTable, ppem: number): int16;
32
47
  /**
33
48
  * Apply Device table adjustment to a value
34
- * For variable fonts, this would need ItemVariationStore lookup instead
49
+ * @param device - The device or variation index table, or null
50
+ * @param value - The base value to adjust
51
+ * @param ppem - Pixels per em size for device table lookup
52
+ * @returns Adjusted value (for Device tables) or unchanged value (for VariationIndex tables or null)
35
53
  */
36
54
  export declare function applyDeviceAdjustment(device: DeviceOrVariationIndex | null, value: number, ppem: number): number;
37
55
  /**
@@ -49,6 +67,9 @@ export interface ResolvedValueRecord {
49
67
  }
50
68
  /**
51
69
  * Apply all Device adjustments to a resolved value record
70
+ * @param record - The value record containing placement and advance values with device tables
71
+ * @param ppem - Pixels per em size for device table lookups
72
+ * @returns Object containing adjusted xPlacement, yPlacement, xAdvance, and yAdvance values
52
73
  */
53
74
  export declare function applyDeviceAdjustments(record: ResolvedValueRecord, ppem: number): {
54
75
  xPlacement: number;
@@ -69,9 +69,24 @@ export declare function parseScriptList(reader: Reader): ScriptList;
69
69
  export declare function parseFeatureList(reader: Reader): FeatureList;
70
70
  /** Parse lookup headers (does not parse subtables) */
71
71
  export declare function parseLookupHeaders(reader: Reader): LookupHeader[];
72
- /** Find script in script list */
72
+ /**
73
+ * Find script in script list by tag
74
+ * @param scriptList - The script list to search
75
+ * @param scriptTag - The script tag to find (e.g., 'latn', 'arab')
76
+ * @returns The script table if found, null otherwise
77
+ */
73
78
  export declare function findScript(scriptList: ScriptList, scriptTag: Tag): Script | null;
74
- /** Find language system in script */
79
+ /**
80
+ * Find language system in script by tag
81
+ * @param script - The script table to search
82
+ * @param langSysTag - The language system tag to find (e.g., 'ENG', 'ARA'), or null for default
83
+ * @returns The language system table if found, or the default language system if langSysTag is null or not found
84
+ */
75
85
  export declare function findLangSys(script: Script, langSysTag: Tag | null): LangSys | null;
76
- /** Get feature by index */
86
+ /**
87
+ * Get feature by index from feature list
88
+ * @param featureList - The feature list to retrieve from
89
+ * @param index - The zero-based feature index
90
+ * @returns The feature record at the specified index, or null if index is out of bounds
91
+ */
77
92
  export declare function getFeature(featureList: FeatureList, index: number): FeatureRecord | null;
@@ -0,0 +1,59 @@
1
+ import type { GlyphId } from "../../types.ts";
2
+ import type { Coverage } from "./coverage.ts";
3
+ /**
4
+ * Set Digest - A Bloom filter for fast O(1) glyph membership rejection.
5
+ *
6
+ * Uses three 64-bit masks with different bit shifts (0, 4, 9) to minimize
7
+ * false positives. This is the same technique used by HarfBuzz/rustybuzz.
8
+ *
9
+ * The digest allows us to quickly reject glyphs that are definitely NOT
10
+ * in a lookup's coverage without doing expensive Coverage table lookups.
11
+ */
12
+ export declare class SetDigest {
13
+ private mask0;
14
+ private mask1;
15
+ private mask2;
16
+ /**
17
+ * Add a single glyph to the digest
18
+ * @param glyphId - The glyph ID to add
19
+ */
20
+ add(glyphId: GlyphId): void;
21
+ /**
22
+ * Add a range of glyphs to the digest
23
+ * @param start - Start glyph ID (inclusive)
24
+ * @param end - End glyph ID (inclusive)
25
+ */
26
+ addRange(start: GlyphId, end: GlyphId): void;
27
+ /**
28
+ * Fast check if glyph MAY be in the set
29
+ * @param glyphId - The glyph ID to check
30
+ * @returns False if glyph is definitely NOT in the set, true if glyph MAY be in the set (false positives possible)
31
+ */
32
+ mayHave(glyphId: GlyphId): boolean;
33
+ /**
34
+ * Add all glyphs from a Coverage table to this digest
35
+ * @param coverage - The coverage table containing glyphs to add
36
+ */
37
+ addCoverage(coverage: Coverage): void;
38
+ /**
39
+ * Check if this digest MAY intersect with another digest
40
+ * @param other - The other digest to check intersection with
41
+ * @returns False if there is definitely NO overlap, true if there MAY be overlap (false positives possible)
42
+ */
43
+ mayIntersect(other: SetDigest): boolean;
44
+ /**
45
+ * Get raw masks for external comparison
46
+ * @returns Object containing the three internal mask values
47
+ */
48
+ getMasks(): {
49
+ mask0: number;
50
+ mask1: number;
51
+ mask2: number;
52
+ };
53
+ }
54
+ /**
55
+ * Create a SetDigest from multiple Coverage tables (for a lookup with multiple subtables)
56
+ * @param coverages - Array of coverage tables to combine into a single digest
57
+ * @returns A new SetDigest containing all glyphs from all coverage tables
58
+ */
59
+ export declare function createLookupDigest(coverages: Coverage[]): SetDigest;
File without changes