mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-29 07:37:57 +02:00
XFA - Support non-embedded fonts without a Widths entry
- some pdf use some fonts which are not embedded or they don't have any width array or don't have any css info (e.g. for standard fonts or Arial). - so add widths arrays for Liberation fonts in order to compute the ones for other fonts in using scale factors array.
This commit is contained in:
parent
ff3a5382ee
commit
70bb672dcd
11 changed files with 464 additions and 59 deletions
|
@ -17,6 +17,7 @@ import { $globalData, $toHTML } from "./xfa_object.js";
|
|||
import { Binder } from "./bind.js";
|
||||
import { DataHandler } from "./data.js";
|
||||
import { FontFinder } from "./fonts.js";
|
||||
import { stripQuotes } from "./utils.js";
|
||||
import { warn } from "../../shared/util.js";
|
||||
import { XFAParser } from "./parser.js";
|
||||
|
||||
|
@ -62,6 +63,24 @@ class XFAFactory {
|
|||
|
||||
setFonts(fonts) {
|
||||
this.form[$globalData].fontFinder = new FontFinder(fonts);
|
||||
const missingFonts = [];
|
||||
for (let typeface of this.form[$globalData].usedTypefaces) {
|
||||
typeface = stripQuotes(typeface);
|
||||
const font = this.form[$globalData].fontFinder.find(typeface);
|
||||
if (!font) {
|
||||
missingFonts.push(typeface);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingFonts.length > 0) {
|
||||
return missingFonts;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
appendFonts(fonts) {
|
||||
this.form[$globalData].fontFinder.add(fonts);
|
||||
}
|
||||
|
||||
getPages() {
|
||||
|
|
|
@ -21,53 +21,13 @@ class FontFinder {
|
|||
this.cache = new Map();
|
||||
this.warned = new Set();
|
||||
this.defaultFont = null;
|
||||
this.add(pdfFonts);
|
||||
}
|
||||
|
||||
add(pdfFonts) {
|
||||
for (const pdfFont of pdfFonts) {
|
||||
const cssFontInfo = pdfFont.cssFontInfo;
|
||||
const name = cssFontInfo.fontFamily;
|
||||
let font = this.fonts.get(name);
|
||||
if (!font) {
|
||||
font = Object.create(null);
|
||||
this.fonts.set(name, font);
|
||||
if (!this.defaultFont) {
|
||||
this.defaultFont = font;
|
||||
}
|
||||
}
|
||||
let property = "";
|
||||
if (cssFontInfo.italicAngle !== "0") {
|
||||
if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
||||
property = "bolditalic";
|
||||
} else {
|
||||
property = "italic";
|
||||
}
|
||||
} else if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
||||
property = "bold";
|
||||
}
|
||||
|
||||
if (!property) {
|
||||
if (
|
||||
pdfFont.name.includes("Bold") ||
|
||||
(pdfFont.psName && pdfFont.psName.includes("Bold"))
|
||||
) {
|
||||
property = "bold";
|
||||
}
|
||||
if (
|
||||
pdfFont.name.includes("Italic") ||
|
||||
pdfFont.name.endsWith("It") ||
|
||||
(pdfFont.psName &&
|
||||
(pdfFont.psName.includes("Italic") ||
|
||||
pdfFont.psName.endsWith("It")))
|
||||
) {
|
||||
property += "italic";
|
||||
}
|
||||
}
|
||||
|
||||
if (!property) {
|
||||
property = "regular";
|
||||
}
|
||||
|
||||
font[property] = pdfFont;
|
||||
this.addPdfFont(pdfFont);
|
||||
}
|
||||
|
||||
for (const pdfFont of this.fonts.values()) {
|
||||
if (!pdfFont.regular) {
|
||||
pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic;
|
||||
|
@ -75,6 +35,52 @@ class FontFinder {
|
|||
}
|
||||
}
|
||||
|
||||
addPdfFont(pdfFont) {
|
||||
const cssFontInfo = pdfFont.cssFontInfo;
|
||||
const name = cssFontInfo.fontFamily;
|
||||
let font = this.fonts.get(name);
|
||||
if (!font) {
|
||||
font = Object.create(null);
|
||||
this.fonts.set(name, font);
|
||||
if (!this.defaultFont) {
|
||||
this.defaultFont = font;
|
||||
}
|
||||
}
|
||||
let property = "";
|
||||
if (cssFontInfo.italicAngle !== "0") {
|
||||
if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
||||
property = "bolditalic";
|
||||
} else {
|
||||
property = "italic";
|
||||
}
|
||||
} else if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
||||
property = "bold";
|
||||
}
|
||||
|
||||
if (!property) {
|
||||
if (
|
||||
pdfFont.name.includes("Bold") ||
|
||||
(pdfFont.psName && pdfFont.psName.includes("Bold"))
|
||||
) {
|
||||
property = "bold";
|
||||
}
|
||||
if (
|
||||
pdfFont.name.includes("Italic") ||
|
||||
pdfFont.name.endsWith("It") ||
|
||||
(pdfFont.psName &&
|
||||
(pdfFont.psName.includes("Italic") || pdfFont.psName.endsWith("It")))
|
||||
) {
|
||||
property += "italic";
|
||||
}
|
||||
}
|
||||
|
||||
if (!property) {
|
||||
property = "regular";
|
||||
}
|
||||
|
||||
font[property] = pdfFont;
|
||||
}
|
||||
|
||||
getDefault() {
|
||||
return this.defaultFont;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ class XFAParser extends XMLParserBase {
|
|||
super();
|
||||
this._builder = new Builder();
|
||||
this._stack = [];
|
||||
this._globalData = Object.create(null);
|
||||
this._globalData = {
|
||||
usedTypefaces: new Set(),
|
||||
};
|
||||
this._ids = new Map();
|
||||
this._current = this._builder.buildRoot(this._ids);
|
||||
this._errorCode = XMLParserErrorCode.NoError;
|
||||
|
|
|
@ -2665,6 +2665,11 @@ class Font extends XFAObject {
|
|||
this.fill = null;
|
||||
}
|
||||
|
||||
[$clean](builder) {
|
||||
super[$clean](builder);
|
||||
this[$globalData].usedTypefaces.add(this.typeface);
|
||||
}
|
||||
|
||||
[$toStyle]() {
|
||||
const style = toStyle(this, "fill");
|
||||
const color = style.color;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import {
|
||||
$acceptWhitespace,
|
||||
$childrenToHTML,
|
||||
$clean,
|
||||
$content,
|
||||
$extra,
|
||||
$getChildren,
|
||||
|
@ -144,18 +145,23 @@ function mapStyle(styleStr, fontFinder) {
|
|||
return style;
|
||||
}
|
||||
|
||||
function checkStyle(style) {
|
||||
if (!style) {
|
||||
function checkStyle(node) {
|
||||
if (!node.style) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Remove any non-allowed keys.
|
||||
return style
|
||||
return node.style
|
||||
.trim()
|
||||
.split(/\s*;\s*/)
|
||||
.filter(s => !!s)
|
||||
.map(s => s.split(/\s*:\s*/, 2))
|
||||
.filter(([key]) => VALID_STYLES.has(key))
|
||||
.filter(([key, value]) => {
|
||||
if (key === "font-family") {
|
||||
node[$globalData].usedTypefaces.add(value);
|
||||
}
|
||||
return VALID_STYLES.has(key);
|
||||
})
|
||||
.map(kv => kv.join(":"))
|
||||
.join(";");
|
||||
}
|
||||
|
@ -165,7 +171,12 @@ const NoWhites = new Set(["body", "html"]);
|
|||
class XhtmlObject extends XmlObject {
|
||||
constructor(attributes, name) {
|
||||
super(XHTML_NS_ID, name);
|
||||
this.style = checkStyle(attributes.style);
|
||||
this.style = attributes.style || "";
|
||||
}
|
||||
|
||||
[$clean](builder) {
|
||||
super[$clean](builder);
|
||||
this.style = checkStyle(this);
|
||||
}
|
||||
|
||||
[$acceptWhitespace]() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue