UNPKG

@itwin/core-backend

Version:
143 lines 5.7 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.EmbeddedFontFile = exports.CadFontFile = void 0; exports.shxFontFileFromBlob = shxFontFileFromBlob; exports.rscFontFileFromBlob = rscFontFileFromBlob; exports.trueTypeFontFileFromFileName = trueTypeFontFileFromFileName; const fs = require("fs"); const core_common_1 = require("@itwin/core-common"); const Symbols_1 = require("./Symbols"); const core_bentley_1 = require("@itwin/core-bentley"); const NativePlatform_1 = require("./NativePlatform"); class FontFileImpl { [Symbols_1._implementationProhibited] = undefined; faces; get isEmbeddable() { return true; } [Symbols_1._key]; [Symbols_1._faceProps]; constructor(faces) { this.faces = faces.map((face) => { return { familyName: face.familyName, isBold: face.faceName.startsWith("bold"), isItalic: face.faceName.endsWith("italic"), }; }); this[Symbols_1._faceProps] = faces; // Sort the face props in canonical order so we can compare FontFiles for equivalent contents. this[Symbols_1._faceProps].sort((a, b) => a.familyName.localeCompare(b.familyName) || a.faceName.localeCompare(b.faceName) || (0, core_bentley_1.compareNumbersOrUndefined)(a.subId, b.subId)); // Stringify the face props so that the key properties (and no other properties) appear in a canonical order. for trivial comparisons. this[Symbols_1._key] = JSON.stringify(this[Symbols_1._faceProps], ["familyName", "faceName", "type", "subId"]); } } /** Points to an OpenType font file on disk. */ class TrueTypeFontFile extends FontFileImpl { #fileName; #embeddable; constructor(fileName, embeddable, faces) { super(faces); this.#fileName = fileName; this.#embeddable = embeddable; } get type() { return core_common_1.FontType.TrueType; } get isEmbeddable() { return this.#embeddable; } [Symbols_1._getData]() { return fs.readFileSync(this.#fileName); } } /** Holds the binary representation of a SHX or RSC font in memory. */ class CadFontFile extends FontFileImpl { #data; #type; constructor(data, type, faces) { super(faces); this.#data = data; this.#type = type; } get type() { return this.#type; } [Symbols_1._getData]() { return this.#data; } } exports.CadFontFile = CadFontFile; /** Points to a font file in any format embedded in an iModel. */ class EmbeddedFontFile extends FontFileImpl { // The value of the Id column for the row in the be_Prop table that embeds this font's data. #db; #id; #type; constructor(db, id, type, faces) { super(faces); this.#db = db; this.#id = id; this.#type = type; } get type() { return this.#type; } [Symbols_1._getData]() { const data = this.#db.queryFilePropertyBlob({ namespace: "dgn_Font", name: "EmbeddedFaceData", id: this.#id, }); if (!data) { throw new Error("Embedded font not found"); } return data; } } exports.EmbeddedFontFile = EmbeddedFontFile; function shxFontFileFromBlob(args) { if (args.familyName.length === 0) { throw new Error("Font family name cannot be empty"); } // An SHX file with fewer than 40 bytes isn't valid. const minShxSize = 40; const shxHeaders = [ "AutoCAD-86 unifont 1.0", "AutoCAD-86 shapes 1.0", "AutoCAD-86 shapes 1.1", ].map((shxHeader) => Array.from(shxHeader)) .map((chars) => new Uint8Array(chars.map((ch) => ch.charCodeAt(0)))); // See https://github.com/iTwin/imodel-native/blob/91f509c2175dc49ce1efcf5a906c9a9aa193451d/iModelCore/iModelPlatform/DgnCore/ShxFont.cpp#L44 function validateShx(blob) { if (blob.length >= minShxSize) { for (const header of shxHeaders) { if (header.every((char, index) => char === blob[index])) { return; } } } throw new Error("Failed to read font file"); } validateShx(args.blob); return new CadFontFile(args.blob, core_common_1.FontType.Shx, [{ faceName: "regular", familyName: args.familyName, type: core_common_1.FontType.Shx, }]); } function rscFontFileFromBlob(args) { if (args.familyName.length === 0) { throw new Error("Font family name cannot be empty"); } if (!NativePlatform_1.IModelNative.platform.isRscFontData(args.blob)) { throw new Error("Failed to read font file"); } return new CadFontFile(args.blob, core_common_1.FontType.Rsc, [{ faceName: "regular", familyName: args.familyName, type: core_common_1.FontType.Rsc, encoding: args.encoding, }]); } function trueTypeFontFileFromFileName(fileName) { const metadata = NativePlatform_1.IModelNative.platform.getTrueTypeFontMetadata(fileName); if (metadata.faces.length === 0) { // The input was almost certainly not a TrueType font file. throw new Error("Failed to read font file"); } return new TrueTypeFontFile(fileName, metadata.embeddable, metadata.faces); } //# sourceMappingURL=FontFileImpl.js.map