text-shaper 0.1.2 → 0.1.4

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 (64) hide show
  1. package/README.md +413 -38
  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/brotli/decode.d.ts +42 -0
  11. package/dist/font/face.d.ts +2 -0
  12. package/dist/font/font.d.ts +14 -0
  13. package/dist/font/tables/cff.d.ts +3 -1
  14. package/dist/font/tables/cff2.d.ts +63 -0
  15. package/dist/font/tables/colr.d.ts +4 -1
  16. package/dist/font/tables/fvar.d.ts +3 -1
  17. package/dist/font/tables/glyf.d.ts +13 -0
  18. package/dist/font/tables/gpos.d.ts +24 -1
  19. package/dist/font/tables/gsub.d.ts +20 -0
  20. package/dist/font/tables/gvar.d.ts +10 -1
  21. package/dist/font/tables/head.d.ts +5 -0
  22. package/dist/font/tables/hhea.d.ts +5 -0
  23. package/dist/font/tables/loca.d.ts +3 -0
  24. package/dist/font/tables/maxp.d.ts +5 -0
  25. package/dist/font/tables/name.d.ts +5 -0
  26. package/dist/font/tables/os2.d.ts +5 -0
  27. package/dist/font/tables/post.d.ts +5 -0
  28. package/dist/index.d.ts +5 -3
  29. package/dist/index.js +12 -10
  30. package/dist/index.js.map +105 -99
  31. package/dist/layout/justify.d.ts +15 -2
  32. package/dist/layout/structures/class-def.d.ts +61 -8
  33. package/dist/layout/structures/coverage.d.ts +57 -10
  34. package/dist/layout/structures/device.d.ts +26 -5
  35. package/dist/layout/structures/layout-common.d.ts +18 -3
  36. package/dist/layout/structures/set-digest.d.ts +59 -0
  37. package/dist/raster/asymmetric-stroke.d.ts +9 -5
  38. package/dist/raster/bitmap-utils.d.ts +67 -0
  39. package/dist/raster/blur.d.ts +11 -0
  40. package/dist/raster/cascade-blur.d.ts +9 -10
  41. package/dist/raster/cell.d.ts +24 -0
  42. package/dist/raster/fixed-point.d.ts +1 -1
  43. package/dist/raster/gradient.d.ts +15 -0
  44. package/dist/raster/gray-raster.d.ts +7 -1
  45. package/dist/raster/lcd-filter.d.ts +15 -0
  46. package/dist/raster/msdf.d.ts +27 -5
  47. package/dist/raster/outline-decompose.d.ts +16 -17
  48. package/dist/raster/rasterize.d.ts +19 -2
  49. package/dist/raster/sdf.d.ts +3 -0
  50. package/dist/raster/stroker.d.ts +3 -0
  51. package/dist/raster/types.d.ts +9 -0
  52. package/dist/render/path.d.ts +56 -1
  53. package/dist/shaper/complex/arabic.d.ts +1 -0
  54. package/dist/shaper/shape-plan.d.ts +11 -8
  55. package/dist/shaper/shaper.d.ts +189 -4
  56. package/dist/unicode/bidi/brackets.d.ts +15 -0
  57. package/dist/unicode/bidi/char-types.d.ts +4 -0
  58. package/dist/unicode/bidi/embedding-levels.d.ts +3 -0
  59. package/dist/unicode/bidi/mirroring.d.ts +10 -0
  60. package/dist/unicode/bidi/reordering.d.ts +15 -0
  61. package/dist/unicode/normalize.d.ts +23 -0
  62. package/dist/unicode/script.d.ts +17 -0
  63. package/dist/unicode/segmentation.d.ts +18 -0
  64. package/package.json +11 -2
