1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-26 10:08:06 +02:00

Merge pull request #12726 from brendandahl/standard-fonts

[api-minor] Include and use the 14 standard font files.
This commit is contained in:
Jonas Jenwald 2021-06-08 10:09:40 +02:00 committed by GitHub
commit e7dc822e74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 463 additions and 80 deletions

View file

@ -74,7 +74,10 @@ class CFFFont {
return charCodeToGlyphId;
}
const encoding = cff.encoding ? cff.encoding.encoding : null;
let encoding = cff.encoding ? cff.encoding.encoding : null;
if (properties.isInternalFont) {
encoding = properties.defaultEncoding;
}
charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);
return charCodeToGlyphId;
}

View file

@ -64,7 +64,9 @@ import {
} from "./unicode.js";
import {
getSerifFonts,
getStandardFontName,
getStdFontMap,
getStdFontNameToFileMap,
getSymbolsFonts,
} from "./standard_fonts.js";
import { getTilingPatternIR, Pattern } from "./pattern.js";
@ -77,6 +79,7 @@ import {
LocalImageCache,
LocalTilingPatternCache,
} from "./image_utils.js";
import { NullStream, Stream } from "./stream.js";
import { bidi } from "./bidi.js";
import { ColorSpace } from "./colorspace.js";
import { DecodeStream } from "./decode_stream.js";
@ -84,7 +87,6 @@ import { getGlyphsUnicode } from "./glyphlist.js";
import { getLookupTableFactory } from "./core_utils.js";
import { getMetrics } from "./metrics.js";
import { MurmurHash3_64 } from "./murmurhash3.js";
import { NullStream } from "./stream.js";
import { OperatorList } from "./operator_list.js";
import { PDFImage } from "./image.js";
@ -94,6 +96,8 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
ignoreErrors: false,
isEvalSupported: true,
fontExtraProperties: false,
standardFontDataUrl: null,
useSystemFonts: true,
});
const PatternType = {
@ -381,6 +385,43 @@ class PartialEvaluator {
return data;
}
async fetchStandardFontData(name) {
// The symbol fonts are not consistent across platforms, always load the
// font data for them.
if (
this.options.useSystemFonts &&
name !== "Symbol" &&
name !== "ZapfDingbats"
) {
return null;
}
const standardFontNameToFileName = getStdFontNameToFileMap();
const filename = standardFontNameToFileName[name];
if (this.options.standardFontDataUrl !== null) {
const url = `${this.options.standardFontDataUrl}${filename}.pfb`;
const response = await fetch(url);
if (!response.ok) {
warn(
`fetchStandardFontData failed to fetch file "${url}" with "${response.statusText}".`
);
return null;
}
return new Stream(await response.arrayBuffer());
}
// Get the data on the main thread instead.
try {
const data = await this.handler.sendWithPromise("FetchStandardFontData", {
filename,
});
return new Stream(data);
} catch (e) {
warn(
`fetchStandardFontData failed to fetch file "${filename}" with "${e}".`
);
}
return null;
}
async buildFormXObject(
resources,
xobj,
@ -3725,6 +3766,7 @@ class PartialEvaluator {
properties = {
type,
name: baseFontName,
loadedName: baseDict.loadedName,
widths: metrics.widths,
defaultWidth: metrics.defaultWidth,
flags,
@ -3734,6 +3776,13 @@ class PartialEvaluator {
isType3Font,
};
const widths = dict.get("Widths");
const standardFontName = getStandardFontName(baseFontName);
let file = null;
if (standardFontName) {
properties.isStandardFont = true;
file = await this.fetchStandardFontData(standardFontName);
properties.isInternalFont = !!file;
}
return this.extractDataStructures(dict, dict, properties).then(
newProperties => {
if (widths) {
@ -3749,7 +3798,7 @@ class PartialEvaluator {
newProperties
);
}
return new Font(baseFontName, null, newProperties);
return new Font(baseFontName, file, newProperties);
}
);
}
@ -3802,6 +3851,8 @@ class PartialEvaluator {
warn(`translateFont - fetching "${fontName.name}" font file: "${ex}".`);
fontFile = new NullStream();
}
let isStandardFont = false;
let isInternalFont = false;
if (fontFile) {
if (fontFile.dict) {
const subtypeEntry = fontFile.dict.get("Subtype");
@ -3812,6 +3863,13 @@ class PartialEvaluator {
length2 = fontFile.dict.get("Length2");
length3 = fontFile.dict.get("Length3");
}
} else if (type === "Type1") {
const standardFontName = getStandardFontName(fontName.name);
if (standardFontName) {
isStandardFont = true;
fontFile = await this.fetchStandardFontData(standardFontName);
isInternalFont = !!fontFile;
}
}
properties = {
@ -3822,6 +3880,8 @@ class PartialEvaluator {
length1,
length2,
length3,
isStandardFont,
isInternalFont,
loadedName: baseDict.loadedName,
composite,
fixedPitch: false,

View file

@ -30,6 +30,7 @@ import {
FontFlags,
getFontType,
MacStandardGlyphOrdering,
normalizeFontName,
recoverGlyphName,
SEAC_ANALYSIS_ENABLED,
} from "./fonts_utils.js";
@ -130,6 +131,9 @@ function adjustWidths(properties) {
}
function adjustToUnicode(properties, builtInEncoding) {
if (properties.isInternalFont) {
return;
}
if (properties.hasIncludedToUnicodeMap) {
return; // The font dictionary has a `ToUnicode` entry.
}
@ -932,7 +936,7 @@ class Font {
}
this.data = data;
this.fontType = getFontType(type, subtype);
this.fontType = getFontType(type, subtype, properties.isStandardFont);
// Transfer some properties again that could change during font conversion
this.fontMatrix = properties.fontMatrix;
@ -971,7 +975,7 @@ class Font {
const name = this.name;
const type = this.type;
const subtype = this.subtype;
let fontName = name.replace(/[,_]/g, "-").replace(/\s/g, "");
let fontName = normalizeFontName(name);
const stdFontMap = getStdFontMap(),
nonStdFontMap = getNonStdFontMap();
const isStandardFont = !!stdFontMap[fontName];
@ -1090,7 +1094,7 @@ class Font {
this.toFontChar = map;
}
this.loadedName = fontName.split("-")[0];
this.fontType = getFontType(type, subtype);
this.fontType = getFontType(type, subtype, properties.isStandardFont);
}
checkAndRepair(name, font, properties) {

View file

@ -78,9 +78,12 @@ const MacStandardGlyphOrdering = [
"threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla",
"scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat"];
function getFontType(type, subtype) {
function getFontType(type, subtype, isStandardFont = false) {
switch (type) {
case "Type1":
if (isStandardFont) {
return FontType.TYPE1STANDARD;
}
return subtype === "Type1C" ? FontType.TYPE1C : FontType.TYPE1;
case "CIDFontType0":
return subtype === "CIDFontType0C"
@ -135,7 +138,17 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
let glyphId, charCode, baseEncoding;
const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
if (properties.baseEncodingName) {
if (properties.isInternalFont) {
baseEncoding = builtInEncoding;
for (charCode = 0; charCode < baseEncoding.length; charCode++) {
glyphId = glyphNames.indexOf(baseEncoding[charCode]);
if (glyphId >= 0) {
charCodeToGlyphId[charCode] = glyphId;
} else {
charCodeToGlyphId[charCode] = 0; // notdef
}
}
} else if (properties.baseEncodingName) {
// If a valid base encoding name was used, the mapping is initialized with
// that.
baseEncoding = getEncoding(properties.baseEncodingName);
@ -193,10 +206,15 @@ function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
return charCodeToGlyphId;
}
function normalizeFontName(name) {
return name.replace(/[,_]/g, "-").replace(/\s/g, "");
}
export {
FontFlags,
getFontType,
MacStandardGlyphOrdering,
normalizeFontName,
recoverGlyphName,
SEAC_ANALYSIS_ENABLED,
type1FontGlyphMapping,

View file

@ -14,12 +14,30 @@
*/
import { getLookupTableFactory } from "./core_utils.js";
import { normalizeFontName } from "./fonts_utils.js";
/**
* Hold a map of decoded fonts and of the standard fourteen Type1
* fonts and their acronyms.
*/
const getStdFontMap = getLookupTableFactory(function (t) {
// The standard 14 fonts:
t["Times-Roman"] = "Times-Roman";
t.Helvetica = "Helvetica";
t.Courier = "Courier";
t.Symbol = "Symbol";
t["Times-Bold"] = "Times-Bold";
t["Helvetica-Bold"] = "Helvetica-Bold";
t["Courier-Bold"] = "Courier-Bold";
t.ZapfDingbats = "ZapfDingbats";
t["Times-Italic"] = "Times-Italic";
t["Helvetica-Oblique"] = "Helvetica-Oblique";
t["Courier-Oblique"] = "Courier-Oblique";
t["Times-BoldItalic"] = "Times-BoldItalic";
t["Helvetica-BoldOblique"] = "Helvetica-BoldOblique";
t["Courier-BoldOblique"] = "Courier-BoldOblique";
// Extra mappings
t.ArialNarrow = "Helvetica";
t["ArialNarrow-Bold"] = "Helvetica-Bold";
t["ArialNarrow-BoldItalic"] = "Helvetica-BoldOblique";
@ -40,7 +58,6 @@ const getStdFontMap = getLookupTableFactory(function (t) {
t["Arial-BoldMT"] = "Helvetica-Bold";
t["Arial-ItalicMT"] = "Helvetica-Oblique";
t.ArialMT = "Helvetica";
t["Courier-Bold"] = "Courier-Bold";
t["Courier-BoldItalic"] = "Courier-BoldOblique";
t["Courier-Italic"] = "Courier-Oblique";
t.CourierNew = "Courier";
@ -51,12 +68,8 @@ const getStdFontMap = getLookupTableFactory(function (t) {
t["CourierNewPS-BoldMT"] = "Courier-Bold";
t["CourierNewPS-ItalicMT"] = "Courier-Oblique";
t.CourierNewPSMT = "Courier";
t.Helvetica = "Helvetica";
t["Helvetica-Bold"] = "Helvetica-Bold";
t["Helvetica-BoldItalic"] = "Helvetica-BoldOblique";
t["Helvetica-BoldOblique"] = "Helvetica-BoldOblique";
t["Helvetica-Italic"] = "Helvetica-Oblique";
t["Helvetica-Oblique"] = "Helvetica-Oblique";
t["Symbol-Bold"] = "Symbol";
t["Symbol-BoldItalic"] = "Symbol";
t["Symbol-Italic"] = "Symbol";
@ -77,6 +90,23 @@ const getStdFontMap = getLookupTableFactory(function (t) {
t["TimesNewRomanPSMT-Italic"] = "Times-Italic";
});
const getStdFontNameToFileMap = getLookupTableFactory(function (t) {
t.Courier = "FoxitFixed";
t["Courier-Bold"] = "FoxitFixedBold";
t["Courier-BoldOblique"] = "FoxitFixedBoldItalic";
t["Courier-Oblique"] = "FoxitFixedItalic";
t.Helvetica = "FoxitSans";
t["Helvetica-Bold"] = "FoxitSansBold";
t["Helvetica-BoldOblique"] = "FoxitSansBoldItalic";
t["Helvetica-Oblique"] = "FoxitSansItalic";
t["Times-Roman"] = "FoxitSerif";
t["Times-Bold"] = "FoxitSerifBold";
t["Times-BoldItalic"] = "FoxitSerifBoldItalic";
t["Times-Italic"] = "FoxitSerifItalic";
t.Symbol = "FoxitSymbol";
t.ZapfDingbats = "FoxitDingbats";
});
/**
* Holds the map of the non-standard fonts that might be included as
* a standard fonts without glyph data.
@ -763,11 +793,19 @@ const getSupplementalGlyphMapForCalibri = getLookupTableFactory(function (t) {
t[1086] = 45;
});
function getStandardFontName(name) {
const fontName = normalizeFontName(name);
const stdFontMap = getStdFontMap();
return stdFontMap[fontName];
}
export {
getGlyphMapForStandardFonts,
getNonStdFontMap,
getSerifFonts,
getStandardFontName,
getStdFontMap,
getStdFontNameToFileMap,
getSupplementalGlyphMapForArialBlack,
getSupplementalGlyphMapForCalibri,
getSymbolsFonts,

View file

@ -411,6 +411,8 @@ class WorkerMessageHandler {
ignoreErrors: data.ignoreErrors,
isEvalSupported: data.isEvalSupported,
fontExtraProperties: data.fontExtraProperties,
useSystemFonts: data.useSystemFonts,
standardFontDataUrl: data.standardFontDataUrl,
};
getPdfManager(data, evaluatorOptions, data.enableXfa)