UNPKG

lib-font

Version:

A JS based OpenType font inspector

109 lines (97 loc) 2.95 kB
import { SimpleTable } from "./tables/simple-table.js"; import lazy from "../lazy.js"; const gzipDecode = globalThis.pako ? globalThis.pako.inflate : undefined; let nativeGzipDecode = undefined; if (!gzipDecode) { import("zlib").then((zlib) => { nativeGzipDecode = (buffer) => zlib.unzipSync(buffer); }); } /** * The WOFF header * * See https://www.w3.org/TR/WOFF for WOFF information * See https://docs.microsoft.com/en-us/typography/opentype/spec/overview for font information */ class WOFF extends SimpleTable { constructor(font, dataview, createTable) { const { p } = super({ offset: 0, length: 44 }, dataview, `woff`); this.signature = p.tag; this.flavor = p.uint32; this.length = p.uint32; this.numTables = p.uint16; p.uint16; this.totalSfntSize = p.uint32; this.majorVersion = p.uint16; this.minorVersion = p.uint16; this.metaOffset = p.uint32; this.metaLength = p.uint32; this.metaOrigLength = p.uint32; this.privOffset = p.uint32; this.privLength = p.uint32; p.verifyLength(); this.directory = [...new Array(this.numTables)].map( (_) => new WoffTableDirectoryEntry(p) ); buildWoffLazyLookups(this, dataview, createTable); } } /** * ... */ class WoffTableDirectoryEntry { constructor(p) { this.tag = p.tag; this.offset = p.uint32; this.compLength = p.uint32; this.origLength = p.uint32; this.origChecksum = p.uint32; } } /** * Build late-evaluating properties for each table in a * woff/woff2 font, so that accessing a table via the * woff.tables.tableName or woff2.tables.tableName * property kicks off a table parse on first access. * * @param {*} woff the woff or woff2 font object * @param {DataView} dataview passed when dealing with woff * @param {buffer} decoded passed when dealing with woff2 */ function buildWoffLazyLookups(woff, dataview, createTable) { woff.tables = {}; woff.directory.forEach((entry) => { lazy(woff.tables, entry.tag.trim(), () => { let offset = 0; let view = dataview; // compressed data? if (entry.compLength !== entry.origLength) { const data = dataview.buffer.slice( entry.offset, entry.offset + entry.compLength ); let unpacked; if (gzipDecode) { unpacked = gzipDecode(new Uint8Array(data)); } else if (nativeGzipDecode) { unpacked = nativeGzipDecode(new Uint8Array(data)); } else { const msg = `no brotli decoder available to decode WOFF2 font`; if (font.onerror) font.onerror(msg); throw new Error(msg); } view = new DataView(unpacked.buffer); } // uncompressed data. else { offset = entry.offset; } return createTable( woff.tables, { tag: entry.tag, offset, length: entry.origLength }, view ); }); }); } export { WOFF };