text-shaper 0.1.1 → 0.1.2
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/dist/index.d.ts +8 -3
- package/dist/index.js +10 -10
- package/dist/index.js.map +13 -8
- package/dist/perf/benchmark-runner-eksh2b26.js +0 -0
- package/dist/perf/benchmark-runner.html +517 -0
- package/dist/perf/comparison-tests.js +22676 -0
- package/dist/perf/comparison-tests.js.map +111 -0
- package/dist/perf/cpu/cpu-perf.js +21920 -0
- package/dist/perf/cpu/cpu-perf.js.map +108 -0
- package/dist/perf/gpu/webgl-perf.js +470 -0
- package/dist/perf/gpu/webgl-perf.js.map +11 -0
- package/dist/perf/gpu/webgpu-perf.js +442 -0
- package/dist/perf/gpu/webgpu-perf.js.map +11 -0
- package/dist/perf/index.html +258 -0
- package/dist/perf/module-loader.js +18 -0
- package/dist/perf/utils/perf-utils.js +170 -0
- package/dist/perf/utils/perf-utils.js.map +10 -0
- package/dist/raster/asymmetric-stroke.d.ts +57 -0
- package/dist/raster/bitmap-utils.d.ts +57 -0
- package/dist/raster/cascade-blur.d.ts +45 -0
- package/dist/raster/msdf.d.ts +125 -0
- package/dist/raster/types.d.ts +15 -0
- package/dist/render/outline-transform.d.ts +169 -0
- package/package.json +2 -2
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
* An edge with color assignment
|
|
33
|
+
*/
|
|
34
|
+
export type MsdfEdge = {
|
|
35
|
+
type: "line";
|
|
36
|
+
p0: Point;
|
|
37
|
+
p1: Point;
|
|
38
|
+
color: EdgeColor;
|
|
39
|
+
} | {
|
|
40
|
+
type: "quadratic";
|
|
41
|
+
p0: Point;
|
|
42
|
+
p1: Point;
|
|
43
|
+
p2: Point;
|
|
44
|
+
color: EdgeColor;
|
|
45
|
+
} | {
|
|
46
|
+
type: "cubic";
|
|
47
|
+
p0: Point;
|
|
48
|
+
p1: Point;
|
|
49
|
+
p2: Point;
|
|
50
|
+
p3: Point;
|
|
51
|
+
color: EdgeColor;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Signed distance result with parameter t
|
|
55
|
+
*/
|
|
56
|
+
export interface SignedDistanceResult {
|
|
57
|
+
distance: number;
|
|
58
|
+
t: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Options for MSDF rendering
|
|
62
|
+
*/
|
|
63
|
+
export interface MsdfOptions {
|
|
64
|
+
/** Width in pixels */
|
|
65
|
+
width: number;
|
|
66
|
+
/** Height in pixels */
|
|
67
|
+
height: number;
|
|
68
|
+
/** Scale factor (font units to pixels) */
|
|
69
|
+
scale: number;
|
|
70
|
+
/** X offset in pixels */
|
|
71
|
+
offsetX?: number;
|
|
72
|
+
/** Y offset in pixels */
|
|
73
|
+
offsetY?: number;
|
|
74
|
+
/** Flip Y axis (font coords are Y-up, bitmap is Y-down) */
|
|
75
|
+
flipY?: boolean;
|
|
76
|
+
/** Spread/radius - how far the distance field extends in pixels (default: 8) */
|
|
77
|
+
spread?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Return the median of three numbers
|
|
81
|
+
*/
|
|
82
|
+
export declare function median(a: number, b: number, c: number): number;
|
|
83
|
+
/**
|
|
84
|
+
* Compute signed distance from point to line segment
|
|
85
|
+
*/
|
|
86
|
+
export declare function signedDistanceToLine(px: number, py: number, p0: Point, p1: Point): SignedDistanceResult;
|
|
87
|
+
/**
|
|
88
|
+
* Compute signed distance from point to quadratic bezier curve
|
|
89
|
+
* Uses Newton-Raphson iteration to find closest point
|
|
90
|
+
*/
|
|
91
|
+
export declare function signedDistanceToQuadratic(px: number, py: number, p0: Point, p1: Point, p2: Point): SignedDistanceResult;
|
|
92
|
+
/**
|
|
93
|
+
* Compute signed distance from point to cubic bezier curve
|
|
94
|
+
* Uses Newton-Raphson iteration with multiple starting points
|
|
95
|
+
*/
|
|
96
|
+
export declare function signedDistanceToCubic(px: number, py: number, p0: Point, p1: Point, p2: Point, p3: Point): SignedDistanceResult;
|
|
97
|
+
/**
|
|
98
|
+
* Assign colors to edges based on corner angles
|
|
99
|
+
* At sharp corners, adjacent edges get different colors
|
|
100
|
+
*/
|
|
101
|
+
export declare function assignEdgeColors(contours: MsdfEdge[][]): void;
|
|
102
|
+
/**
|
|
103
|
+
* Render a glyph path as a multi-channel signed distance field
|
|
104
|
+
*/
|
|
105
|
+
export declare function renderMsdf(path: GlyphPath, options: MsdfOptions): Bitmap;
|
|
106
|
+
/**
|
|
107
|
+
* Build an MSDF texture atlas from a set of glyphs
|
|
108
|
+
*/
|
|
109
|
+
export declare function buildMsdfAtlas(font: Font, glyphIds: number[], options: MsdfAtlasOptions): GlyphAtlas;
|
|
110
|
+
/**
|
|
111
|
+
* Build MSDF atlas for ASCII printable characters (32-126)
|
|
112
|
+
*/
|
|
113
|
+
export declare function buildMsdfAsciiAtlas(font: Font, options: MsdfAtlasOptions): GlyphAtlas;
|
|
114
|
+
/**
|
|
115
|
+
* Build MSDF atlas for a specific string (including all unique glyphs)
|
|
116
|
+
*/
|
|
117
|
+
export declare function buildMsdfStringAtlas(font: Font, text: string, options: MsdfAtlasOptions): GlyphAtlas;
|
|
118
|
+
/**
|
|
119
|
+
* Export MSDF atlas as RGB texture data
|
|
120
|
+
*/
|
|
121
|
+
export declare function msdfAtlasToRGB(atlas: GlyphAtlas): Uint8Array;
|
|
122
|
+
/**
|
|
123
|
+
* Export MSDF atlas as RGBA texture data
|
|
124
|
+
*/
|
|
125
|
+
export declare function msdfAtlasToRGBA(atlas: GlyphAtlas): Uint8Array;
|
package/dist/raster/types.d.ts
CHANGED
|
@@ -160,6 +160,21 @@ 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
|
|
165
180
|
*/
|
|
@@ -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;
|
package/package.json
CHANGED