@@ -35,10 +35,25 @@ export declare enum LcdMode {
35
35
  * 1. Render at 3x horizontal resolution
36
36
  * 2. Apply FIR filter to reduce color fringing
37
37
  * 3. Output RGB values per pixel
38
+ *
39
+ * @param path Glyph path to rasterize
40
+ * @param width Width in pixels
41
+ * @param height Height in pixels
42
+ * @param scale Scale factor from font units to pixels
43
+ * @param offsetX X offset in pixels
44
+ * @param offsetY Y offset in pixels
45
+ * @param mode LCD subpixel mode (RGB, BGR, RGB_V, BGR_V)
46
+ * @param filterWeights FIR filter coefficients for reducing color fringing
47
+ * @returns Bitmap with LCD subpixel data (3 bytes per pixel)
38
48
  */
39
49
  export declare function rasterizeLcd(path: GlyphPath, width: number, height: number, scale: number, offsetX: number, offsetY: number, mode?: LcdMode, filterWeights?: number[]): Bitmap;
40
50
  /**
41
51
  * Convert LCD bitmap to RGBA for display
42
52
  * Uses gamma-corrected blending against a background color
53
+ *
54
+ * @param lcd LCD bitmap to convert
55
+ * @param bgColor Background color as RGB (0-255 each)
56
+ * @param fgColor Foreground color as RGB (0-255 each)
57
+ * @returns RGBA pixel array (4 bytes per pixel)
43
58
  */
44
59
  export declare function lcdToRGBA(lcd: Bitmap, bgColor?: [number, number, number], fgColor?: [number, number, number]): Uint8Array;
@@ -29,27 +29,36 @@ export interface Point {
29
29
  */
30
30
  export type EdgeColor = 0 | 1 | 2;
31
31
  /**
32
- * An edge with color assignment
32
+ * Bounding box for edge culling
33
33
  */
34
- export type MsdfEdge = {
34
+ interface EdgeBounds {
35
+ minX: number;
36
+ maxX: number;
37
+ minY: number;
38
+ maxY: number;
39
+ }
40
+ /**
41
+ * An edge with color assignment and bounding box
42
+ */
43
+ export type MsdfEdge = ({
35
44
  type: "line";
36
45
  p0: Point;
37
46
  p1: Point;
38
47
  color: EdgeColor;
39
- } | {
48
+ } & EdgeBounds) | ({
40
49
  type: "quadratic";
41
50
  p0: Point;
42
51
  p1: Point;
43
52
  p2: Point;
44
53
  color: EdgeColor;
45
- } | {
54
+ } & EdgeBounds) | ({
46
55
  type: "cubic";
47
56
  p0: Point;
48
57
  p1: Point;
49
58
  p2: Point;
50
59
  p3: Point;
51
60
  color: EdgeColor;
52
- };
61
+ } & EdgeBounds);
53
62
  /**
54
63
  * Signed distance result with parameter t
55
64
  */
@@ -99,6 +108,18 @@ export declare function signedDistanceToCubic(px: number, py: number, p0: Point,
99
108
  * At sharp corners, adjacent edges get different colors
100
109
  */
101
110
  export declare function assignEdgeColors(contours: MsdfEdge[][]): void;
111
+ /**
112
+ * Compute signed distance from point to edge
113
+ */
114
+ export declare function signedDistanceToEdge(px: number, py: number, edge: MsdfEdge): SignedDistanceResult;
115
+ /**
116
+ * Determine if a point is inside using ray casting (even-odd rule)
117
+ */
118
+ export declare function isPointInside(px: number, py: number, contours: MsdfEdge[][]): boolean;
119
+ /**
120
+ * Flatten an edge to points for inside testing
121
+ */
122
+ export declare function flattenEdge(edge: MsdfEdge): Point[];
102
123
  /**
103
124
  * Render a glyph path as a multi-channel signed distance field
104
125
  */
@@ -123,3 +144,4 @@ export declare function msdfAtlasToRGB(atlas: GlyphAtlas): Uint8Array;
123
144
  * Export MSDF atlas as RGBA texture data
124
145
  */
125
146
  export declare function msdfAtlasToRGBA(atlas: GlyphAtlas): Uint8Array;
147
+ export {};
@@ -22,28 +22,28 @@ export interface ValidationResult {
22
22
  }
23
23
  /**
24
24
  * Validate a GlyphPath before rasterization (like FreeType's outline validation)
25
- *
26
- * Checks:
27
- * - Path is not null/undefined
28
- * - Commands array exists
29
- * - Path is not empty (unless allowEmpty is true)
30
- * - Command structure is valid
31
- * - Contours are properly closed (start with M, end with Z)
25
+ * Checks: path existence, command structure validity, and proper contour closure
26
+ * @param path Glyph path to validate
27
+ * @param allowEmpty Whether empty paths are considered valid (default: true)
28
+ * @returns Validation result with error code and optional message
32
29
  */
33
30
  export declare function validateOutline(path: GlyphPath | null | undefined, allowEmpty?: boolean): ValidationResult;
34
31
  /**
35
32
  * Convert a GlyphPath to rasterizer commands
36
- *
37
- * @param raster - The rasterizer instance
38
- * @param path - Path commands to decompose
39
- * @param scale - Scale factor (font units to pixels)
40
- * @param offsetX - X offset in pixels
41
- * @param offsetY - Y offset in pixels
42
- * @param flipY - Flip Y axis (font coords are Y-up)
33
+ * @param raster The rasterizer instance to receive commands
34
+ * @param path Path commands to decompose
35
+ * @param scale Scale factor (font units to pixels)
36
+ * @param offsetX X offset in pixels (default: 0)
37
+ * @param offsetY Y offset in pixels (default: 0)
38
+ * @param flipY Flip Y axis - font coords are Y-up, bitmap is Y-down (default: true)
43
39
  */
44
40
  export declare function decomposePath(raster: GrayRaster, path: GlyphPath, scale: number, offsetX?: number, offsetY?: number, flipY?: boolean): void;
45
41
  /**
46
42
  * Calculate bounding box of path in pixel coordinates
43
+ * @param path Glyph path to measure
44
+ * @param scale Scale factor (font units to pixels)
45
+ * @param flipY Flip Y axis for bitmap coordinates (default: true)
46
+ * @returns Bounding box in pixel coordinates, or null if path has no bounds
47
47
  */
48
48
  export declare function getPathBounds(path: GlyphPath, scale: number, flipY?: boolean): {
49
49
  minX: number;
@@ -53,9 +53,8 @@ export declare function getPathBounds(path: GlyphPath, scale: number, flipY?: bo
53
53
  } | null;
54
54
  /**
55
55
  * Get fill rule from outline flags (like FreeType's FT_OUTLINE_EVEN_ODD_FILL check)
56
- *
57
56
  * @param path Path with optional flags
58
- * @param defaultRule Default fill rule if flags not set
59
- * @returns Fill rule to use
57
+ * @param defaultRule Default fill rule if flags not set (default: NonZero)
58
+ * @returns Fill rule to use for rendering
60
59
  */
61
60
  export declare function getFillRuleFromFlags(path: GlyphPath | null | undefined, defaultRule?: FillRule): FillRule;
@@ -7,10 +7,18 @@ import type { GlyphId } from "../types.ts";
7
7
  import { type Bitmap, PixelMode, type RasterizedGlyph, type RasterizeOptions } from "./types.ts";
8
8
  /**
9
9
  * Rasterize a glyph path to a bitmap
10
+ * @param path Glyph path to rasterize
11
+ * @param options Rasterization options including dimensions, scale, and pixel mode
12
+ * @returns Rendered bitmap of the glyph
10
13
  */
11
14
  export declare function rasterizePath(path: GlyphPath, options: RasterizeOptions): Bitmap;
12
15
  /**
13
16
  * Rasterize a glyph from a font
17
+ * @param font Font containing the glyph
18
+ * @param glyphId ID of the glyph to rasterize
19
+ * @param fontSize Font size in pixels
20
+ * @param options Optional rendering settings (pixel mode, padding, hinting)
21
+ * @returns Rasterized glyph with bitmap and bearing information, or null if glyph is empty
14
22
  */
15
23
  export declare function rasterizeGlyph(font: Font, glyphId: GlyphId, fontSize: number, options?: {
16
24
  pixelMode?: PixelMode;
@@ -20,6 +28,11 @@ export declare function rasterizeGlyph(font: Font, glyphId: GlyphId, fontSize: n
20
28
  }): RasterizedGlyph | null;
21
29
  /**
22
30
  * Rasterize text string using shaped glyphs
31
+ * @param font Font to use for rendering
32
+ * @param text Text string to rasterize
33
+ * @param fontSize Font size in pixels
34
+ * @param options Optional rendering settings (pixel mode, padding)
35
+ * @returns Bitmap containing rendered text, or null if no glyphs
23
36
  */
24
37
  export declare function rasterizeText(font: Font, text: string, fontSize: number, options?: {
25
38
  pixelMode?: PixelMode;
@@ -27,17 +40,21 @@ export declare function rasterizeText(font: Font, text: string, fontSize: number
27
40
  }): Bitmap | null;
28
41
  /**
29
42
  * Export bitmap to raw RGBA pixels (for WebGL textures, etc.)
43
+ * @param bitmap Source bitmap to convert
44
+ * @returns RGBA pixel array (4 bytes per pixel)
30
45
  */
31
46
  export declare function bitmapToRGBA(bitmap: Bitmap): Uint8Array;
32
47
  /**
33
48
  * Export bitmap to grayscale array
49
+ * @param bitmap Source bitmap to convert
50
+ * @returns Grayscale pixel array (1 byte per pixel)
34
51
  */
35
52
  export declare function bitmapToGray(bitmap: Bitmap): Uint8Array;
36
53
  export { type BBox, evaluateCubic, evaluateQuadratic, getCubicExtrema, getExactBounds, getQuadraticExtrema, } from "./bbox.ts";
37
- export { blendBitmap, convertBitmap, copyBitmap, emboldenBitmap, resizeBitmap, } from "./bitmap-utils.ts";
54
+ export { blendBitmap, convertBitmap, copyBitmap, emboldenBitmap, resizeBitmap, resizeBitmapBilinear, } from "./bitmap-utils.ts";
38
55
  export { blurBitmap, boxBlur, createGaussianKernel, gaussianBlur, } from "./blur.ts";
39
56
  export { type ColorStop, createGradientBitmap, type Gradient, interpolateGradient, type LinearGradient, type RadialGradient, rasterizePathWithGradient, } from "./gradient.ts";
40
57
  export { renderSdf, type SdfOptions } from "./sdf.ts";
41
58
  export { type LineCap, type LineJoin, type StrokerOptions, strokePath, } from "./stroker.ts";
42
59
  export { condensePath, emboldenPath, obliquePath, transformPath, } from "./synth.ts";
43
- export { type Bitmap, clearBitmap, createBitmap, FillRule, PixelMode, type RasterizedGlyph, type RasterizeOptions, type Span, } from "./types.ts";
60
+ export { type Bitmap, clearBitmap, createBitmap, createBottomUpBitmap, FillRule, PixelMode, type RasterizedGlyph, type RasterizeOptions, type Span, } from "./types.ts";
@@ -33,5 +33,8 @@ export interface SdfOptions {
33
33
  }
34
34
  /**
35
35
  * Render a glyph path as a signed distance field
36
+ * @param path Glyph path to render
37
+ * @param options SDF rendering options (dimensions, scale, spread)
38
+ * @returns Grayscale bitmap with signed distance field (128 = on edge, 255 = inside, 0 = outside)
36
39
  */
37
40
  export declare function renderSdf(path: GlyphPath, options: SdfOptions): Bitmap;
@@ -25,5 +25,8 @@ export interface StrokerOptions {
25
25
  }
26
26
  /**
27
27
  * Stroke a glyph path, producing a new path that represents the stroked outline
28
+ * @param path Input glyph path to stroke
29
+ * @param options Stroke parameters (width, cap style, join style, miter limit)
30
+ * @returns New path representing the stroked outline that can be filled
28
31
  */
29
32
  export declare function strokePath(path: GlyphPath, options: StrokerOptions): GlyphPath;
@@ -177,15 +177,24 @@ export interface MsdfAtlasOptions {
177
177
  }
178
178
  /**
179
179
  * Create an empty bitmap
180
+ * @param width Width in pixels
181
+ * @param height Height in pixels
182
+ * @param pixelMode Pixel format (default: Gray)
183
+ * @returns Empty bitmap with the specified dimensions and format
180
184
  */
181
185
  export declare function createBitmap(width: number, height: number, pixelMode?: PixelMode): Bitmap;
182
186
  /**
183
187
  * Clear a bitmap to zero
188
+ * @param bitmap Bitmap to clear
184
189
  */
185
190
  export declare function clearBitmap(bitmap: Bitmap): void;
186
191
  /**
187
192
  * Create a bottom-up bitmap (negative pitch)
188
193
  * Bottom-up bitmaps have row 0 at the bottom of the image,
189
194
  * which matches some graphics APIs (e.g., Windows DIB, OpenGL textures)
195
+ * @param width Width in pixels
196
+ * @param height Height in pixels
197
+ * @param pixelMode Pixel format (default: Gray)
198
+ * @returns Bottom-up bitmap with row 0 at the bottom
190
199
  */
191
200
  export declare function createBottomUpBitmap(width: number, height: number, pixelMode?: PixelMode): Bitmap;
@@ -2,6 +2,7 @@ import type { GlyphBuffer } from "../buffer/glyph-buffer.ts";
2
2
  import type { Font } from "../font/font.ts";
3
3
  import type { Contour } from "../font/tables/glyf.ts";
4
4
  import type { GlyphId } from "../types.ts";
5
+ import { type Matrix2D, type Matrix3x3 } from "./outline-transform.ts";
5
6
  /**
6
7
  * Path command types for glyph rendering
7
8
  */
@@ -63,11 +64,12 @@ export interface GlyphPath {
63
64
  */
64
65
  export declare function contourToPath(contour: Contour): PathCommand[];
65
66
  /**
66
- * Get path commands for a glyph
67
+ * Get cached glyph path, computing and caching if not already cached
67
68
  */
68
69
  export declare function getGlyphPath(font: Font, glyphId: GlyphId): GlyphPath | null;
69
70
  /**
70
71
  * Convert path commands to SVG path data string
72
+ * Uses Math.round for ~40% faster string generation
71
73
  */
72
74
  export declare function pathToSVG(path: GlyphPath, options?: {
73
75
  flipY?: boolean;
@@ -125,6 +127,10 @@ export declare function renderShapedText(ctx: CanvasRenderingContext2D, font: Fo
125
127
  strokeWidth?: number;
126
128
  lineCap?: CanvasLineCap;
127
129
  lineJoin?: CanvasLineJoin;
130
+ /** 2D affine matrix to apply to glyph coordinates */
131
+ matrix?: Matrix2D;
132
+ /** 3D perspective matrix to apply to glyph coordinates (takes precedence over matrix) */
133
+ matrix3D?: Matrix3x3;
128
134
  }): void;
129
135
  /**
130
136
  * Generate SVG for shaped text
@@ -136,6 +142,12 @@ export declare function shapedTextToSVG(font: Font, glyphs: ShapedGlyph[], optio
136
142
  strokeWidth?: number;
137
143
  lineCap?: "butt" | "round" | "square";
138
144
  lineJoin?: "miter" | "round" | "bevel";
145
+ /** 2D affine matrix to apply to glyph coordinates */
146
+ matrix?: Matrix2D;
147
+ /** 3D perspective matrix to apply to glyph coordinates (takes precedence over matrix) */
148
+ matrix3D?: Matrix3x3;
149
+ /** If true, use native SVG transform attribute instead of transforming path data (2D only) */
150
+ useNativeTransform?: boolean;
139
151
  }): string;
140
152
  /**
141
153
  * Convert GlyphBuffer output to ShapedGlyph array
@@ -182,3 +194,46 @@ export declare function createPath2D(path: GlyphPath, options?: {
182
194
  offsetX?: number;
183
195
  offsetY?: number;
184
196
  }): Path2D;
197
+ /**
198
+ * Render path to canvas with 2D affine matrix transformation applied to coordinates
199
+ * The matrix transforms each point before drawing
200
+ */
201
+ export declare function pathToCanvasWithMatrix(ctx: CanvasRenderingContext2D | Path2D, path: GlyphPath, matrix: Matrix2D, options?: {
202
+ flipY?: boolean;
203
+ }): void;
204
+ /**
205
+ * Convert path to SVG with 2D affine matrix transformation applied to coordinates
206
+ */
207
+ export declare function pathToSVGWithMatrix(path: GlyphPath, matrix: Matrix2D, options?: {
208
+ flipY?: boolean;
209
+ }): string;
210
+ /**
211
+ * Render path to canvas with 3D perspective matrix transformation
212
+ * Uses homogeneous coordinates for perspective projection
213
+ */
214
+ export declare function pathToCanvasWithMatrix3D(ctx: CanvasRenderingContext2D | Path2D, path: GlyphPath, matrix: Matrix3x3, options?: {
215
+ flipY?: boolean;
216
+ }): void;
217
+ /**
218
+ * Convert path to SVG with 3D perspective matrix transformation
219
+ * Uses homogeneous coordinates for perspective projection
220
+ */
221
+ export declare function pathToSVGWithMatrix3D(path: GlyphPath, matrix: Matrix3x3, options?: {
222
+ flipY?: boolean;
223
+ }): string;
224
+ /**
225
+ * Apply 2D affine matrix to canvas context using native transform
226
+ * Use ctx.save() before and ctx.restore() after to preserve context state
227
+ */
228
+ export declare function applyMatrixToContext(ctx: CanvasRenderingContext2D, matrix: Matrix2D): void;
229
+ /**
230
+ * Convert 2D affine matrix to SVG transform attribute string
231
+ * Returns a string like "matrix(a, b, c, d, tx, ty)"
232
+ */
233
+ export declare function matrixToSVGTransform(matrix: Matrix2D): string;
234
+ /**
235
+ * Direct SVG serialization with transform applied in single pass
236
+ * Avoids creating intermediate PathCommand arrays
237
+ * Uses Math.round for ~40% faster string generation
238
+ */
239
+ export declare function pathToSVGDirect(path: GlyphPath, scale: number, offsetX: number, offsetY: number): string;
@@ -56,5 +56,6 @@ export declare function analyzeJoining(infos: GlyphInfo[]): JoiningAction[];
56
56
  export declare function getFeatureForAction(action: JoiningAction): string | null;
57
57
  /**
58
58
  * Set the feature mask for each glyph based on joining analysis
59
+ * Inlined for performance - avoids intermediate array allocation
59
60
  */
60
61
  export declare function setupArabicMasks(infos: GlyphInfo[]): void;
@@ -7,21 +7,24 @@ export interface ShapeFeature {
7
7
  tag: Tag;
8
8
  enabled: boolean;
9
9
  }
10
+ /** Lookup entry with index */
11
+ export interface LookupEntry<T> {
12
+ index: number;
13
+ lookup: T;
14
+ }
10
15
  /** Collected lookups for shaping */
11
16
  export interface ShapePlan {
12
17
  script: Tag;
13
18
  language: Tag | null;
14
19
  direction: "ltr" | "rtl";
15
20
  /** GSUB lookups to apply, in order */
16
- gsubLookups: Array<{
17
- index: number;
18
- lookup: AnyGsubLookup;
19
- }>;
21
+ gsubLookups: LookupEntry<AnyGsubLookup>[];
20
22
  /** GPOS lookups to apply, in order */
21
- gposLookups: Array<{
22
- index: number;
23
- lookup: AnyGposLookup;
24
- }>;
23
+ gposLookups: LookupEntry<AnyGposLookup>[];
24
+ /** Fast O(1) lookup by index for nested GSUB lookups */
25
+ gsubLookupMap: Map<number, LookupEntry<AnyGsubLookup>>;
26
+ /** Fast O(1) lookup by index for nested GPOS lookups */
27
+ gposLookupMap: Map<number, LookupEntry<AnyGposLookup>>;
25
28
  }
26
29
  /** Get or create a cached shape plan */
27
30
  export declare function getOrCreateShapePlan(font: Font, script: string, language: string | null, direction: "ltr" | "rtl", userFeatures?: ShapeFeature[], axisCoords?: number[] | null): ShapePlan;
@@ -2,17 +2,202 @@ import { GlyphBuffer } from "../buffer/glyph-buffer.ts";
2
2
  import type { UnicodeBuffer } from "../buffer/unicode-buffer.ts";
3
3
  import { Face } from "../font/face.ts";
4
4
  import type { Font } from "../font/font.ts";
5
- import { type ShapeFeature } from "./shape-plan.ts";
5
+ import { type AnyGposLookup, type CursivePosLookup, type MarkBasePosLookup, type MarkLigaturePosLookup, type MarkMarkPosLookup, type PairPosLookup, type SinglePosLookup } from "../font/tables/gpos.ts";
6
+ import type { ChainingContextPosFormat1, ChainingContextPosFormat2, ChainingContextPosFormat3, ChainingContextPosLookup, ContextPosFormat1, ContextPosFormat2, ContextPosFormat3, ContextPosLookup, PosLookupRecord } from "../font/tables/gpos-contextual.ts";
7
+ import { type AlternateSubstLookup, type AnyGsubLookup, type ChainingContextSubstLookup, type ContextSubstLookup, type LigatureSubstLookup, type MultipleSubstLookup, type ReverseChainingSingleSubstLookup, type SingleSubstLookup } from "../font/tables/gsub.ts";
8
+ import type { ChainingContextFormat1, ChainingContextFormat2, ChainingContextFormat3, ContextSubstFormat1, ContextSubstFormat2, ContextSubstFormat3, SequenceLookupRecord } from "../font/tables/gsub-contextual.ts";
9
+ import type { ClassDef } from "../layout/structures/class-def.ts";
10
+ import type { GlyphId } from "../types.ts";
11
+ import { type ShapeFeature, type ShapePlan } from "./shape-plan.ts";
12
+ /**
13
+ * Options for controlling text shaping behavior.
14
+ */
6
15
  export interface ShapeOptions {
16
+ /** ISO 15924 script tag (e.g., "arab", "deva", "latn"). Defaults to buffer.script or "latn" */
7
17
  script?: string;
18
+ /** BCP 47 language tag (e.g., "en", "ar-SA", "hi-IN"). Defaults to buffer.language or null */
8
19
  language?: string | null;
20
+ /** Text direction: "ltr" (left-to-right) or "rtl" (right-to-left). Defaults to "ltr" */
9
21
  direction?: "ltr" | "rtl";
22
+ /** Array of OpenType features to apply (e.g., [{tag: "liga", value: 1}, {tag: "kern", value: 0}]) */
10
23
  features?: ShapeFeature[];
11
24
  }
12
- /** Font or Face - accepted by shape function */
25
+ /**
26
+ * Union type accepting either Font or Face instances.
27
+ * Use Face for variable fonts to provide axis coordinates for feature variations.
28
+ * Use Font for static fonts or when default axis values are acceptable.
29
+ */
13
30
  export type FontLike = Font | Face;
14
31
  /**
15
- * Shape text using OpenType features.
16
- * Accepts Font or Face (for variable fonts).
32
+ * Pre-computed skip markers for efficient glyph skipping in contextual matching.
33
+ * Bit is set to 1 if glyph at that position should be skipped for the given lookup flag.
34
+ */
35
+ type SkipMarkers = Uint8Array;
36
+ /**
37
+ * Pre-compute skip markers for all glyphs in the buffer.
38
+ * This avoids calling shouldSkipGlyph() repeatedly in tight loops.
39
+ * O(n) one-time cost instead of O(n²) repeated calls.
40
+ */
41
+ declare function precomputeSkipMarkers(font: Font, buffer: GlyphBuffer, lookupFlag: number): SkipMarkers;
42
+ /**
43
+ * Pre-compute next non-skip index array for O(1) pair lookups.
44
+ * nextNonSkip[i] = index of next non-skipped glyph after i, or -1 if none.
45
+ * Built in reverse for O(n) construction.
46
+ */
47
+ declare function buildNextNonSkipArray(skip: SkipMarkers, length: number): Int16Array;
48
+ /**
49
+ * Return a GlyphBuffer to the pool for reuse.
50
+ * Call this when done with a buffer from shape() to reduce allocations.
51
+ * The pool has a maximum size, so buffers beyond that limit will be discarded.
52
+ *
53
+ * @param buffer - The GlyphBuffer to return to the pool
54
+ */
55
+ export declare function releaseBuffer(buffer: GlyphBuffer): void;
56
+ /**
57
+ * Shape text using OpenType features and complex script processing.
58
+ *
59
+ * Text shaping is the process of converting Unicode text into positioned glyphs for rendering.
60
+ * This involves:
61
+ * - Mapping characters to glyphs via the font's cmap table
62
+ * - Applying OpenType GSUB substitutions (ligatures, contextual forms, etc.)
63
+ * - Positioning glyphs via GPOS or fallback kerning/mark positioning
64
+ * - Complex script analysis (Arabic joining, Indic reordering, etc.)
65
+ * - Applying OpenType features (liga, kern, calt, etc.)
66
+ *
67
+ * The function returns a pooled GlyphBuffer for efficiency. Call releaseBuffer() when done
68
+ * to return it to the pool for reuse.
69
+ *
70
+ * @param fontLike - Font or Face instance (Face for variable fonts with axis coordinates)
71
+ * @param buffer - UnicodeBuffer containing the input text and metadata (script, language, direction)
72
+ * @param options - Optional shaping parameters
73
+ * @param options.script - ISO 15924 script tag (e.g., "arab", "deva"), defaults to buffer.script or "latn"
74
+ * @param options.language - BCP 47 language tag (e.g., "en", "ar-SA"), defaults to buffer.language or null
75
+ * @param options.direction - Text direction "ltr" or "rtl", defaults to "ltr"
76
+ * @param options.features - Array of OpenType features to enable/disable (e.g., [{tag: "liga", value: 1}])
77
+ * @returns GlyphBuffer containing shaped glyphs with positions and metadata
17
78
  */
18
79
  export declare function shape(fontLike: FontLike, buffer: UnicodeBuffer, options?: ShapeOptions): GlyphBuffer;
80
+ /**
81
+ * Shape text into an existing GlyphBuffer (zero-allocation hot path).
82
+ *
83
+ * This is a performance-optimized version of shape() that reuses an existing GlyphBuffer
84
+ * instead of allocating a new one. Use this for maximum performance when shaping repeatedly,
85
+ * such as in animation loops or batch text processing.
86
+ *
87
+ * The provided GlyphBuffer will be reset and filled with the shaped output. This avoids
88
+ * allocations from the buffer pool and gives you full control over buffer lifecycle.
89
+ *
90
+ * @param fontLike - Font or Face instance (Face for variable fonts with axis coordinates)
91
+ * @param buffer - UnicodeBuffer containing the input text and metadata (script, language, direction)
92
+ * @param glyphBuffer - Existing GlyphBuffer to fill with shaped output (will be reset)
93
+ * @param options - Optional shaping parameters
94
+ * @param options.script - ISO 15924 script tag (e.g., "arab", "deva"), defaults to buffer.script or "latn"
95
+ * @param options.language - BCP 47 language tag (e.g., "en", "ar-SA"), defaults to buffer.language or null
96
+ * @param options.direction - Text direction "ltr" or "rtl", defaults to "ltr"
97
+ * @param options.features - Array of OpenType features to enable/disable (e.g., [{tag: "liga", value: 1}])
98
+ */
99
+ export declare function shapeInto(fontLike: FontLike, buffer: UnicodeBuffer, glyphBuffer: GlyphBuffer, options?: ShapeOptions): void;
100
+ declare function applyGsubLookup(font: Font, buffer: GlyphBuffer, lookup: AnyGsubLookup, plan: ShapePlan): void;
101
+ declare function applySingleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: SingleSubstLookup): void;
102
+ declare function applyMultipleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: MultipleSubstLookup): void;
103
+ declare function applyAlternateSubstLookup(font: Font, buffer: GlyphBuffer, lookup: AlternateSubstLookup): void;
104
+ declare function applyLigatureSubstLookup(font: Font, buffer: GlyphBuffer, lookup: LigatureSubstLookup): void;
105
+ declare function applyContextSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ContextSubstLookup, plan: ShapePlan): void;
106
+ declare function applyChainingContextSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ChainingContextSubstLookup, plan: ShapePlan): void;
107
+ declare function applyReverseChainingSingleSubstLookup(font: Font, buffer: GlyphBuffer, lookup: ReverseChainingSingleSubstLookup): void;
108
+ /** Match Context Format 1 - glyph-based rules */
109
+ declare function matchContextFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat1, lookupFlag: number): SequenceLookupRecord[] | null;
110
+ /** Match Context Format 2 - class-based rules */
111
+ declare function matchContextFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat2, lookupFlag: number): SequenceLookupRecord[] | null;
112
+ /** Match Context Format 3 - coverage-based */
113
+ declare function matchContextFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextSubstFormat3, lookupFlag: number): boolean;
114
+ /** Match Chaining Context Format 1 - glyph-based rules */
115
+ declare function matchChainingFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat1, lookupFlag: number): SequenceLookupRecord[] | null;
116
+ /** Match Chaining Context Format 2 - class-based rules */
117
+ declare function matchChainingFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat2, lookupFlag: number): SequenceLookupRecord[] | null;
118
+ /** Match Chaining Context Format 3 - coverage-based */
119
+ declare function matchChainingFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextFormat3, lookupFlag: number): boolean;
120
+ declare function applyNestedLookups(_font: Font, buffer: GlyphBuffer, startIndex: number, lookupRecords: Array<{
121
+ sequenceIndex: number;
122
+ lookupListIndex: number;
123
+ }>, plan: ShapePlan): void;
124
+ /**
125
+ * Glyph class cache for efficient repeated lookups during GPOS positioning.
126
+ * Map from GlyphId to GlyphClass (avoids repeated GDEF lookups for same glyph).
127
+ */
128
+ type GlyphClassCache = Map<GlyphId, number>;
129
+ declare function applyGposLookup(font: Font, buffer: GlyphBuffer, lookup: AnyGposLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void;
130
+ declare function applySinglePosLookup(font: Font, buffer: GlyphBuffer, lookup: SinglePosLookup, hasMarks: boolean): void;
131
+ declare function applyPairPosLookup(font: Font, buffer: GlyphBuffer, lookup: PairPosLookup, hasMarks: boolean): void;
132
+ declare function applyCursivePosLookup(font: Font, buffer: GlyphBuffer, lookup: CursivePosLookup, hasMarks: boolean): void;
133
+ declare function applyMarkBasePosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkBasePosLookup, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array): void;
134
+ declare function applyMarkLigaturePosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkLigaturePosLookup, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array): void;
135
+ declare function applyMarkMarkPosLookup(font: Font, buffer: GlyphBuffer, lookup: MarkMarkPosLookup, glyphClassCache: GlyphClassCache): void;
136
+ declare function applyContextPosLookup(font: Font, buffer: GlyphBuffer, lookup: ContextPosLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void;
137
+ declare function applyChainingContextPosLookup(font: Font, buffer: GlyphBuffer, lookup: ChainingContextPosLookup, plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void;
138
+ /** Match Context Pos Format 1 - glyph-based rules */
139
+ declare function matchContextPosFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat1, lookupFlag: number): PosLookupRecord[] | null;
140
+ /** Match Context Pos Format 2 - class-based rules */
141
+ declare function matchContextPosFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat2, lookupFlag: number): PosLookupRecord[] | null;
142
+ /** Match Context Pos Format 3 - coverage-based */
143
+ declare function matchContextPosFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ContextPosFormat3, lookupFlag: number): boolean;
144
+ /** Match Chaining Context Pos Format 1 - glyph-based rules */
145
+ declare function matchChainingContextPosFormat1(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat1, lookupFlag: number): PosLookupRecord[] | null;
146
+ /** Match Chaining Context Pos Format 2 - class-based rules */
147
+ declare function matchChainingContextPosFormat2(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat2, lookupFlag: number): PosLookupRecord[] | null;
148
+ /** Match Chaining Context Pos Format 3 - coverage-based */
149
+ declare function matchChainingContextPosFormat3(font: Font, buffer: GlyphBuffer, startIndex: number, subtable: ChainingContextPosFormat3, lookupFlag: number): boolean;
150
+ /** Apply nested positioning lookups at specific positions */
151
+ declare function applyNestedPosLookups(font: Font, buffer: GlyphBuffer, startIndex: number, lookupRecords: PosLookupRecord[], plan: ShapePlan, glyphClassCache: GlyphClassCache, baseIndexArray: Int16Array, hasMarks: boolean): void;
152
+ /** Match a sequence of specific glyphs forward */
153
+ declare function matchGlyphSequence(font: Font, buffer: GlyphBuffer, startPos: number, glyphs: GlyphId[], lookupFlag: number): boolean;
154
+ /** Match a sequence of specific glyphs backward */
155
+ declare function matchGlyphSequenceBackward(font: Font, buffer: GlyphBuffer, startPos: number, glyphs: GlyphId[], lookupFlag: number): boolean;
156
+ /** Match a sequence of classes forward */
157
+ declare function matchClassSequence(font: Font, buffer: GlyphBuffer, startPos: number, classes: number[], classDef: ClassDef, lookupFlag: number): boolean;
158
+ /** Match a sequence of classes backward */
159
+ declare function matchClassSequenceBackward(font: Font, buffer: GlyphBuffer, startPos: number, classes: number[], classDef: ClassDef, lookupFlag: number): boolean;
160
+ declare function shouldSkipGlyph(font: Font, glyphId: GlyphId, lookupFlag: number): boolean;
161
+ declare function applyMorx(font: Font, buffer: GlyphBuffer): void;
162
+ export declare const __testing: {
163
+ applyGsubLookup: typeof applyGsubLookup;
164
+ applyGposLookup: typeof applyGposLookup;
165
+ applySingleSubstLookup: typeof applySingleSubstLookup;
166
+ applyMultipleSubstLookup: typeof applyMultipleSubstLookup;
167
+ applyAlternateSubstLookup: typeof applyAlternateSubstLookup;
168
+ applyLigatureSubstLookup: typeof applyLigatureSubstLookup;
169
+ applyContextSubstLookup: typeof applyContextSubstLookup;
170
+ applyChainingContextSubstLookup: typeof applyChainingContextSubstLookup;
171
+ applyReverseChainingSingleSubstLookup: typeof applyReverseChainingSingleSubstLookup;
172
+ applySinglePosLookup: typeof applySinglePosLookup;
173
+ applyPairPosLookup: typeof applyPairPosLookup;
174
+ applyCursivePosLookup: typeof applyCursivePosLookup;
175
+ applyMarkBasePosLookup: typeof applyMarkBasePosLookup;
176
+ applyMarkLigaturePosLookup: typeof applyMarkLigaturePosLookup;
177
+ applyMarkMarkPosLookup: typeof applyMarkMarkPosLookup;
178
+ applyContextPosLookup: typeof applyContextPosLookup;
179
+ applyChainingContextPosLookup: typeof applyChainingContextPosLookup;
180
+ matchContextFormat1: typeof matchContextFormat1;
181
+ matchContextFormat2: typeof matchContextFormat2;
182
+ matchContextFormat3: typeof matchContextFormat3;
183
+ matchChainingFormat1: typeof matchChainingFormat1;
184
+ matchChainingFormat2: typeof matchChainingFormat2;
185
+ matchChainingFormat3: typeof matchChainingFormat3;
186
+ matchContextPosFormat1: typeof matchContextPosFormat1;
187
+ matchContextPosFormat2: typeof matchContextPosFormat2;
188
+ matchContextPosFormat3: typeof matchContextPosFormat3;
189
+ matchChainingContextPosFormat1: typeof matchChainingContextPosFormat1;
190
+ matchChainingContextPosFormat2: typeof matchChainingContextPosFormat2;
191
+ matchChainingContextPosFormat3: typeof matchChainingContextPosFormat3;
192
+ matchGlyphSequence: typeof matchGlyphSequence;
193
+ matchGlyphSequenceBackward: typeof matchGlyphSequenceBackward;
194
+ matchClassSequence: typeof matchClassSequence;
195
+ matchClassSequenceBackward: typeof matchClassSequenceBackward;
196
+ shouldSkipGlyph: typeof shouldSkipGlyph;
197
+ precomputeSkipMarkers: typeof precomputeSkipMarkers;
198
+ buildNextNonSkipArray: typeof buildNextNonSkipArray;
199
+ applyNestedLookups: typeof applyNestedLookups;
200
+ applyNestedPosLookups: typeof applyNestedPosLookups;
201
+ applyMorx: typeof applyMorx;
202
+ };
203
+ export {};
@@ -2,6 +2,21 @@
2
2
  * Bidi bracket pair functions
