67 lines
2.8 KiB
Markdown
67 lines
2.8 KiB
Markdown
# 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`/`m` moveto to identify individual subpaths
|
|
- Drops `Z`/`z` close-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 `PathCommand` type from `@suaveplan/font-convert`
|
|
|
|
## Usage: Basic Example
|
|
|
|
```ts
|
|
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
|
|
|
|
```ts
|
|
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.
|