Skip to content

Commit

Permalink
Merge pull request #12726 from brendandahl/standard-fonts
Browse files Browse the repository at this point in the history
[api-minor] Include and use the 14 standard font files.
  • Loading branch information
Snuffleupagus committed Jun 8, 2021
2 parents 8b4acb4 + 4c1dd47 commit e7dc822
Show file tree
Hide file tree
Showing 36 changed files with 460 additions and 77 deletions.
5 changes: 5 additions & 0 deletions examples/node/pdf2png/pdf2png.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;

// Where the standard fonts are located.
const STANDARD_FONT_DATA_URL =
"../../../node_modules/pdfjs-dist/standard_fonts/";

// Loading file from file system into typed array.
const pdfPath =
process.argv[2] || "../../../web/compressed.tracemonkey-pldi-09.pdf";
Expand All @@ -64,6 +68,7 @@ const loadingTask = pdfjsLib.getDocument({
data,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
standardFontDataUrl: STANDARD_FONT_DATA_URL,
});
loadingTask.promise
.then(function (pdfDocument) {
Expand Down
Binary file added external/standard_fonts/FoxitDingbats.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitFixed.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitFixedBold.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitFixedBoldItalic.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitFixedItalic.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSans.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSansBold.pfb
Binary file not shown.
Binary file not shown.
Binary file added external/standard_fonts/FoxitSansItalic.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSerif.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSerifBold.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSerifBoldItalic.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSerifItalic.pfb
Binary file not shown.
Binary file added external/standard_fonts/FoxitSymbol.pfb
Binary file not shown.
27 changes: 27 additions & 0 deletions external/standard_fonts/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2014 PDFium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11 changes: 11 additions & 0 deletions external/standard_fonts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The files in this directory were extracted from Pdfium

Original copyright notice:

```
Copyright 2014 PDFium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
```
44 changes: 43 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,14 @@ function buildGeneric(defines, dir) {
base: "external/bcmaps",
})
.pipe(gulp.dest(dir + "web/cmaps")),
gulp
.src(
["external/standard_fonts/*.pfb", "external/standard_fonts/LICENSE"],
{
base: "external/standard_fonts",
}
)
.pipe(gulp.dest(dir + "web/standard_fonts")),
preprocessHTML("web/viewer.html", defines).pipe(gulp.dest(dir + "web")),
preprocessCSS("web/viewer.css", "generic", defines, true)
.pipe(postcss([calc(), autoprefixer(AUTOPREFIXER_CONFIG)]))
Expand Down Expand Up @@ -980,6 +988,14 @@ function buildMinified(defines, dir) {
base: "external/bcmaps",
})
.pipe(gulp.dest(dir + "web/cmaps")),
gulp
.src(
["external/standard_fonts/*.pfb", "external/standard_fonts/LICENSE"],
{
base: "external/standard_fonts",
}
)
.pipe(gulp.dest(dir + "web/standard_fonts")),

preprocessHTML("web/viewer.html", defines).pipe(gulp.dest(dir + "web")),
preprocessCSS("web/viewer.css", "minified", defines, true)
Expand Down Expand Up @@ -1214,7 +1230,17 @@ gulp.task(
base: "external/bcmaps",
})
.pipe(gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/cmaps")),

gulp
.src(
[
"external/standard_fonts/*.pfb",
"external/standard_fonts/LICENSE",
],
{
base: "external/standard_fonts",
}
)
.pipe(gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")),
preprocessHTML("web/viewer.html", defines).pipe(
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web")
),
Expand Down Expand Up @@ -1305,6 +1331,17 @@ gulp.task(
base: "external/bcmaps",
})
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/cmaps")),
gulp
.src(
[
"external/standard_fonts/*.pfb",
"external/standard_fonts/LICENSE",
],
{
base: "external/standard_fonts",
}
)
.pipe(gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")),

preprocessHTML("web/viewer.html", defines).pipe(
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
Expand Down Expand Up @@ -2051,6 +2088,11 @@ gulp.task(
gulp
.src(GENERIC_DIR + "web/cmaps/**/*", { base: GENERIC_DIR + "web" })
.pipe(gulp.dest(DIST_DIR)),
gulp
.src(GENERIC_DIR + "web/standard_fonts/**/*", {
base: GENERIC_DIR + "web",
})
.pipe(gulp.dest(DIST_DIR)),
gulp
.src([
GENERIC_DIR + "build/{pdf,pdf.worker,pdf.sandbox}.js",
Expand Down
5 changes: 4 additions & 1 deletion src/core/cff_font.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
64 changes: 62 additions & 2 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ import {
} from "./unicode.js";
import {
getSerifFonts,
getStandardFontName,
getStdFontMap,
getStdFontNameToFileMap,
getSymbolsFonts,
} from "./standard_fonts.js";
import { getTilingPatternIR, Pattern } from "./pattern.js";
Expand All @@ -77,14 +79,14 @@ 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";
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";

Expand All @@ -94,6 +96,8 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
ignoreErrors: false,
isEvalSupported: true,
fontExtraProperties: false,
standardFontDataUrl: null,
useSystemFonts: true,
});

const PatternType = {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -3725,6 +3766,7 @@ class PartialEvaluator {
properties = {
type,
name: baseFontName,
loadedName: baseDict.loadedName,
widths: metrics.widths,
defaultWidth: metrics.defaultWidth,
flags,
Expand All @@ -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) {
Expand All @@ -3749,7 +3798,7 @@ class PartialEvaluator {
newProperties
);
}
return new Font(baseFontName, null, newProperties);
return new Font(baseFontName, file, newProperties);
}
);
}
Expand Down Expand Up @@ -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");
Expand All @@ -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 = {
Expand All @@ -3822,6 +3880,8 @@ class PartialEvaluator {
length1,
length2,
length3,
isStandardFont,
isInternalFont,
loadedName: baseDict.loadedName,
composite,
fixedPitch: false,
Expand Down
10 changes: 7 additions & 3 deletions src/core/fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
FontFlags,
getFontType,
MacStandardGlyphOrdering,
normalizeFontName,
recoverGlyphName,
SEAC_ANALYSIS_ENABLED,
} from "./fonts_utils.js";
Expand Down Expand Up @@ -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.
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 20 additions & 2 deletions src/core/fonts_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit e7dc822

Please sign in to comment.