3
3
  * Port of bidi-js brackets.js
4
4
  */
5
+ /**
6
+ * Get the closing bracket character for an opening bracket
7
+ * @param char Opening bracket character
8
+ * @returns Corresponding closing bracket character, or null if not an opening bracket
9
+ */
5
10
  export declare function openingToClosingBracket(char: string): string | null;
11
+ /**
12
+ * Get the opening bracket character for a closing bracket
13
+ * @param char Closing bracket character
14
+ * @returns Corresponding opening bracket character, or null if not a closing bracket
15
+ */
6
16
  export declare function closingToOpeningBracket(char: string): string | null;
17
+ /**
18
+ * Get the canonical bracket character for a bracket
19
+ * @param char Bracket character
20
+ * @returns Canonical form of the bracket character, or null if not applicable
21
+ */
7
22
  export declare function getCanonicalBracket(char: string): string | null;
@@ -11,9 +11,13 @@ export declare const BN_LIKE_TYPES: number;
11
11
  export declare const TRAILING_TYPES: number;
12
12
  /**
13
13
  * Get the bidi character type for a character
14
+ * @param char Character to check
15
+ * @returns Bidi character type as a bitmask
14
16
  */
15
17
  export declare function getBidiCharType(char: string): number;
16
18
  /**
17
19
  * Get the name of a bidi character type
20
+ * @param char Character to check
21
+ * @returns Bidi character type name (e.g., "L", "R", "EN", "AN", etc.)
18
22
  */
19
23
  export declare function getBidiCharTypeName(char: string): string;
@@ -14,5 +14,8 @@ export interface EmbeddingLevelsResult {
14
14
  * This function applies the Bidirectional Algorithm to a string, returning the resolved embedding levels
15
15
  * in a single Uint8Array plus a list of objects holding each paragraph's start and end indices and resolved
16
16
  * base embedding level.
17
+ * @param string Text string to process
18
+ * @param baseDirection Base text direction: "ltr", "rtl", or "auto"
19
+ * @returns Object containing embedding levels array and paragraph information
17
20
  */
18
21
  export declare function getEmbeddingLevels(string: string, baseDirection?: "ltr" | "rtl" | "auto"): EmbeddingLevelsResult;