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
@@ -5,16 +5,27 @@ import { type Bitmap } from "./types.ts";
5
5
  /**
6
6
  * Generate 1D Gaussian kernel
7
7
  * Uses Gaussian function: exp(-x²/(2σ²))
8
+ *
9
+ * @param radius Blur radius (sigma value)
10
+ * @returns Normalized Gaussian kernel weights
8
11
  */
9
12
  export declare function createGaussianKernel(radius: number): Float32Array;
10
13
  /**
11
14
  * Gaussian blur implementation using separable 2-pass algorithm
12
15
  * Modifies bitmap in-place and returns it
16
+ *
17
+ * @param bitmap Bitmap to blur (modified in-place)
18
+ * @param radius Blur radius in pixels
19
+ * @returns The same bitmap after blur is applied
13
20
  */
14
21
  export declare function gaussianBlur(bitmap: Bitmap, radius: number): Bitmap;
15
22
  /**
16
23
  * Box blur using running sum for O(1) per pixel
17
24
  * Modifies bitmap in-place and returns it
25
+ *
26
+ * @param bitmap Bitmap to blur (modified in-place)
27
+ * @param radius Blur radius in pixels
28
+ * @returns The same bitmap after blur is applied
18
29
  */
19
30
  export declare function boxBlur(bitmap: Bitmap, radius: number): Bitmap;
20
31
  /**
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Cascade Blur Algorithm
3
+ *
4
+ * High-performance Gaussian blur for large radii using pyramid scaling.
5
+ *
6
+ * The key insight: to blur with large radius efficiently:
7
+ * 1. Scale down the image by factor of 2 (with smooth kernel)
8
+ * 2. Apply blur with smaller kernel on reduced image
9
+ * 3. Scale back up (with smooth kernel)
10
+ *
11
+ * The shrink/expand kernels [1, 5, 10, 10, 5, 1]/32 provide sufficient
12
+ * smoothness to maintain 8-bit precision through multiple cascade levels.
13
+ *
14
+ * Performance: O(n) per pixel regardless of blur radius
15
+ * Traditional Gaussian: O(r) per pixel where r is radius
16
+ */
17
+ import { type Bitmap } from "./types.ts";
18
+ /**
19
+ * Cascade Gaussian blur with asymmetric X/Y radii
20
+ * High-performance blur using pyramid scaling for large radii
21
+ * @param bitmap Input bitmap to blur
22
+ * @param radiusX Blur radius along X axis in pixels
23
+ * @param radiusY Blur radius along Y axis in pixels (defaults to radiusX)
24
+ * @returns New bitmap with blur applied (dimensions may change)
25
+ */
26
+ export declare function cascadeBlur(bitmap: Bitmap, radiusX: number, radiusY?: number): Bitmap;
27
+ /**
28
+ * Fast Gaussian blur using cascade algorithm
29
+ * This is the recommended blur function for large radii (> 3 pixels)
30
+ * @param bitmap Input bitmap to blur
31
+ * @param radius Blur radius in pixels
32
+ * @returns New bitmap with blur applied (dimensions may change)
33
+ */
34
+ export declare function fastGaussianBlur(bitmap: Bitmap, radius: number): Bitmap;
35
+ /**
36
+ * Adaptive blur that chooses the best algorithm based on radius
37
+ * For small radii (≤ 3): uses simple separable Gaussian (more precise)
38
+ * For large radii (> 3): uses cascade algorithm (faster)
39
+ * @param bitmap Input bitmap to blur
40
+ * @param radiusX Horizontal blur radius in pixels
41
+ * @param radiusY Vertical blur radius in pixels (defaults to radiusX)
42
+ * @returns Blurred bitmap using the optimal algorithm
43
+ */
44
+ export declare function adaptiveBlur(bitmap: Bitmap, radiusX: number, radiusY?: number): Bitmap;
@@ -110,6 +110,30 @@ export declare class CellBuffer {
110
110
  y: number;
111
111
  cells: Cell[];
112
112
  }>;
