126 lines
8.1 KiB
Markdown
126 lines
8.1 KiB
Markdown
# @suaveplan/font-compress - Font subsetting and compression library with a codec-agnostic adapter interface. Supports Unicode range subsetting, WOFF2/WOFF/OTF/TTF output, OpenType feature filtering, hinting strip, and metadata strip.
|
|
|
|
## Summary
|
|
|
|
Font subsetting and compression library with a codec-agnostic adapter interface. Supports Unicode range subsetting, WOFF2/WOFF/OTF/TTF output, OpenType feature filtering, hinting strip, and metadata strip. Adapter implementations supply the actual codec; this package provides the orchestration, validation, format detection, and OTel instrumentation.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [types](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [common](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [format-detect](./src/utils/format-detect.md) — Provides magic-byte font format detection from raw binary data. Before compressing or probing a font file, `FontCompres…
|
|
- [unicode-ranges](./src/utils/unicode-ranges.md) — Parses CSS/OpenType-style Unicode range notation into a `Set<number>` of integer codepoints. Font subsetting workflows…
|
|
<!-- end:auto-docs --> - [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detect](./src/utils/format-detect.md) — Provides magic-byte font format detection from raw binary data. Before compressing or probing a font file, `FontCompres…
|
|
- [unicode-ranges](./src/utils/unicode-ranges.md) — Parses CSS/OpenType-style Unicode range notation into a `Set<number>` of integer codepoints. Font subsetting workflows…
|
|
- [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detect](./src/utils/format-detect.md) — Provides magic-byte font format detection from raw binary data. Before compressing or probing a font file, `FontCompres…
|
|
- [unicode-ranges](./src/utils/unicode-ranges.md) — Parses CSS/OpenType-style Unicode range notation into a `Set<number>` of integer codepoints. Font subsetting workflows…
|
|
- [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detect](./src/utils/format-detect.md) — Provides magic-byte font format detection from raw binary data. Before compressing or probing a font file, `FontCompres…
|
|
- [unicode-ranges](./src/utils/unicode-ranges.md) — Parses CSS/OpenType-style Unicode range notation into a `Set<number>` of integer codepoints. Font subsetting workflows…
|
|
- [null](./src/adapters/null/null.md) — <!-- begin:auto-docs --> _(no submodules)_- [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_ - [font-compressor](./src/core/font-compressor/font-compressor.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_ - [common](./src/types/common.md) — <!-- begin:auto-docs --> _(no submodules)_- [format-detect](./src/utils/format-detect.md) — Provides magic-byte font format detection from raw binary data. Before compressing or probing a font file, `FontCompres…
|
|
- [unicode-ranges](./src/utils/unicode-ranges.md) — Parses CSS/OpenType-style Unicode range notation into a `Set<number>` of integer codepoints. Font subsetting workflows…
|
|
|
|
## Packages
|
|
|
|
| Module | Description |
|
|
|---|---|
|
|
| [FontCompressor](src/core/font-compressor/font-compressor.md) | Core orchestrator: validation, format checks, AbortSignal, OTel |
|
|
| [NullFontCompressAdapter](src/adapters/null-adapter/null-adapter.md) | No-op adapter for unit/integration tests |
|
|
| [parseUnicodeRanges](src/utils/unicode-ranges.md) | Unicode range string → `Set<number>` codepoint parser |
|
|
| [detectFontFormat](src/utils/format-detect.md) | Magic-byte font format detection |
|
|
| [Types & Schemas](src/types/common.md) | All public types and Zod validation schemas |
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
bun add @suaveplan/font-compress
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```typescript
|
|
import {
|
|
FontCompressor,
|
|
NullFontCompressAdapter,
|
|
} from "@suaveplan/font-compress";
|
|
|
|
// Replace NullFontCompressAdapter with a real codec adapter in production
|
|
const adapter = new NullFontCompressAdapter();
|
|
const compressor = new FontCompressor({ adapter });
|
|
|
|
const fontBytes = await Bun.file("Roboto-Regular.ttf").bytes();
|
|
const result = await compressor.compress(fontBytes, {
|
|
subset: { unicodeRanges: ["U+0020-007F"] },
|
|
outputFormat: "woff2",
|
|
stripHinting: true,
|
|
});
|
|
|
|
console.log(`Compressed ${result.originalSize} → ${result.compressedSize} bytes`);
|
|
console.log(`Ratio: ${(result.ratio * 100).toFixed(1)}%`);
|
|
```
|
|
|
|
## Providing a Real Codec Adapter
|
|
|
|
Implement `FontCompressAdapter` to wrap any real font codec:
|
|
|
|
```typescript
|
|
import type { FontCompressAdapter, FontMetadata, FontCompressResult, CompressFontOptions } from "@suaveplan/font-compress";
|
|
|
|
class WoffToolsAdapter implements FontCompressAdapter {
|
|
readonly supportedInputFormats = ["ttf", "otf"] as const;
|
|
readonly supportedOutputFormats = ["woff2"] as const;
|
|
|
|
async probe(data: Uint8Array): Promise<FontMetadata> {
|
|
// parse font tables to extract metadata
|
|
}
|
|
|
|
async compress(data: Uint8Array, options: CompressFontOptions): Promise<FontCompressResult> {
|
|
// call woff2-encoder or similar
|
|
}
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
All errors thrown by this package are instances of `FontCompressError`, which extends `SuaveplanError`. Use the `code` property for programmatic error handling:
|
|
|
|
```typescript
|
|
import { FONT_COMPRESS_CODES, FontCompressError } from "@suaveplan/font-compress";
|
|
|
|
try {
|
|
await compressor.compress(data, { outputFormat: "woff2" });
|
|
} catch (e) {
|
|
if (e instanceof FontCompressError) {
|
|
switch (e.code) {
|
|
case FONT_COMPRESS_CODES.UNSUPPORTED_FORMAT: /* ... */
|
|
case FONT_COMPRESS_CODES.PARSE_FAILED: /* ... */
|
|
case FONT_COMPRESS_CODES.ENCODE_FAILED: /* ... */
|
|
case FONT_COMPRESS_CODES.INVALID_OPTIONS: /* ... */
|
|
case FONT_COMPRESS_CODES.SUBSET_FAILED: /* ... */
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Unicode Range Subsetting
|
|
|
|
```typescript
|
|
import { parseUnicodeRanges } from "@suaveplan/font-compress/utils/unicode-ranges";
|
|
|
|
const codepoints = parseUnicodeRanges(["U+0020-007F", "U+00A0-00FF"]);
|
|
console.log(codepoints.size); // 192 codepoints
|
|
```
|
|
|
|
## Format Detection
|
|
|
|
```typescript
|
|
import { detectFontFormat } from "@suaveplan/font-compress/utils/format-detect";
|
|
|
|
const fmt = detectFontFormat(await Bun.file("font.woff2").bytes());
|
|
console.log(fmt); // "woff2"
|
|
```
|