芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/app.optimyar.com/backend/node_modules/opentype.js/src/opentype.js
// opentype.js // https://github.com/nodebox/opentype.js // (c) 2015 Frederik De Bleser // opentype.js may be freely distributed under the MIT license. /* global DataView, Uint8Array, XMLHttpRequest */ import inflate from 'tiny-inflate'; import Font from './font'; import Glyph from './glyph'; import { CmapEncoding, GlyphNames, addGlyphNames } from './encoding'; import parse from './parse'; import BoundingBox from './bbox'; import Path from './path'; import { nodeBufferToArrayBuffer } from './util'; import cmap from './tables/cmap'; import cff from './tables/cff'; import fvar from './tables/fvar'; import glyf from './tables/glyf'; import gpos from './tables/gpos'; import gsub from './tables/gsub'; import head from './tables/head'; import hhea from './tables/hhea'; import hmtx from './tables/hmtx'; import kern from './tables/kern'; import ltag from './tables/ltag'; import loca from './tables/loca'; import maxp from './tables/maxp'; import _name from './tables/name'; import os2 from './tables/os2'; import post from './tables/post'; import meta from './tables/meta'; /** * The opentype library. * @namespace opentype */ // File loaders ///////////////////////////////////////////////////////// /** * Loads a font from a file. The callback throws an error message as the first parameter if it fails * and the font as an ArrayBuffer in the second parameter if it succeeds. * @param {string} path - The path of the file * @param {Function} callback - The function to call when the font load completes */ function loadFromFile(path, callback) { const fs = require('fs'); fs.readFile(path, function(err, buffer) { if (err) { return callback(err.message); } callback(null, nodeBufferToArrayBuffer(buffer)); }); } /** * Loads a font from a URL. The callback throws an error message as the first parameter if it fails * and the font as an ArrayBuffer in the second parameter if it succeeds. * @param {string} url - The URL of the font file. * @param {Function} callback - The function to call when the font load completes */ function loadFromUrl(url, callback) { const request = new XMLHttpRequest(); request.open('get', url, true); request.responseType = 'arraybuffer'; request.onload = function() { if (request.status !== 200) { return callback('Font could not be loaded: ' + request.statusText); } return callback(null, request.response); }; request.onerror = function () { callback('Font could not be loaded'); }; request.send(); } // Table Directory Entries ////////////////////////////////////////////// /** * Parses OpenType table entries. * @param {DataView} * @param {Number} * @return {Object[]} */ function parseOpenTypeTableEntries(data, numTables) { const tableEntries = []; let p = 12; for (let i = 0; i < numTables; i += 1) { const tag = parse.getTag(data, p); const checksum = parse.getULong(data, p + 4); const offset = parse.getULong(data, p + 8); const length = parse.getULong(data, p + 12); tableEntries.push({tag: tag, checksum: checksum, offset: offset, length: length, compression: false}); p += 16; } return tableEntries; } /** * Parses WOFF table entries. * @param {DataView} * @param {Number} * @return {Object[]} */ function parseWOFFTableEntries(data, numTables) { const tableEntries = []; let p = 44; // offset to the first table directory entry. for (let i = 0; i < numTables; i += 1) { const tag = parse.getTag(data, p); const offset = parse.getULong(data, p + 4); const compLength = parse.getULong(data, p + 8); const origLength = parse.getULong(data, p + 12); let compression; if (compLength < origLength) { compression = 'WOFF'; } else { compression = false; } tableEntries.push({tag: tag, offset: offset, compression: compression, compressedLength: compLength, length: origLength}); p += 20; } return tableEntries; } /** * @typedef TableData * @type Object * @property {DataView} data - The DataView * @property {number} offset - The data offset. */ /** * @param {DataView} * @param {Object} * @return {TableData} */ function uncompressTable(data, tableEntry) { if (tableEntry.compression === 'WOFF') { const inBuffer = new Uint8Array(data.buffer, tableEntry.offset + 2, tableEntry.compressedLength - 2); const outBuffer = new Uint8Array(tableEntry.length); inflate(inBuffer, outBuffer); if (outBuffer.byteLength !== tableEntry.length) { throw new Error('Decompression error: ' + tableEntry.tag + ' decompressed length doesn\'t match recorded length'); } const view = new DataView(outBuffer.buffer, 0); return {data: view, offset: 0}; } else { return {data: data, offset: tableEntry.offset}; } } // Public API /////////////////////////////////////////////////////////// /** * Parse the OpenType file data (as an ArrayBuffer) and return a Font object. * Throws an error if the font could not be parsed. * @param {ArrayBuffer} * @return {opentype.Font} */ function parseBuffer(buffer) { let indexToLocFormat; let ltagTable; // Since the constructor can also be called to create new fonts from scratch, we indicate this // should be an empty font that we'll fill with our own data. const font = new Font({empty: true}); // OpenType fonts use big endian byte ordering. // We can't rely on typed array view types, because they operate with the endianness of the host computer. // Instead we use DataViews where we can specify endianness. const data = new DataView(buffer, 0); let numTables; let tableEntries = []; const signature = parse.getTag(data, 0); if (signature === String.fromCharCode(0, 1, 0, 0) || signature === 'true' || signature === 'typ1') { font.outlinesFormat = 'truetype'; numTables = parse.getUShort(data, 4); tableEntries = parseOpenTypeTableEntries(data, numTables); } else if (signature === 'OTTO') { font.outlinesFormat = 'cff'; numTables = parse.getUShort(data, 4); tableEntries = parseOpenTypeTableEntries(data, numTables); } else if (signature === 'wOFF') { const flavor = parse.getTag(data, 4); if (flavor === String.fromCharCode(0, 1, 0, 0)) { font.outlinesFormat = 'truetype'; } else if (flavor === 'OTTO') { font.outlinesFormat = 'cff'; } else { throw new Error('Unsupported OpenType flavor ' + signature); } numTables = parse.getUShort(data, 12); tableEntries = parseWOFFTableEntries(data, numTables); } else { throw new Error('Unsupported OpenType signature ' + signature); } let cffTableEntry; let fvarTableEntry; let glyfTableEntry; let gposTableEntry; let gsubTableEntry; let hmtxTableEntry; let kernTableEntry; let locaTableEntry; let nameTableEntry; let metaTableEntry; let p; for (let i = 0; i < numTables; i += 1) { const tableEntry = tableEntries[i]; let table; switch (tableEntry.tag) { case 'cmap': table = uncompressTable(data, tableEntry); font.tables.cmap = cmap.parse(table.data, table.offset); font.encoding = new CmapEncoding(font.tables.cmap); break; case 'cvt ' : table = uncompressTable(data, tableEntry); p = new parse.Parser(table.data, table.offset); font.tables.cvt = p.parseShortList(tableEntry.length / 2); break; case 'fvar': fvarTableEntry = tableEntry; break; case 'fpgm' : table = uncompressTable(data, tableEntry); p = new parse.Parser(table.data, table.offset); font.tables.fpgm = p.parseByteList(tableEntry.length); break; case 'head': table = uncompressTable(data, tableEntry); font.tables.head = head.parse(table.data, table.offset); font.unitsPerEm = font.tables.head.unitsPerEm; indexToLocFormat = font.tables.head.indexToLocFormat; break; case 'hhea': table = uncompressTable(data, tableEntry); font.tables.hhea = hhea.parse(table.data, table.offset); font.ascender = font.tables.hhea.ascender; font.descender = font.tables.hhea.descender; font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics; break; case 'hmtx': hmtxTableEntry = tableEntry; break; case 'ltag': table = uncompressTable(data, tableEntry); ltagTable = ltag.parse(table.data, table.offset); break; case 'maxp': table = uncompressTable(data, tableEntry); font.tables.maxp = maxp.parse(table.data, table.offset); font.numGlyphs = font.tables.maxp.numGlyphs; break; case 'name': nameTableEntry = tableEntry; break; case 'OS/2': table = uncompressTable(data, tableEntry); font.tables.os2 = os2.parse(table.data, table.offset); break; case 'post': table = uncompressTable(data, tableEntry); font.tables.post = post.parse(table.data, table.offset); font.glyphNames = new GlyphNames(font.tables.post); break; case 'prep' : table = uncompressTable(data, tableEntry); p = new parse.Parser(table.data, table.offset); font.tables.prep = p.parseByteList(tableEntry.length); break; case 'glyf': glyfTableEntry = tableEntry; break; case 'loca': locaTableEntry = tableEntry; break; case 'CFF ': cffTableEntry = tableEntry; break; case 'kern': kernTableEntry = tableEntry; break; case 'GPOS': gposTableEntry = tableEntry; break; case 'GSUB': gsubTableEntry = tableEntry; break; case 'meta': metaTableEntry = tableEntry; break; } } const nameTable = uncompressTable(data, nameTableEntry); font.tables.name = _name.parse(nameTable.data, nameTable.offset, ltagTable); font.names = font.tables.name; if (glyfTableEntry && locaTableEntry) { const shortVersion = indexToLocFormat === 0; const locaTable = uncompressTable(data, locaTableEntry); const locaOffsets = loca.parse(locaTable.data, locaTable.offset, font.numGlyphs, shortVersion); const glyfTable = uncompressTable(data, glyfTableEntry); font.glyphs = glyf.parse(glyfTable.data, glyfTable.offset, locaOffsets, font); } else if (cffTableEntry) { const cffTable = uncompressTable(data, cffTableEntry); cff.parse(cffTable.data, cffTable.offset, font); } else { throw new Error('Font doesn\'t contain TrueType or CFF outlines.'); } const hmtxTable = uncompressTable(data, hmtxTableEntry); hmtx.parse(hmtxTable.data, hmtxTable.offset, font.numberOfHMetrics, font.numGlyphs, font.glyphs); addGlyphNames(font); if (kernTableEntry) { const kernTable = uncompressTable(data, kernTableEntry); font.kerningPairs = kern.parse(kernTable.data, kernTable.offset); } else { font.kerningPairs = {}; } if (gposTableEntry) { const gposTable = uncompressTable(data, gposTableEntry); gpos.parse(gposTable.data, gposTable.offset, font); } if (gsubTableEntry) { const gsubTable = uncompressTable(data, gsubTableEntry); font.tables.gsub = gsub.parse(gsubTable.data, gsubTable.offset); } if (fvarTableEntry) { const fvarTable = uncompressTable(data, fvarTableEntry); font.tables.fvar = fvar.parse(fvarTable.data, fvarTable.offset, font.names); } if (metaTableEntry) { const metaTable = uncompressTable(data, metaTableEntry); font.tables.meta = meta.parse(metaTable.data, metaTable.offset); font.metas = font.tables.meta; } return font; } /** * Asynchronously load the font from a URL or a filesystem. When done, call the callback * with two arguments `(err, font)`. The `err` will be null on success, * the `font` is a Font object. * We use the node.js callback convention so that * opentype.js can integrate with frameworks like async.js. * @alias opentype.load * @param {string} url - The URL of the font to load. * @param {Function} callback - The callback. */ function load(url, callback) { const isNode = typeof window === 'undefined'; const loadFn = isNode ? loadFromFile : loadFromUrl; loadFn(url, function(err, arrayBuffer) { if (err) { return callback(err); } let font; try { font = parseBuffer(arrayBuffer); } catch (e) { return callback(e, null); } return callback(null, font); }); } /** * Synchronously load the font from a URL or file. * When done, returns the font object or throws an error. * @alias opentype.loadSync * @param {string} url - The URL of the font to load. * @return {opentype.Font} */ function loadSync(url) { const fs = require('fs'); const buffer = fs.readFileSync(url); return parseBuffer(nodeBufferToArrayBuffer(buffer)); } export { Font, Glyph, Path, BoundingBox, parse as _parse, parseBuffer as parse, load, loadSync };