@weasel-js/font 1.9.2 → 1.9.4
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/{chunk-RYN4NYX4.js → chunk-ERSHQYJL.js} +99 -17
- package/dist/chunk-ERSHQYJL.js.map +1 -0
- package/dist/index.d.ts +14 -3
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/{test-seams-Df2Zqwk8.d.ts → test-seams-BC5Ykf4D.d.ts} +1 -0
- package/dist/test-seams.d.ts +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-RYN4NYX4.js.map +0 -1
|
@@ -97,6 +97,19 @@ function parseBmFont(raw) {
|
|
|
97
97
|
if (!Array.isArray(r.chars)) throw new Error("parseBmFont: chars must be an array");
|
|
98
98
|
const info = r.info;
|
|
99
99
|
const common = r.common;
|
|
100
|
+
const positive = [
|
|
101
|
+
["info.size", info.size],
|
|
102
|
+
["common.scaleW", common.scaleW],
|
|
103
|
+
["common.scaleH", common.scaleH]
|
|
104
|
+
];
|
|
105
|
+
for (const [name, value] of positive) {
|
|
106
|
+
if (typeof value !== "number" || !(value > 0) || !Number.isFinite(value)) {
|
|
107
|
+
throw new Error(`parseBmFont: ${name} must be a positive number`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (typeof common.base !== "number" || !Number.isFinite(common.base)) {
|
|
111
|
+
throw new Error("parseBmFont: common.base must be a number");
|
|
112
|
+
}
|
|
100
113
|
const chars = r.chars;
|
|
101
114
|
const kernings = Array.isArray(r.kernings) ? r.kernings : [];
|
|
102
115
|
const charMap = /* @__PURE__ */ new Map();
|
|
@@ -178,6 +191,27 @@ function _resetFallbackForTests() {
|
|
|
178
191
|
warnedFallbacks.clear();
|
|
179
192
|
}
|
|
180
193
|
|
|
194
|
+
// src/cssFamily.ts
|
|
195
|
+
function cssFamilyName(family) {
|
|
196
|
+
if (/[,"']/.test(family)) return family;
|
|
197
|
+
return GENERIC_FAMILIES.has(family.trim().toLowerCase()) ? family.trim() : JSON.stringify(family);
|
|
198
|
+
}
|
|
199
|
+
var GENERIC_FAMILIES = /* @__PURE__ */ new Set([
|
|
200
|
+
"serif",
|
|
201
|
+
"sans-serif",
|
|
202
|
+
"monospace",
|
|
203
|
+
"cursive",
|
|
204
|
+
"fantasy",
|
|
205
|
+
"system-ui",
|
|
206
|
+
"ui-serif",
|
|
207
|
+
"ui-sans-serif",
|
|
208
|
+
"ui-monospace",
|
|
209
|
+
"ui-rounded",
|
|
210
|
+
"math",
|
|
211
|
+
"emoji",
|
|
212
|
+
"fangsong"
|
|
213
|
+
]);
|
|
214
|
+
|
|
181
215
|
// src/dynamic/shelfPack.ts
|
|
182
216
|
var ShelfPacker = class {
|
|
183
217
|
constructor(pageSize, maxPages) {
|
|
@@ -299,7 +333,7 @@ var BAKE_SIZE = 48;
|
|
|
299
333
|
var PAD = 8;
|
|
300
334
|
var METRICS_SIZE = 1e3;
|
|
301
335
|
function cssFontString(weight, style, family, size = BAKE_SIZE) {
|
|
302
|
-
return `${style === "italic" ? "italic " : ""}${weight} ${size}px ${
|
|
336
|
+
return `${style === "italic" ? "italic " : ""}${weight} ${size}px ${cssFamilyName(family)}`;
|
|
303
337
|
}
|
|
304
338
|
function createCanvasRasterizer() {
|
|
305
339
|
let canvas;
|
|
@@ -580,9 +614,7 @@ function _resetDynamicFontsForTests() {
|
|
|
580
614
|
// src/outline/OutlineFace.ts
|
|
581
615
|
var OUTLINE_PRECISION = 5;
|
|
582
616
|
|
|
583
|
-
// src/outline/
|
|
584
|
-
var SFNT_HEADER_BYTES = 12;
|
|
585
|
-
var TABLE_RECORD_BYTES = 16;
|
|
617
|
+
// src/outline/tag.ts
|
|
586
618
|
function tagAt(view, offset) {
|
|
587
619
|
return String.fromCharCode(
|
|
588
620
|
view.getUint8(offset),
|
|
@@ -591,10 +623,11 @@ function tagAt(view, offset) {
|
|
|
591
623
|
view.getUint8(offset + 3)
|
|
592
624
|
);
|
|
593
625
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
626
|
+
|
|
627
|
+
// src/outline/dataFork.ts
|
|
628
|
+
var RESOURCE_HEADER_BYTES = 16;
|
|
629
|
+
var TYPE_ENTRY_BYTES = 8;
|
|
630
|
+
var REFERENCE_BYTES = 12;
|
|
598
631
|
var FONT_SIGNATURES = /* @__PURE__ */ new Set([
|
|
599
632
|
"\0\0\0",
|
|
600
633
|
"true",
|
|
@@ -604,7 +637,6 @@ var FONT_SIGNATURES = /* @__PURE__ */ new Set([
|
|
|
604
637
|
"wOFF",
|
|
605
638
|
"wOF2"
|
|
606
639
|
]);
|
|
607
|
-
var RESOURCE_HEADER_BYTES = 16;
|
|
608
640
|
function isDataForkFont(bytes) {
|
|
609
641
|
if (bytes.byteLength < RESOURCE_HEADER_BYTES) return false;
|
|
610
642
|
const view = new DataView(bytes);
|
|
@@ -615,6 +647,46 @@ function isDataForkFont(bytes) {
|
|
|
615
647
|
const mapLength = view.getUint32(12);
|
|
616
648
|
return dataOffset >= RESOURCE_HEADER_BYTES && dataOffset + dataLength === mapOffset && mapOffset + mapLength <= bytes.byteLength;
|
|
617
649
|
}
|
|
650
|
+
var truncated = () => new Error("Datafork TrueType (.dfont) is truncated: a resource runs past the end of its segment.");
|
|
651
|
+
function sfntResources(bytes) {
|
|
652
|
+
const view = new DataView(bytes);
|
|
653
|
+
const dataOffset = view.getUint32(0);
|
|
654
|
+
const mapOffset = view.getUint32(4);
|
|
655
|
+
const dataLength = view.getUint32(8);
|
|
656
|
+
const mapEnd = mapOffset + view.getUint32(12);
|
|
657
|
+
const inMap = (at, count) => at >= mapOffset && at + count <= mapEnd;
|
|
658
|
+
if (!inMap(mapOffset + 24, 2)) return [];
|
|
659
|
+
const typeList = mapOffset + view.getUint16(mapOffset + 24);
|
|
660
|
+
if (!inMap(typeList, 2)) return [];
|
|
661
|
+
const typeCount = view.getUint16(typeList) + 1 & 65535;
|
|
662
|
+
const out = [];
|
|
663
|
+
for (let t = 0; t < typeCount; t++) {
|
|
664
|
+
const entry = typeList + 2 + t * TYPE_ENTRY_BYTES;
|
|
665
|
+
if (!inMap(entry, TYPE_ENTRY_BYTES)) throw truncated();
|
|
666
|
+
if (tagAt(view, entry) !== "sfnt") continue;
|
|
667
|
+
const count = view.getUint16(entry + 4) + 1;
|
|
668
|
+
const references = typeList + view.getUint16(entry + 6);
|
|
669
|
+
for (let i = 0; i < count; i++) {
|
|
670
|
+
const ref = references + i * REFERENCE_BYTES;
|
|
671
|
+
if (!inMap(ref, REFERENCE_BYTES)) throw truncated();
|
|
672
|
+
const offset = view.getUint32(ref + 4) & 16777215;
|
|
673
|
+
if (offset + 4 > dataLength) throw truncated();
|
|
674
|
+
const start = dataOffset + offset + 4;
|
|
675
|
+
const length = view.getUint32(start - 4);
|
|
676
|
+
if (offset + 4 + length > dataLength) throw truncated();
|
|
677
|
+
out.push(bytes.slice(start, start + length));
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return out;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// src/outline/sfnt.ts
|
|
684
|
+
var SFNT_HEADER_BYTES = 12;
|
|
685
|
+
var TABLE_RECORD_BYTES = 16;
|
|
686
|
+
function isFontCollection(bytes) {
|
|
687
|
+
if (bytes.byteLength < 4) return false;
|
|
688
|
+
return tagAt(new DataView(bytes), 0) === "ttcf";
|
|
689
|
+
}
|
|
618
690
|
function readTableDirectory(view, dirOffset) {
|
|
619
691
|
const numTables = view.getUint16(dirOffset + 4);
|
|
620
692
|
const records = [];
|
|
@@ -653,7 +725,12 @@ function extractFont(source, view, dirOffset) {
|
|
|
653
725
|
const records = readTableDirectory(view, dirOffset);
|
|
654
726
|
const padded = (n) => n + 3 & -4;
|
|
655
727
|
let total = SFNT_HEADER_BYTES + records.length * TABLE_RECORD_BYTES;
|
|
656
|
-
for (const r of records)
|
|
728
|
+
for (const r of records) {
|
|
729
|
+
if (r.offset + r.length > source.byteLength) {
|
|
730
|
+
throw new Error(`font collection is truncated: table "${r.tag}" runs past the end of the file`);
|
|
731
|
+
}
|
|
732
|
+
total += padded(r.length);
|
|
733
|
+
}
|
|
657
734
|
const out = new ArrayBuffer(total);
|
|
658
735
|
const dst = new DataView(out);
|
|
659
736
|
const dstBytes = new Uint8Array(out);
|
|
@@ -679,9 +756,13 @@ function extractFont(source, view, dirOffset) {
|
|
|
679
756
|
}
|
|
680
757
|
function sfntFromCollection(bytes, postScriptName) {
|
|
681
758
|
if (isDataForkFont(bytes)) {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
)
|
|
759
|
+
const fonts = sfntResources(bytes);
|
|
760
|
+
if (fonts.length === 0) throw new Error("Datafork TrueType (.dfont) holds no sfnt resource.");
|
|
761
|
+
const named = postScriptName ? fonts.find((font) => {
|
|
762
|
+
const view2 = new DataView(font);
|
|
763
|
+
return postScriptNameAt(view2, readTableDirectory(view2, 0)) === postScriptName;
|
|
764
|
+
}) : void 0;
|
|
765
|
+
return { bytes: named ?? fonts[0], matched: named !== void 0 || !postScriptName };
|
|
685
766
|
}
|
|
686
767
|
if (!isFontCollection(bytes)) return { bytes, matched: true };
|
|
687
768
|
const view = new DataView(bytes);
|
|
@@ -1280,6 +1361,7 @@ function missResolveResult(family, weight, style, suppressWarn = false) {
|
|
|
1280
1361
|
source: "outline"
|
|
1281
1362
|
};
|
|
1282
1363
|
}
|
|
1364
|
+
if (fontPending(family, weight, style)) return pendingMiss(family, weight, style);
|
|
1283
1365
|
const policy2 = getFontFallbackPolicy();
|
|
1284
1366
|
if (policy2 === "canvas") {
|
|
1285
1367
|
autoEnrollCanvasFont(family);
|
|
@@ -1525,7 +1607,7 @@ function cssFontFamily(family, variant = {}) {
|
|
|
1525
1607
|
if (!priv) return family;
|
|
1526
1608
|
const name = nameFor(priv.target);
|
|
1527
1609
|
for (const v of priv.variants) ensureFace(name, v.family, v.weight, v.style);
|
|
1528
|
-
return `${JSON.stringify(name)}, ${family}`;
|
|
1610
|
+
return `${JSON.stringify(name)}, ${cssFamilyName(family)}`;
|
|
1529
1611
|
}
|
|
1530
1612
|
function cssFontFamilyLoading(family, variant = {}) {
|
|
1531
1613
|
const priv = privateFamily(family, variant);
|
|
@@ -1584,6 +1666,6 @@ function _resetDomFacesForTests() {
|
|
|
1584
1666
|
warned2.clear();
|
|
1585
1667
|
}
|
|
1586
1668
|
|
|
1587
|
-
export { DEFAULT_BAKE_BUDGET, FIXTURE_FONT, PAGE_SIZE, SDF_RADIUS, __setGlyphRasterizerForTests, _getPagesForTests, _resetDomFacesForTests, _resetDynamicFontsForTests, _resetFallbackForTests, _resetFontOutlinesForTests, _resetFontRegistryForTests, createOpenTypeParser, cssFontFamily, cssFontFamilyLoading, dynamicPageTextureId, ensureFontTexture, faceMetricsFor, faceMetricsFromTables, faceMetricsOf, fontOutlineRegistry, fontPending, fontRegistry, getDefaultFontFamily, getFont, getFontFallbackPolicy, glyphGeneration, glyphOutline, hasFontOutlines, isCanvasFont, listCanvasFonts, listFontOutlines, listFontWeights, listFonts, loadFontOutlines, markAllFontsNotUploaded, outlineMetrics, outlineStatus, parseBmFont, registerCanvasFont, registerFont, registerFontOutlines, resetBakeBudget, resolveFontVariant, resolveGlyphFallback, setDefaultFontFamily, setFontFallbackPolicy, subscribeGlyphReady, syncDynamicPageTexture, textureCacheKey, unregisterCanvasFont, unregisterFontOutlines, verticalMetricsFromTables, warmFonts };
|
|
1588
|
-
//# sourceMappingURL=chunk-
|
|
1589
|
-
//# sourceMappingURL=chunk-
|
|
1669
|
+
export { DEFAULT_BAKE_BUDGET, FIXTURE_FONT, PAGE_SIZE, SDF_RADIUS, __setGlyphRasterizerForTests, _getPagesForTests, _resetDomFacesForTests, _resetDynamicFontsForTests, _resetFallbackForTests, _resetFontOutlinesForTests, _resetFontRegistryForTests, createOpenTypeParser, cssFamilyName, cssFontFamily, cssFontFamilyLoading, dynamicPageTextureId, ensureFontTexture, faceMetricsFor, faceMetricsFromTables, faceMetricsOf, fontOutlineRegistry, fontPending, fontRegistry, getDefaultFontFamily, getFont, getFontFallbackPolicy, glyphGeneration, glyphOutline, hasFontOutlines, isCanvasFont, listCanvasFonts, listFontOutlines, listFontWeights, listFonts, loadFontOutlines, markAllFontsNotUploaded, outlineMetrics, outlineStatus, parseBmFont, registerCanvasFont, registerFont, registerFontOutlines, resetBakeBudget, resolveFontVariant, resolveGlyphFallback, setDefaultFontFamily, setFontFallbackPolicy, subscribeGlyphReady, syncDynamicPageTexture, textureCacheKey, unregisterCanvasFont, unregisterFontOutlines, verticalMetricsFromTables, warmFonts };
|
|
1670
|
+
//# sourceMappingURL=chunk-ERSHQYJL.js.map
|
|
1671
|
+
//# sourceMappingURL=chunk-ERSHQYJL.js.map
|