maplibre-font-maker-node 0.1.0

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/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # font-maker-node
2
+
3
+ A TypeScript library for generating MapLibre-compatible glyph PBF files in memory from TTF, OTF, WOFF, or WOFF2 font bytes.
4
+ Variable fonts are supported, but a specific instantiation must be chosen, so you should supply a value for each axis.
5
+
6
+ ## Usage
7
+
8
+ ```ts
9
+ import { generateGlyphPbfFiles, latinRanges } from 'font-maker-node';
10
+
11
+ const files = await generateGlyphPbfFiles({
12
+ fontstack: 'Barlow Regular',
13
+ fonts: [
14
+ {
15
+ name: 'Barlow Regular',
16
+ bytes: ttfBytes,
17
+ },
18
+ ],
19
+ ranges: latinRanges(),
20
+ });
21
+ ```
22
+
23
+ The result is an array of in-memory files:
24
+
25
+ ```ts
26
+ [
27
+ {
28
+ filename: 'Barlow Regular/0-255.pbf',
29
+ bytes: Uint8Array,
30
+ },
31
+ ];
32
+ ```
33
+
34
+ The caller is responsible for writing files to disk if desired. The public API does not read font files or write output files. The only filesystem access performed by the library is loading the vendored `maplibre-font-maker/sdfglyph.js` and `maplibre-font-maker/sdfglyph.wasm` runtime files during initialization.
35
+
36
+ ## API
37
+
38
+ ```ts
39
+ generateGlyphPbfFiles(options)
40
+ range256(start)
41
+ basicLatinRanges()
42
+ latinRanges()
43
+ allBmpRanges()
44
+ ```
45
+
46
+ `basicLatinRanges()` returns the `0-255` MapLibre glyph range. `latinRanges()` returns `0-255`, `256-511`, and `512-767`. `allBmpRanges()` returns all 256 ranges covering the BMP.
47
+
48
+ ## Web Fonts And Variable Settings
49
+
50
+ ```ts
51
+ const files = await generateGlyphPbfFiles({
52
+ fontstack: 'Inter Bold',
53
+ fonts: [
54
+ {
55
+ name: 'Inter Bold',
56
+ bytes: woff2Bytes,
57
+ settings: {
58
+ wght: 700,
59
+ },
60
+ },
61
+ ],
62
+ ranges: latinRanges(),
63
+ });
64
+ ```
65
+
66
+ In the settings, key must be a 4-character OpenType variation-axis tag and each value must be the fixed numeric axis value to instantiate. Unspecified axes are pinned to the font's default values when a variable font is normalized.
67
+
68
+ ## We use [font-maker](https://github.com/maplibre/font-maker) internally
69
+
70
+ This library wraps the MapLibre `font-maker` WebAssembly runtime, which is vendored under [`maplibre-font-maker/`](./maplibre-font-maker/README.md). See that directory's README for its source, checksums, and rebuild instructions.
@@ -0,0 +1,10 @@
1
+ export type FontVariationSettings = Record<string, number>;
2
+ export interface FontInput {
3
+ name: string;
4
+ bytes: Uint8Array;
5
+ settings?: FontVariationSettings;
6
+ }
7
+ export declare function isSupportedFontInput(bytes: Uint8Array): boolean;
8
+ export declare function normalizeFontInput(font: FontInput): Promise<FontInput>;
9
+ export declare function validateFontVariationSettings(settings: FontVariationSettings | undefined, path: string): FontVariationSettings | undefined;
10
+ //# sourceMappingURL=font-normalization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-normalization.d.ts","sourceRoot":"","sources":["../src/font-normalization.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE/D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAe5E;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,qBAAqB,GAAG,SAAS,EAC3C,IAAI,EAAE,MAAM,GACX,qBAAqB,GAAG,SAAS,CAwBnC"}
@@ -0,0 +1,81 @@
1
+ import { instantiateVariableFont, subset } from '@web-alchemy/fonttools';
2
+ const WOFF_SIGNATURE = 'wOFF';
3
+ const WOFF2_SIGNATURE = 'wOF2';
4
+ export function isSupportedFontInput(bytes) {
5
+ return hasSupportedSfntSignature(bytes) || isWoff(bytes) || isWoff2(bytes);
6
+ }
7
+ export async function normalizeFontInput(font) {
8
+ if (!needsNormalization(font)) {
9
+ return font;
10
+ }
11
+ const bytes = await normalizeWithFontTools(font.bytes, font.settings ?? {});
12
+ if (!hasSupportedSfntSignature(bytes)) {
13
+ throw new Error(`Failed to normalize font "${font.name}": normalized bytes are not a supported TTF or OTF font.`);
14
+ }
15
+ return {
16
+ ...font,
17
+ bytes,
18
+ };
19
+ }
20
+ export function validateFontVariationSettings(settings, path) {
21
+ if (settings === undefined) {
22
+ return undefined;
23
+ }
24
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
25
+ throw new TypeError(`${path} must be an object mapping 4-character axis tags to numeric values.`);
26
+ }
27
+ const normalized = {};
28
+ for (const [axisTag, value] of Object.entries(settings)) {
29
+ if (!isAxisTag(axisTag)) {
30
+ throw new TypeError(`Invalid variation axis tag "${axisTag}" in ${path}. Axis tags must be 4 printable ASCII characters.`);
31
+ }
32
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
33
+ throw new TypeError(`Variation axis "${axisTag}" in ${path} must be a finite number.`);
34
+ }
35
+ normalized[axisTag] = value;
36
+ }
37
+ return normalized;
38
+ }
39
+ function needsNormalization(font) {
40
+ return isWoff(font.bytes) || isWoff2(font.bytes) || font.settings !== undefined;
41
+ }
42
+ async function normalizeWithFontTools(bytes, settings) {
43
+ let result = bytes;
44
+ // Pin variable axes to the requested location, collapsing the font to a static
45
+ // instance. fontTools raises if the font is not variable or an axis/value is invalid.
46
+ if (Object.keys(settings).length > 0) {
47
+ result = await instantiateVariableFont(result, settings);
48
+ }
49
+ // Instancing preserves the input flavor and the WASM only accepts plain SFNT, so
50
+ // decompress any WOFF/WOFF2 to TTF/OTF. A wildcard subset retains every glyph.
51
+ if (isWoff(result) || isWoff2(result)) {
52
+ result = await subset(result, { '*': true });
53
+ }
54
+ return new Uint8Array(result);
55
+ }
56
+ function hasSupportedSfntSignature(bytes) {
57
+ if (bytes.byteLength < 4) {
58
+ return false;
59
+ }
60
+ if (bytes[0] === 0x00 && bytes[1] === 0x01 && bytes[2] === 0x00 && bytes[3] === 0x00) {
61
+ return true;
62
+ }
63
+ const signature = getSignature(bytes);
64
+ return signature === 'OTTO' || signature === 'true' || signature === 'typ1' || signature === 'ttcf';
65
+ }
66
+ function isWoff(bytes) {
67
+ return getSignature(bytes) === WOFF_SIGNATURE;
68
+ }
69
+ function isWoff2(bytes) {
70
+ return getSignature(bytes) === WOFF2_SIGNATURE;
71
+ }
72
+ function getSignature(bytes) {
73
+ if (bytes.byteLength < 4) {
74
+ return '';
75
+ }
76
+ return String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
77
+ }
78
+ function isAxisTag(value) {
79
+ return /^[\x20-\x7e]{4}$/.test(value);
80
+ }
81
+ //# sourceMappingURL=font-normalization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-normalization.js","sourceRoot":"","sources":["../src/font-normalization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { FontInput } from './font-normalization.js';
2
+ import type { GlyphRange } from './ranges.js';
3
+ export { allBmpRanges, basicLatinRanges, latinRanges, range256 } from './ranges.js';
4
+ export type { GlyphRange } from './ranges.js';
5
+ export type { FontInput, FontVariationSettings } from './font-normalization.js';
6
+ export interface GeneratedGlyphPbfFile {
7
+ filename: string;
8
+ bytes: Uint8Array;
9
+ }
10
+ export interface GenerateGlyphPbfFilesOptions {
11
+ fontstack: string;
12
+ fonts: FontInput[];
13
+ ranges: GlyphRange[];
14
+ }
15
+ export declare function generateGlyphPbfFiles(options: GenerateGlyphPbfFilesOptions): Promise<GeneratedGlyphPbfFile[]>;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpF,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAiClC"}
package/dist/index.js ADDED
@@ -0,0 +1,161 @@
1
+ import { isSupportedFontInput, normalizeFontInput, validateFontVariationSettings, } from './font-normalization.js';
2
+ import { range256 } from './ranges.js';
3
+ import { loadFontMaker } from './wasm/load-font-maker.js';
4
+ import { allocateBytes, copyBytes, freePointer } from './wasm/memory.js';
5
+ import { ccallNumber, ccallVoid } from './wasm/sdfglyph-module.js';
6
+ export { allBmpRanges, basicLatinRanges, latinRanges, range256 } from './ranges.js';
7
+ export async function generateGlyphPbfFiles(options) {
8
+ const fontstack = validateFontstack(options?.fontstack);
9
+ const fonts = validateFonts(options?.fonts);
10
+ const ranges = validateRanges(options?.ranges);
11
+ const normalizedFonts = await normalizeFonts(fonts);
12
+ const module = await initializeWasm();
13
+ let fontstackPtr;
14
+ const fontDataPtrs = [];
15
+ try {
16
+ fontstackPtr = ccallNumber(module, 'create_fontstack', ['string'], [fontstack]);
17
+ if (!fontstackPtr) {
18
+ throw new Error('font-maker WASM returned a null fontstack pointer.');
19
+ }
20
+ for (const font of normalizedFonts) {
21
+ const dataPtr = allocateBytes(module, font.bytes);
22
+ fontDataPtrs.push(dataPtr);
23
+ addFace(module, fontstackPtr, font, dataPtr);
24
+ }
25
+ return ranges.map((range) => generateRange(module, fontstackPtr, fontstack, range));
26
+ }
27
+ finally {
28
+ if (fontstackPtr) {
29
+ ccallVoid(module, 'free_fontstack', ['number'], [fontstackPtr]);
30
+ }
31
+ for (const ptr of fontDataPtrs) {
32
+ freePointer(module, ptr);
33
+ }
34
+ }
35
+ }
36
+ async function initializeWasm() {
37
+ try {
38
+ return await loadFontMaker();
39
+ }
40
+ catch (error) {
41
+ throw new Error(`Failed to initialize font-maker WASM: ${formatError(error)}`);
42
+ }
43
+ }
44
+ function addFace(module, fontstackPtr, font, dataPtr) {
45
+ try {
46
+ ccallVoid(module, 'fontstack_add_face', ['number', 'number', 'number'], [
47
+ fontstackPtr,
48
+ dataPtr,
49
+ font.bytes.byteLength,
50
+ ]);
51
+ }
52
+ catch (error) {
53
+ throw new Error(`Failed to add font "${font.name}": ${formatError(error)}`);
54
+ }
55
+ }
56
+ function generateRange(module, fontstackPtr, fontstack, range) {
57
+ let glyphBufferPtr;
58
+ try {
59
+ glyphBufferPtr = ccallNumber(module, 'generate_glyph_buffer', ['number', 'number'], [
60
+ fontstackPtr,
61
+ range.start,
62
+ ]);
63
+ if (!glyphBufferPtr) {
64
+ throw new Error(`font-maker WASM returned a null glyph buffer pointer for ${formatRange(range)}.`);
65
+ }
66
+ const dataPtr = ccallNumber(module, 'glyph_buffer_data', ['number'], [glyphBufferPtr]);
67
+ const byteLength = ccallNumber(module, 'glyph_buffer_size', ['number'], [glyphBufferPtr]);
68
+ if (byteLength <= 0) {
69
+ throw new Error(`font-maker WASM returned an empty glyph buffer for ${formatRange(range)}.`);
70
+ }
71
+ return {
72
+ filename: `${fontstack}/${formatRange(range)}.pbf`,
73
+ bytes: copyBytes(module, dataPtr, byteLength),
74
+ };
75
+ }
76
+ catch (error) {
77
+ throw new Error(`Failed to generate glyph range ${formatRange(range)}: ${formatError(error)}`);
78
+ }
79
+ finally {
80
+ if (glyphBufferPtr) {
81
+ ccallVoid(module, 'free_glyph_buffer', ['number'], [glyphBufferPtr]);
82
+ }
83
+ }
84
+ }
85
+ function validateFontstack(fontstack) {
86
+ if (typeof fontstack !== 'string' || fontstack.trim().length === 0) {
87
+ throw new TypeError('fontstack must be a non-empty string.');
88
+ }
89
+ if (fontstack.includes('\0')) {
90
+ throw new TypeError('fontstack must not contain null bytes.');
91
+ }
92
+ return fontstack;
93
+ }
94
+ function validateFonts(fonts) {
95
+ if (!Array.isArray(fonts) || fonts.length === 0) {
96
+ throw new TypeError('fonts must contain at least one font.');
97
+ }
98
+ return fonts.map((font, index) => validateFont(font, index));
99
+ }
100
+ function validateFont(font, index) {
101
+ if (!font || typeof font !== 'object') {
102
+ throw new TypeError(`fonts[${index}] must be an object.`);
103
+ }
104
+ if (typeof font.name !== 'string' || font.name.trim().length === 0) {
105
+ throw new TypeError(`fonts[${index}].name must be a non-empty string.`);
106
+ }
107
+ if (!(font.bytes instanceof Uint8Array)) {
108
+ throw new TypeError(`fonts[${index}].bytes must be a Uint8Array.`);
109
+ }
110
+ if (!isSupportedFontInput(font.bytes)) {
111
+ throw new TypeError(`fonts[${index}].bytes is not a supported TTF, OTF, WOFF, or WOFF2 font.`);
112
+ }
113
+ return {
114
+ name: font.name,
115
+ bytes: font.bytes,
116
+ settings: validateFontVariationSettings(font.settings, `fonts[${index}].settings`),
117
+ };
118
+ }
119
+ async function normalizeFonts(fonts) {
120
+ try {
121
+ return await Promise.all(fonts.map((font) => normalizeFontInput(font)));
122
+ }
123
+ catch (error) {
124
+ throw new Error(`Failed to normalize font input: ${formatError(error)}`);
125
+ }
126
+ }
127
+ function validateRanges(ranges) {
128
+ if (!Array.isArray(ranges) || ranges.length === 0) {
129
+ throw new TypeError('ranges must contain at least one glyph range.');
130
+ }
131
+ const seen = new Set();
132
+ return ranges.map((range, index) => {
133
+ const normalized = validateRange(range, index);
134
+ const key = formatRange(normalized);
135
+ if (seen.has(key)) {
136
+ throw new TypeError(`Duplicate glyph range: ${key}.`);
137
+ }
138
+ seen.add(key);
139
+ return normalized;
140
+ });
141
+ }
142
+ function validateRange(range, index) {
143
+ if (!range || typeof range !== 'object') {
144
+ throw new TypeError(`ranges[${index}] must be an object.`);
145
+ }
146
+ const expected = range256(Number(range.start));
147
+ if (range.end !== expected.end) {
148
+ throw new RangeError(`ranges[${index}] must be a 256-codepoint range. Expected ${formatRange(expected)}.`);
149
+ }
150
+ return expected;
151
+ }
152
+ function formatRange(range) {
153
+ return `${range.start}-${range.end}`;
154
+ }
155
+ function formatError(error) {
156
+ if (error instanceof Error) {
157
+ return error.message;
158
+ }
159
+ return String(error);
160
+ }
161
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface GlyphRange {
2
+ start: number;
3
+ end: number;
4
+ }
5
+ export declare function range256(start: number): GlyphRange;
6
+ export declare function basicLatinRanges(): GlyphRange[];
7
+ export declare function latinRanges(): GlyphRange[];
8
+ export declare function allBmpRanges(): GlyphRange[];
9
+ //# sourceMappingURL=ranges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranges.d.ts","sourceRoot":"","sources":["../src/ranges.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAGlD;AAED,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAE/C;AAED,wBAAgB,WAAW,IAAI,UAAU,EAAE,CAE1C;AAED,wBAAgB,YAAY,IAAI,UAAU,EAAE,CAE3C"}
package/dist/ranges.js ADDED
@@ -0,0 +1,27 @@
1
+ const RANGE_SIZE = 256;
2
+ const BMP_END = 0xffff;
3
+ export function range256(start) {
4
+ validateRangeStart(start);
5
+ return { start, end: start + RANGE_SIZE - 1 };
6
+ }
7
+ export function basicLatinRanges() {
8
+ return [range256(0)];
9
+ }
10
+ export function latinRanges() {
11
+ return [range256(0), range256(256), range256(512)];
12
+ }
13
+ export function allBmpRanges() {
14
+ return Array.from({ length: (BMP_END + 1) / RANGE_SIZE }, (_, index) => range256(index * RANGE_SIZE));
15
+ }
16
+ function validateRangeStart(start) {
17
+ if (!Number.isInteger(start)) {
18
+ throw new RangeError(`Range start must be an integer. Received ${start}.`);
19
+ }
20
+ if (start < 0 || start + RANGE_SIZE - 1 > BMP_END) {
21
+ throw new RangeError(`Range start must produce a BMP range between 0 and ${BMP_END}. Received ${start}.`);
22
+ }
23
+ if (start % RANGE_SIZE !== 0) {
24
+ throw new RangeError(`Range start must be aligned to ${RANGE_SIZE}. Received ${start}.`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=ranges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranges.js","sourceRoot":"","sources":["../src/ranges.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,OAAO,GAAG,MAAM,CAAC;AAEvB,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC;AACxG,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,4CAA4C,KAAK,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,UAAU,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC;QAClD,MAAM,IAAI,UAAU,CAAC,sDAAsD,OAAO,cAAc,KAAK,GAAG,CAAC,CAAC;IAC5G,CAAC;IAED,IAAI,KAAK,GAAG,UAAU,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,kCAAkC,UAAU,cAAc,KAAK,GAAG,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function loadFontMaker(): Promise<FontMakerModule>;
2
+ //# sourceMappingURL=load-font-maker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-font-maker.d.ts","sourceRoot":"","sources":["../../src/wasm/load-font-maker.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAG9D"}
@@ -0,0 +1,92 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { fileURLToPath } from 'node:url';
3
+ import vm from 'node:vm';
4
+ let loadPromise;
5
+ export async function loadFontMaker() {
6
+ loadPromise ??= loadFontMakerFresh();
7
+ return loadPromise;
8
+ }
9
+ async function loadFontMakerFresh() {
10
+ const vendorDirUrl = new URL('../../maplibre-font-maker/', import.meta.url);
11
+ const glueUrl = new URL('sdfglyph.js', vendorDirUrl);
12
+ const wasmUrl = new URL('sdfglyph.wasm', vendorDirUrl);
13
+ const { WebAssembly } = globalThis;
14
+ const [glueSource, wasmBinary] = await Promise.all([
15
+ readFile(glueUrl, 'utf8'),
16
+ readFile(wasmUrl),
17
+ ]);
18
+ return new Promise((resolve, reject) => {
19
+ let settled = false;
20
+ const finish = (callback) => {
21
+ if (settled) {
22
+ return;
23
+ }
24
+ settled = true;
25
+ callback();
26
+ };
27
+ const moduleConfig = {
28
+ wasmBinary,
29
+ print: () => undefined,
30
+ printErr: () => undefined,
31
+ onAbort: (reason) => {
32
+ finish(() => reject(new Error(`font-maker WASM aborted: ${String(reason)}`)));
33
+ },
34
+ onRuntimeInitialized: () => {
35
+ const utf8ToString = context.UTF8ToString;
36
+ if (typeof utf8ToString === 'function') {
37
+ moduleConfig.UTF8ToString = utf8ToString;
38
+ }
39
+ if (!isInitializedModule(moduleConfig)) {
40
+ finish(() => reject(new Error('font-maker WASM initialized without the expected API.')));
41
+ return;
42
+ }
43
+ finish(() => resolve(moduleConfig));
44
+ },
45
+ };
46
+ const context = vm.createContext({
47
+ Module: moduleConfig,
48
+ console,
49
+ crypto: globalThis.crypto,
50
+ setTimeout,
51
+ clearTimeout,
52
+ setInterval,
53
+ clearInterval,
54
+ TextDecoder,
55
+ TextEncoder,
56
+ WebAssembly,
57
+ });
58
+ try {
59
+ const script = new vm.Script(glueSource, {
60
+ filename: fileURLToPath(glueUrl),
61
+ });
62
+ script.runInContext(context);
63
+ }
64
+ catch (error) {
65
+ finish(() => reject(new Error(`Failed to initialize font-maker WASM: ${formatError(error)}`)));
66
+ }
67
+ });
68
+ }
69
+ function isInitializedModule(module) {
70
+ return (typeof module.ccall === 'function' &&
71
+ typeof module._malloc === 'function' &&
72
+ typeof module._free === 'function' &&
73
+ typeof module.UTF8ToString === 'function' &&
74
+ isUint8ArrayLike(module.HEAPU8));
75
+ }
76
+ // The HEAPU8 typed array is created inside the vm sandbox, so it is not an
77
+ // `instanceof` the host realm's Uint8Array. Duck-type it instead.
78
+ function isUint8ArrayLike(value) {
79
+ return (typeof value === 'object' &&
80
+ value !== null &&
81
+ 'buffer' in value &&
82
+ 'byteLength' in value &&
83
+ 'BYTES_PER_ELEMENT' in value &&
84
+ value.BYTES_PER_ELEMENT === 1);
85
+ }
86
+ function formatError(error) {
87
+ if (error instanceof Error) {
88
+ return error.message;
89
+ }
90
+ return String(error);
91
+ }
92
+ //# sourceMappingURL=load-font-maker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-font-maker.js","sourceRoot":"","sources":["../../src/wasm/load-font-maker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function allocateBytes(module: FontMakerModule, bytes: Uint8Array): Pointer;
2
+ export declare function copyBytes(module: FontMakerModule, ptr: Pointer, byteLength: number): Uint8Array;
3
+ export declare function freePointer(module: FontMakerModule, ptr: Pointer | undefined): void;
4
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/wasm/memory.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CASjF;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAU/F;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAInF"}
@@ -0,0 +1,23 @@
1
+ export function allocateBytes(module, bytes) {
2
+ const ptr = module._malloc(bytes.byteLength);
3
+ if (!ptr) {
4
+ throw new Error(`Failed to allocate ${bytes.byteLength} bytes in font-maker WASM memory.`);
5
+ }
6
+ new Uint8Array(module.HEAPU8.buffer, ptr, bytes.byteLength).set(bytes);
7
+ return ptr;
8
+ }
9
+ export function copyBytes(module, ptr, byteLength) {
10
+ if (!ptr) {
11
+ throw new Error('Cannot copy bytes from a null WASM pointer.');
12
+ }
13
+ if (!Number.isInteger(byteLength) || byteLength < 0) {
14
+ throw new Error(`Invalid WASM byte length: ${byteLength}.`);
15
+ }
16
+ return new Uint8Array(module.HEAPU8.subarray(ptr, ptr + byteLength));
17
+ }
18
+ export function freePointer(module, ptr) {
19
+ if (ptr) {
20
+ module._free(ptr);
21
+ }
22
+ }
23
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/wasm/memory.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,MAAuB,EAAE,KAAiB;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAC,UAAU,mCAAmC,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAuB,EAAE,GAAY,EAAE,UAAkB;IACjF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAuB,EAAE,GAAwB;IAC3E,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function ccallNumber(module: FontMakerModule, ident: string, argTypes: CcallArgumentType[], args: Array<number | string>): number;
2
+ export declare function ccallVoid(module: FontMakerModule, ident: string, argTypes: CcallArgumentType[], args: Array<number | string>): void;
3
+ //# sourceMappingURL=sdfglyph-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdfglyph-module.d.ts","sourceRoot":"","sources":["../../src/wasm/sdfglyph-module.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CACzB,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAC3B,MAAM,CAQR;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAC3B,IAAI,CAEN"}
@@ -0,0 +1,11 @@
1
+ export function ccallNumber(module, ident, argTypes, args) {
2
+ const result = module.ccall(ident, 'number', argTypes, args);
3
+ if (typeof result !== 'number') {
4
+ throw new Error(`Expected ${ident} to return a number.`);
5
+ }
6
+ return result;
7
+ }
8
+ export function ccallVoid(module, ident, argTypes, args) {
9
+ module.ccall(ident, null, argTypes, args);
10
+ }
11
+ //# sourceMappingURL=sdfglyph-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdfglyph-module.js","sourceRoot":"","sources":["../../src/wasm/sdfglyph-module.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CACzB,MAAuB,EACvB,KAAa,EACb,QAA6B,EAC7B,IAA4B;IAE5B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE7D,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,YAAY,KAAK,sBAAsB,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,MAAuB,EACvB,KAAa,EACb,QAA6B,EAC7B,IAA4B;IAE5B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,29 @@
1
+ Copyright (c) 2022 MapLibre contributors
2
+ Copyright (c) 2019-2022, Protomaps LLC
3
+ Copyright (c) 2014, Mapbox
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of [project] nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,19 @@
1
+ # Vendored MapLibre `font-maker` runtime
2
+
3
+ The files in this directory are generated artifacts from MapLibre `font-maker`. They are third-party and must not be edited by hand.
4
+
5
+ - Source repository: `https://github.com/maplibre/font-maker`
6
+ - Source commit inspected for the wrapper API: `c56771948c59a01b89d0498d47dc4abf56c25338`
7
+ - Published artifacts used here:
8
+ - `https://maplibre.org/font-maker/sdfglyph.js`
9
+ - `https://maplibre.org/font-maker/sdfglyph.wasm`
10
+ - `sdfglyph.js` SHA-256: `2D5CCE9E20511E3E1798A696B496CFB4FB9C55CD9CCEAA73FD77849E1C3D7A64`
11
+ - `sdfglyph.wasm` SHA-256: `DE2986E66201499DE76F21BB3A649E1F27D7D68AF21CB2616DC3A7B25BADE691`
12
+
13
+ The upstream BSD-3-Clause license is included at [`LICENSE.font-maker`](./LICENSE.font-maker).
14
+
15
+ To rebuild the runtime from upstream, install Emscripten and Boost headers, initialize upstream submodules, then run:
16
+
17
+ ```sh
18
+ ./build_wasm.sh /path/to/boost
19
+ ```