113
+ /**
114
+ * Iterate scanlines directly without allocating cell arrays
115
+ * Returns first cell index for each row, caller walks linked list via pool
116
+ */
117
+ iterateScanlines(): Generator<{
118
+ y: number;
119
+ firstCellIndex: number;
120
+ }>;
121
+ /**
122
+ * Get the cell pool for direct access during sweep
123
+ */
124
+ getPool(): Cell[];
125
+ /**
126
+ * Get the null cell index (sentinel value)
127
+ */
128
+ getNullIndex(): number;
129
+ /**
130
+ * Get ycells array for direct iteration (avoids generator overhead)
131
+ */
132
+ getYCells(): number[];
133
+ /**
134
+ * Get band minimum Y for coordinate calculation
135
+ */
136
+ getBandMinY(): number;
113
137
  /**
114
138
  * Iterate cells for a single row (for band sweep)
115
139
  */
@@ -57,7 +57,7 @@ export declare function upscale(x: number): number;
57
57
  export declare function downscale(x: number): number;
58
58
  /**
59
59
  * Multiply two fixed-point numbers and divide, avoiding overflow
60
- * Computes (a * b) / c with 64-bit intermediate precision
60
+ * Computes (a * b) / c with 64-bit intermediate precision when needed
61
61
  */
62
62
  export declare function mulDiv(a: number, b: number, c: number): number;
63
63
  /**
@@ -48,14 +48,29 @@ export interface RadialGradient {
48
48
  export type Gradient = LinearGradient | RadialGradient;
49
49
  /**
50
50
  * Get color at position in gradient
51
+ *
52
+ * @param gradient Linear or radial gradient definition
53
+ * @param x X coordinate
54
+ * @param y Y coordinate
55
+ * @returns RGBA color at position (0-255 each)
51
56
  */
52
57
  export declare function interpolateGradient(gradient: Gradient, x: number, y: number): [number, number, number, number];
53
58
  /**
54
59
  * Create a bitmap filled with gradient (no path)
60
+ *
61
+ * @param width Width in pixels
62
+ * @param height Height in pixels
63
+ * @param gradient Linear or radial gradient definition
64
+ * @returns RGBA bitmap filled with gradient
55
65
  */
56
66
  export declare function createGradientBitmap(width: number, height: number, gradient: Gradient): Bitmap;
57
67
  /**
58
68
  * Rasterize path with gradient fill
59
69
  * First rasterizes path to get coverage mask, then fills with gradient
70
+ *
71
+ * @param path Glyph path to rasterize
72
+ * @param gradient Linear or radial gradient definition
73
+ * @param options Rasterization options (width, height, scale, etc.)
74
+ * @returns RGBA bitmap with gradient-filled path
60
75
  */
61
76
  export declare function rasterizePathWithGradient(path: GlyphPath, gradient: Gradient, options: RasterizeOptions): Bitmap;
