2.8 KiB
reverseWinding
Purpose
Reverses the winding order of a typeface.js path command sequence. Three.js FontLoader expects counter-clockwise winding for outer contours, while some TrueType and CFF fonts ship with clockwise winding. Calling reverseWinding before serialising glyphs ensures the outline direction is corrected without reprocessing the source binary.
Features
- Splits commands at each
M/mmoveto to identify individual subpaths - Drops
Z/zclose-path commands (they are implicit in typeface.js rendering) - Reverses command order within each subpath
- Swaps cubic bezier control point pairs (
x1/y1↔x2/y2) to maintain curve shape - Preserves quadratic bezier single control point after destination flip
- Works with zero commands (returns empty array, no error)
- Operates entirely on the
PathCommandtype from@suaveplan/font-convert
Usage: Basic Example
import { reverseWinding } from "@suaveplan/font-convert";
import type { PathCommand } from "@suaveplan/font-convert";
const commands: PathCommand[] = [
{ type: "m", x: 0, y: 0 },
{ type: "l", x: 100, y: 0 },
{ type: "l", x: 50, y: 100 },
{ type: "z" },
];
const reversed = reverseWinding(commands);
// reversed[0] = { type: "m", x: 50, y: 100 } — last point becomes new start
// reversed[1] = { type: "l", x: 100, y: 0 }
// reversed[2] = { type: "l", x: 0, y: 0 }
Usage: Advanced Example
import { reverseWinding } from "@suaveplan/font-convert";
import type { PathCommand } from "@suaveplan/font-convert";
// Cubic bezier: reversal swaps x1/y1 and x2/y2
const cubicCommands: PathCommand[] = [
{ type: "m", x: 0, y: 0 },
{ type: "b", x1: 10, y1: 20, x2: 30, y2: 40, x: 100, y: 0 },
];
const rev = reverseWinding(cubicCommands);
// rev[0] = { type: "m", x: 100, y: 0 }
// rev[1] = { type: "b", x1: 30, y1: 40, x2: 10, y2: 20, x: 0, y: 0 }
// ^^^ x2/y2 and x1/y1 are swapped relative to the original
API Reference
reverseWinding(commands: PathCommand[]): PathCommand[]
| Parameter | Type | Description |
|---|---|---|
commands |
PathCommand[] |
Array of path commands as produced by FontConverter |
Returns: A new array of PathCommand objects in reversed winding order. The input array is not mutated.
Implementation Notes
The function mirrors the winding-reversal algorithm used in typeface.js's own CLI tooling and the reference FontConverter.ts. Subpath splitting is done by scanning for m/M commands; z/Z close-path commands are discarded because typeface.js renderers treat each subpath as implicitly closed. The reversed list starts with a new m command pointing at the last non-close command of the original path, then walks the original path backwards, placing each point at the previous command's destination.