/* Copyright 2021 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { CalibriBoldFactors, CalibriBoldItalicFactors, CalibriBoldItalicMetrics, CalibriBoldMetrics, CalibriItalicFactors, CalibriItalicMetrics, CalibriRegularFactors, CalibriRegularMetrics, } from "./calibri_factors.js"; import { Dict, Name } from "./primitives.js"; import { HelveticaBoldFactors, HelveticaBoldItalicFactors, HelveticaBoldItalicMetrics, HelveticaBoldMetrics, HelveticaItalicFactors, HelveticaItalicMetrics, HelveticaRegularFactors, HelveticaRegularMetrics, } from "./helvetica_factors.js"; import { LiberationSansBoldItalicMapping, LiberationSansBoldItalicWidths, LiberationSansBoldMapping, LiberationSansBoldWidths, LiberationSansItalicMapping, LiberationSansItalicWidths, LiberationSansRegularMapping, LiberationSansRegularWidths, } from "./liberationsans_widths.js"; import { MyriadProBoldFactors, MyriadProBoldItalicFactors, MyriadProBoldItalicMetrics, MyriadProBoldMetrics, MyriadProItalicFactors, MyriadProItalicMetrics, MyriadProRegularFactors, MyriadProRegularMetrics, } from "./myriadpro_factors.js"; import { SegoeuiBoldFactors, SegoeuiBoldItalicFactors, SegoeuiBoldItalicMetrics, SegoeuiBoldMetrics, SegoeuiItalicFactors, SegoeuiItalicMetrics, SegoeuiRegularFactors, SegoeuiRegularMetrics, } from "./segoeui_factors.js"; import { getLookupTableFactory } from "./core_utils.js"; import { normalizeFontName } from "./fonts_utils.js"; const getXFAFontMap = getLookupTableFactory(function (t) { t["MyriadPro-Regular"] = t["PdfJS-Fallback-Regular"] = { name: "LiberationSans-Regular", factors: MyriadProRegularFactors, baseWidths: LiberationSansRegularWidths, baseMapping: LiberationSansRegularMapping, metrics: MyriadProRegularMetrics, }; t["MyriadPro-Bold"] = t["PdfJS-Fallback-Bold"] = { name: "LiberationSans-Bold", factors: MyriadProBoldFactors, baseWidths: LiberationSansBoldWidths, baseMapping: LiberationSansBoldMapping, metrics: MyriadProBoldMetrics, }; t["MyriadPro-It"] = t["MyriadPro-Italic"] = t["PdfJS-Fallback-Italic"] = { name: "LiberationSans-Italic", factors: MyriadProItalicFactors, baseWidths: LiberationSansItalicWidths, baseMapping: LiberationSansItalicMapping, metrics: MyriadProItalicMetrics, }; t["MyriadPro-BoldIt"] = t["MyriadPro-BoldItalic"] = t["PdfJS-Fallback-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: MyriadProBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, baseMapping: LiberationSansBoldItalicMapping, metrics: MyriadProBoldItalicMetrics, }; t.ArialMT = t.Arial = t["Arial-Regular"] = { name: "LiberationSans-Regular", baseWidths: LiberationSansRegularWidths, baseMapping: LiberationSansRegularMapping, }; t["Arial-BoldMT"] = t["Arial-Bold"] = { name: "LiberationSans-Bold", baseWidths: LiberationSansBoldWidths, baseMapping: LiberationSansBoldMapping, }; t["Arial-ItalicMT"] = t["Arial-Italic"] = { name: "LiberationSans-Italic", baseWidths: LiberationSansItalicWidths, baseMapping: LiberationSansItalicMapping, }; t["Arial-BoldItalicMT"] = t["Arial-BoldItalic"] = { name: "LiberationSans-BoldItalic", baseWidths: LiberationSansBoldItalicWidths, baseMapping: LiberationSansBoldItalicMapping, }; t["Calibri-Regular"] = { name: "LiberationSans-Regular", factors: CalibriRegularFactors, baseWidths: LiberationSansRegularWidths, baseMapping: LiberationSansRegularMapping, metrics: CalibriRegularMetrics, }; t["Calibri-Bold"] = { name: "LiberationSans-Bold", factors: CalibriBoldFactors, baseWidths: LiberationSansBoldWidths, baseMapping: LiberationSansBoldMapping, metrics: CalibriBoldMetrics, }; t["Calibri-Italic"] = { name: "LiberationSans-Italic", factors: CalibriItalicFactors, baseWidths: LiberationSansItalicWidths, baseMapping: LiberationSansItalicMapping, metrics: CalibriItalicMetrics, }; t["Calibri-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: CalibriBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, baseMapping: LiberationSansBoldItalicMapping, metrics: CalibriBoldItalicMetrics, }; t["Segoeui-Regular"] = { name: "LiberationSans-Regular", factors: SegoeuiRegularFactors, baseWidths: LiberationSansRegularWidths, baseMapping: LiberationSansRegularMapping, metrics: SegoeuiRegularMetrics, }; t["Segoeui-Bold"] = { name: "LiberationSans-Bold", factors: SegoeuiBoldFactors, baseWidths: LiberationSansBoldWidths, baseMapping: LiberationSansBoldMapping, metrics: SegoeuiBoldMetrics, }; t["Segoeui-Italic"] = { name: "LiberationSans-Italic", factors: SegoeuiItalicFactors, baseWidths: LiberationSansItalicWidths, baseMapping: LiberationSansItalicMapping, metrics: SegoeuiItalicMetrics, }; t["Segoeui-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: SegoeuiBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, baseMapping: LiberationSansBoldItalicMapping, metrics: SegoeuiBoldItalicMetrics, }; t["Helvetica-Regular"] = t.Helvetica = { name: "LiberationSans-Regular", factors: HelveticaRegularFactors, baseWidths: LiberationSansRegularWidths, baseMapping: LiberationSansRegularMapping, metrics: HelveticaRegularMetrics, }; t["Helvetica-Bold"] = { name: "LiberationSans-Bold", factors: HelveticaBoldFactors, baseWidths: LiberationSansBoldWidths, baseMapping: LiberationSansBoldMapping, metrics: HelveticaBoldMetrics, }; t["Helvetica-Italic"] = { name: "LiberationSans-Italic", factors: HelveticaItalicFactors, baseWidths: LiberationSansItalicWidths, baseMapping: LiberationSansItalicMapping, metrics: HelveticaItalicMetrics, }; t["Helvetica-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: HelveticaBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, baseMapping: LiberationSansBoldItalicMapping, metrics: HelveticaBoldItalicMetrics, }; }); function getXfaFontName(name) { const fontName = normalizeFontName(name); const fontMap = getXFAFontMap(); return fontMap[fontName]; } function getXfaFontWidths(name) { const info = getXfaFontName(name); if (!info) { return null; } const { baseWidths, baseMapping, factors } = info; let rescaledBaseWidths; if (!factors) { rescaledBaseWidths = baseWidths; } else { rescaledBaseWidths = baseWidths.map((w, i) => w * factors[i]); } let currentCode = -2; let currentArray; // Widths array for composite font is: // CharCode1 [10, 20, 30] ... // which means: // - CharCode1 has a width equal to 10 // - CharCode1+1 has a width equal to 20 // - CharCode1+2 has a width equal to 30 // // The baseMapping array contains a map for glyph index to unicode. // So from baseMapping we'll get sorted unicodes and their positions // (i.e. glyph indices) and then we put widths in an array for the // the consecutive unicodes. const newWidths = []; for (const [unicode, glyphIndex] of baseMapping .map( (charUnicode, index) => [ charUnicode, index, ] /* collect unicode and glyph index */ ) .sort( ([unicode1], [unicode2]) => unicode1 - unicode2 /* order by unicode only */ )) { if (unicode === -1) { continue; } if (unicode === currentCode + 1) { currentArray.push(rescaledBaseWidths[glyphIndex]); currentCode += 1; } else { currentCode = unicode; currentArray = [rescaledBaseWidths[glyphIndex]]; newWidths.push(unicode, currentArray); } } return newWidths; } function getXfaFontDict(name) { const widths = getXfaFontWidths(name); const dict = new Dict(null); dict.set("BaseFont", Name.get(name)); dict.set("Type", Name.get("Font")); dict.set("Subtype", Name.get("CIDFontType2")); dict.set("Encoding", Name.get("Identity-H")); dict.set("CIDToGIDMap", Name.get("Identity")); dict.set("W", widths); dict.set("FirstChar", widths[0]); dict.set( "LastChar", widths[widths.length - 2] + widths[widths.length - 1].length - 1 ); const descriptor = new Dict(null); dict.set("FontDescriptor", descriptor); const systemInfo = new Dict(null); systemInfo.set("Ordering", "Identity"); systemInfo.set("Registry", "Adobe"); systemInfo.set("Supplement", 0); dict.set("CIDSystemInfo", systemInfo); return dict; } export { getXfaFontDict, getXfaFontName };