@@ -67,9 +67,15 @@ export declare class GrayRaster {
67
67
  */
68
68
  private mulDiv;
69
69
  /**
70
- * Draw a quadratic Bezier curve using simple parametric sampling
70
+ * Draw a quadratic Bezier curve using adaptive subdivision
71
+ * Uses flatness test to minimize line segments at small font sizes
71
72
  */
72
73
  conicTo(cx: number, cy: number, toX: number, toY: number): void;
74
+ /**
75
+ * Recursive quadratic subdivision with flatness test
76
+ * Uses FreeType-style flatness: check if control point is within threshold of chord
77
+ */
78
+ private subdivConic;
73
79
  /**
74
80
  * Draw a cubic Bezier curve
75
81
  */
@@ -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;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Multi-channel Signed Distance Field (MSDF) rasterizer
3
+ *
4
+ * MSDF uses three channels (RGB) to encode distance information,
5
+ * allowing sharp corners to be preserved when scaling.
6
+ *
7
+ * Algorithm:
8
+ * 1. Decompose glyph outline into edges (lines, quadratics, cubics)
9
+ * 2. Color edges so adjacent edges at sharp corners have different colors
10
+ * 3. For each pixel, compute signed distance to nearest edge of each color
11
+ * 4. Store R, G, B distances in output bitmap
12
+ * 5. Shader reconstructs using: median(r, g, b)
13
+ *
14
+ * Reference: https://github.com/Chlumsky/msdfgen
15
+ */
16
+ import type { Font } from "../font/font.ts";
17
+ import type { GlyphPath } from "../render/path.ts";
18
+ import { type Bitmap, type GlyphAtlas, type MsdfAtlasOptions } from "./types.ts";
19
+ /**
20
+ * A 2D point
21
+ */
22
+ export interface Point {
23
+ x: number;
24
+ y: number;
25
+ }
26
+ /**
27
+ * Edge color channels for MSDF
28
+ * 0 = red, 1 = green, 2 = blue
29
+ */
30
+ export type EdgeColor = 0 | 1 | 2;
31
+ /**
32
+ * Bounding box for edge culling
33
+ */
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 = ({
44
+ type: "line";
45
+ p0: Point;
46
+ p1: Point;
47
+ color: EdgeColor;
48
+ } & EdgeBounds) | ({
49
+ type: "quadratic";
50
+ p0: Point;
51
+ p1: Point;
52
+ p2: Point;
53
+ color: EdgeColor;
54
+ } & EdgeBounds) | ({
55
+ type: "cubic";
56
+ p0: Point;
57
+ p1: Point;
58
+ p2: Point;
59
+ p3: Point;
60
+ color: EdgeColor;
61
+ } & EdgeBounds);
62
+ /**
63
+ * Signed distance result with parameter t
64
+ */
65
+ export interface SignedDistanceResult {
66
+ distance: number;
67
+ t: number;
68
+ }
69
+ /**
70
+ * Options for MSDF rendering
71
+ */
72
+ export interface MsdfOptions {
73
+ /** Width in pixels */
74
+ width: number;
75
+ /** Height in pixels */
76
+ height: number;
77
+ /** Scale factor (font units to pixels) */
78
+ scale: number;
79
+ /** X offset in pixels */
80
+ offsetX?: number;
81
+ /** Y offset in pixels */
82
+ offsetY?: number;
83
+ /** Flip Y axis (font coords are Y-up, bitmap is Y-down) */
84
+ flipY?: boolean;
85
+ /** Spread/radius - how far the distance field extends in pixels (default: 8) */
86
+ spread?: number;
87
+ }
88
+ /**
89
+ * Return the median of three numbers
90
+ */
91
+ export declare function median(a: number, b: number, c: number): number;
92
+ /**
93
+ * Compute signed distance from point to line segment
94
+ */
95
+ export declare function signedDistanceToLine(px: number, py: number, p0: Point, p1: Point): SignedDistanceResult;
96
+ /**
97
+ * Compute signed distance from point to quadratic bezier curve
98
+ * Uses Newton-Raphson iteration to find closest point
99
+ */
100
+ export declare function signedDistanceToQuadratic(px: number, py: number, p0: Point, p1: Point, p2: Point): SignedDistanceResult;
101
+ /**
102
+ * Compute signed distance from point to cubic bezier curve
103
+ * Uses Newton-Raphson iteration with multiple starting points
104
+ */
105
+ export declare function signedDistanceToCubic(px: number, py: number, p0: Point, p1: Point, p2: Point, p3: Point): SignedDistanceResult;
106
+ /**
107
+ * Assign colors to edges based on corner angles
108
+ * At sharp corners, adjacent edges get different colors
109
+ */
110
+ export declare function assignEdgeColors(contours: MsdfEdge[][]): void;
111
+ /**
112
+ * Render a glyph path as a multi-channel signed distance field
113
+ */
114
+ export declare function renderMsdf(path: GlyphPath, options: MsdfOptions): Bitmap;
115
+ /**
116
+ * Build an MSDF texture atlas from a set of glyphs
117
+ */
118
+ export declare function buildMsdfAtlas(font: Font, glyphIds: number[], options: MsdfAtlasOptions): GlyphAtlas;
119
+ /**
120
+ * Build MSDF atlas for ASCII printable characters (32-126)
121
+ */
122
+ export declare function buildMsdfAsciiAtlas(font: Font, options: MsdfAtlasOptions): GlyphAtlas;
123
+ /**
124
+ * Build MSDF atlas for a specific string (including all unique glyphs)
125
+ */
126
+ export declare function buildMsdfStringAtlas(font: Font, text: string, options: MsdfAtlasOptions): GlyphAtlas;
127
+ /**
128
+ * Export MSDF atlas as RGB texture data
129
+ */
130
+ export declare function msdfAtlasToRGB(atlas: GlyphAtlas): Uint8Array;
131
+ /**
132
+ * Export MSDF atlas as RGBA texture data
133
+ */
134
+ export declare function msdfAtlasToRGBA(atlas: GlyphAtlas): Uint8Array;
135
+ 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;
@@ -160,17 +160,41 @@ export interface AtlasOptions {
160
160
  /** Enable hinting */
161
161
  hinting?: boolean;
162
162
  }
163
+ /**
164
+ * Options for building an MSDF atlas
165
+ */
166
+ export interface MsdfAtlasOptions {
167
+ /** Font size in pixels (size of each glyph cell in the atlas) */
168
+ fontSize: number;
169
+ /** Padding between glyphs */
170
+ padding?: number;
171
+ /** Maximum atlas width */
172
+ maxWidth?: number;
173
+ /** Maximum atlas height */
174
+ maxHeight?: number;
175
+ /** SDF spread/radius in pixels (default: 4) */
176
+ spread?: number;
177
+ }
163
178
  /**
164
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
165
184
  */
166
185
  export declare function createBitmap(width: number, height: number, pixelMode?: PixelMode): Bitmap;
167
186
  /**
168
187
  * Clear a bitmap to zero
188
+ * @param bitmap Bitmap to clear
169
189
  */
170
190
  export declare function clearBitmap(bitmap: Bitmap): void;
171
191
  /**
172
192
  * Create a bottom-up bitmap (negative pitch)
173
193
  * Bottom-up bitmaps have row 0 at the bottom of the image,
174
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
175
199
  */
176
200
  export declare function createBottomUpBitmap(width: number, height: number, pixelMode?: PixelMode): Bitmap;
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Outline Transform Operations
3
+ *
4
+ * Provides geometric transformations for glyph outlines:
5
+ * - 90° rotation
6
+ * - Power-of-2 scaling
7
+ * - 2D affine transforms (translate, rotate, scale, shear)
8
+ * - 3D perspective transforms
9
+ * - Bounding box computation
10
+ */
11
+ import type { GlyphPath } from "./path.ts";
12
+ /**
13
+ * 2D affine transformation matrix [a, b, c, d, tx, ty]
14
+ * Transforms point (x, y) to:
15
+ * x' = a*x + c*y + tx
16
+ * y' = b*x + d*y + ty
17
+ */
18
+ export type Matrix2D = [number, number, number, number, number, number];
19
+ /**
20
+ * 3x3 transformation matrix for 2D homogeneous coordinates
21
+ * | m00 m01 m02 | | x | | x' |
22
+ * | m10 m11 m12 | × | y | = | y' |
23
+ * | m20 m21 m22 | | 1 | | w |
24
+ *
25
+ * Final coordinates: (x'/w, y'/w)
26
+ */
27
+ export type Matrix3x3 = [
28
+ [
29
+ number,
30
+ number,
31
+ number
32
+ ],
33
+ [
34
+ number,
35
+ number,
36
+ number
37
+ ],
38
+ [
39
+ number,
40
+ number,
41
+ number
42
+ ]
43
+ ];
44
+ /**
45
+ * Axis-aligned bounding box
46
+ */
47
+ export interface BoundingBox {
48
+ xMin: number;
49
+ yMin: number;
50
+ xMax: number;
51
+ yMax: number;
52
+ }
53
+ /**
54
+ * Control box (bounding box of control points, not tight bounds)
55
+ */
56
+ export interface ControlBox extends BoundingBox {
57
+ }
58
+ /**
59
+ * Create identity 2D matrix
60
+ */
61
+ export declare function identity2D(): Matrix2D;
62
+ /**
63
+ * Create identity 3x3 matrix
64
+ */
65
+ export declare function identity3x3(): Matrix3x3;
66
+ /**
67
+ * Create translation matrix
68
+ */
69
+ export declare function translate2D(tx: number, ty: number): Matrix2D;
70
+ /**
71
+ * Create scale matrix
72
+ */
73
+ export declare function scale2D(sx: number, sy: number): Matrix2D;
74
+ /**
75
+ * Create rotation matrix (angle in radians)
76
+ */
77
+ export declare function rotate2D(angle: number): Matrix2D;
78
+ /**
79
+ * Create shear/skew matrix
80
+ */
81
+ export declare function shear2D(shearX: number, shearY: number): Matrix2D;
82
+ /**
83
+ * Multiply two 2D matrices: result = a × b
84
+ */
85
+ export declare function multiply2D(a: Matrix2D, b: Matrix2D): Matrix2D;
86
+ /**
87
+ * Multiply two 3x3 matrices: result = a × b
88
+ */
89
+ export declare function multiply3x3(a: Matrix3x3, b: Matrix3x3): Matrix3x3;
90
+ /**
91
+ * Transform a point using 2D matrix
92
+ */
93
+ export declare function transformPoint2D(x: number, y: number, m: Matrix2D): {
94
+ x: number;
95
+ y: number;
96
+ };
97
+ /**
98
+ * Transform a point using 3x3 matrix (with perspective division)
99
+ */
100
+ export declare function transformPoint3x3(x: number, y: number, m: Matrix3x3): {
101
+ x: number;
102
+ y: number;
103
+ };
104
+ /**
105
+ * Rotate outline by 90 degrees counter-clockwise around origin
106
+ * Optionally apply offset after rotation
107
+ */
108
+ export declare function rotateOutline90(path: GlyphPath, offsetX?: number, offsetY?: number): GlyphPath;
109
+ /**
110
+ * Scale outline by power of 2
111
+ * scaleOrdX/Y: shift amount (positive = enlarge, negative = shrink)
112
+ * e.g., scaleOrdX=1 means multiply x by 2, scaleOrdX=-1 means divide by 2
113
+ */
114
+ export declare function scaleOutlinePow2(path: GlyphPath, scaleOrdX: number, scaleOrdY: number): GlyphPath;
115
+ /**
116
+ * Apply 2D affine transformation to outline
117
+ */
118
+ export declare function transformOutline2D(path: GlyphPath, m: Matrix2D): GlyphPath;
119
+ /**
120
+ * Apply 3D perspective transformation to outline
121
+ * Uses homogeneous coordinates for perspective projection
122
+ */
123
+ export declare function transformOutline3D(path: GlyphPath, m: Matrix3x3): GlyphPath;
124
+ /**
125
+ * Compute control box (bounding box of all control points)
126
+ * This is faster than computing tight bounds but may be larger
127
+ */
128
+ export declare function computeControlBox(path: GlyphPath): ControlBox;
129
+ /**
130
+ * Compute tight bounding box (exact bounds considering curve extrema)
131
+ */
132
+ export declare function computeTightBounds(path: GlyphPath): BoundingBox;
133
+ /**
134
+ * Update control box with transformed outline
135
+ * Used for finding minimum X after 3D transform (like libass)
136
+ */
137
+ export declare function updateMinTransformedX(path: GlyphPath, m: Matrix3x3, currentMinX: number): number;
138
+ /**
139
+ * Translate outline by offset
140
+ */
141
+ export declare function translateOutline(path: GlyphPath, dx: number, dy: number): GlyphPath;
142
+ /**
143
+ * Scale outline uniformly
144
+ */
145
+ export declare function scaleOutline(path: GlyphPath, sx: number, sy?: number): GlyphPath;
146
+ /**
147
+ * Rotate outline by angle (in radians) around origin
148
+ */
149
+ export declare function rotateOutline(path: GlyphPath, angle: number): GlyphPath;
150
+ /**
151
+ * Apply italic/oblique shear to outline
152
+ * @param angle Italic angle in degrees (typically 12-15 for italic)
153
+ */
154
+ export declare function italicizeOutline(path: GlyphPath, angle: number): GlyphPath;
155
+ /**
156
+ * Create 3x3 perspective matrix
157
+ * @param vanishingPointX X coordinate of vanishing point
158
+ * @param vanishingPointY Y coordinate of vanishing point
159
+ * @param strength Perspective strength (0 = none, larger = more perspective)
160
+ */
161
+ export declare function perspectiveMatrix(vanishingPointX: number, vanishingPointY: number, strength: number): Matrix3x3;
162
+ /**
163
+ * Combine multiple paths into one
164
+ */
165
+ export declare function combinePaths(paths: GlyphPath[]): GlyphPath;
166
+ /**
167
+ * Clone a path
168
+ */
169
+ export declare function clonePath(path: GlyphPath): GlyphPath;