Merge pull request #13591 from calixteman/xfa_default_font
XFA - Match font family correctly
This commit is contained in:
commit
2e6d3d6b00
@ -926,7 +926,9 @@ class PDFDocument {
|
|||||||
if (!(descriptor instanceof Dict)) {
|
if (!(descriptor instanceof Dict)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const fontFamily = descriptor.get("FontFamily");
|
let fontFamily = descriptor.get("FontFamily");
|
||||||
|
// For example, "Wingdings 3" is not a valid font name in the css specs.
|
||||||
|
fontFamily = fontFamily.replace(/[ ]+([0-9])/g, "$1");
|
||||||
const fontWeight = descriptor.get("FontWeight");
|
const fontWeight = descriptor.get("FontWeight");
|
||||||
|
|
||||||
// Angle is expressed in degrees counterclockwise in PDF
|
// Angle is expressed in degrees counterclockwise in PDF
|
||||||
@ -956,6 +958,7 @@ class PDFDocument {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
this.xfaFactory.setFonts(pdfFonts);
|
this.xfaFactory.setFonts(pdfFonts);
|
||||||
}
|
}
|
||||||
|
@ -836,6 +836,7 @@ function createNameTable(name, proto) {
|
|||||||
class Font {
|
class Font {
|
||||||
constructor(name, file, properties) {
|
constructor(name, file, properties) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.psName = null;
|
||||||
this.mimetype = null;
|
this.mimetype = null;
|
||||||
this.disableFontFace = false;
|
this.disableFontFace = false;
|
||||||
|
|
||||||
@ -2730,6 +2731,7 @@ class Font {
|
|||||||
// ... using existing 'name' table as prototype
|
// ... using existing 'name' table as prototype
|
||||||
const namePrototype = readNameTable(tables.name);
|
const namePrototype = readNameTable(tables.name);
|
||||||
tables.name.data = createNameTable(name, namePrototype);
|
tables.name.data = createNameTable(name, namePrototype);
|
||||||
|
this.psName = namePrototype[0][6] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const builder = new OpenTypeFileBuilder(header.version);
|
const builder = new OpenTypeFileBuilder(header.version);
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { $fonts, $toHTML } from "./xfa_object.js";
|
import { $globalData, $toHTML } from "./xfa_object.js";
|
||||||
import { Binder } from "./bind.js";
|
import { Binder } from "./bind.js";
|
||||||
|
import { FontFinder } from "./fonts.js";
|
||||||
import { warn } from "../../shared/util.js";
|
import { warn } from "../../shared/util.js";
|
||||||
import { XFAParser } from "./parser.js";
|
import { XFAParser } from "./parser.js";
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ class XFAFactory {
|
|||||||
try {
|
try {
|
||||||
this.root = new XFAParser().parse(XFAFactory._createDocument(data));
|
this.root = new XFAParser().parse(XFAFactory._createDocument(data));
|
||||||
this.form = new Binder(this.root).bind();
|
this.form = new Binder(this.root).bind();
|
||||||
|
this.form[$globalData].template = this.form;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
warn(`XFA - an error occured during parsing and binding: ${e}`);
|
warn(`XFA - an error occured during parsing and binding: ${e}`);
|
||||||
}
|
}
|
||||||
@ -56,26 +58,7 @@ class XFAFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setFonts(fonts) {
|
setFonts(fonts) {
|
||||||
this.form[$fonts] = Object.create(null);
|
this.form[$globalData].fontFinder = new FontFinder(fonts);
|
||||||
for (const font of fonts) {
|
|
||||||
const cssFontInfo = font.cssFontInfo;
|
|
||||||
const name = cssFontInfo.fontFamily;
|
|
||||||
if (!this.form[$fonts][name]) {
|
|
||||||
this.form[$fonts][name] = Object.create(null);
|
|
||||||
}
|
|
||||||
let property = "regular";
|
|
||||||
if (cssFontInfo.italicAngle !== "0") {
|
|
||||||
if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
|
||||||
property = "bolditalic";
|
|
||||||
} else {
|
|
||||||
property = "italic";
|
|
||||||
}
|
|
||||||
} else if (parseFloat(cssFontInfo.fontWeight) >= 700) {
|
|
||||||
property = "bold";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.form[$fonts][name][property] = font;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPages() {
|
getPages() {
|
||||||
|
157
src/core/xfa/fonts.js
Normal file
157
src/core/xfa/fonts.js
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/* 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 { warn } from "../../shared/util.js";
|
||||||
|
|
||||||
|
class FontFinder {
|
||||||
|
constructor(pdfFonts) {
|
||||||
|
this.fonts = new Map();
|
||||||
|
this.cache = new Map();
|
||||||
|
this.warned = new Set();
|
||||||
|
this.defaultFont = null;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const pdfFont of this.fonts.values()) {
|
||||||
|
if (!pdfFont.regular) {
|
||||||
|
pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefault() {
|
||||||
|
return this.defaultFont;
|
||||||
|
}
|
||||||
|
|
||||||
|
find(fontName, mustWarn = true) {
|
||||||
|
let font = this.fonts.get(fontName) || this.cache.get(fontName);
|
||||||
|
if (font) {
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pattern = /,|-| |bolditalic|bold|italic|regular|it/gi;
|
||||||
|
let name = fontName.replace(pattern, "");
|
||||||
|
font = this.fonts.get(name);
|
||||||
|
if (font) {
|
||||||
|
this.cache.set(fontName, font);
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
name = name.toLowerCase();
|
||||||
|
|
||||||
|
const maybe = [];
|
||||||
|
for (const [family, pdfFont] of this.fonts.entries()) {
|
||||||
|
if (family.replace(pattern, "").toLowerCase().startsWith(name)) {
|
||||||
|
maybe.push(pdfFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe.length === 0) {
|
||||||
|
for (const [, pdfFont] of this.fonts.entries()) {
|
||||||
|
if (
|
||||||
|
pdfFont.regular.name &&
|
||||||
|
pdfFont.regular.name
|
||||||
|
.replace(pattern, "")
|
||||||
|
.toLowerCase()
|
||||||
|
.startsWith(name)
|
||||||
|
) {
|
||||||
|
maybe.push(pdfFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe.length === 0) {
|
||||||
|
name = name.replace(/psmt|mt/gi, "");
|
||||||
|
for (const [family, pdfFont] of this.fonts.entries()) {
|
||||||
|
if (family.replace(pattern, "").toLowerCase().startsWith(name)) {
|
||||||
|
maybe.push(pdfFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe.length === 0) {
|
||||||
|
for (const pdfFont of this.fonts.values()) {
|
||||||
|
if (
|
||||||
|
pdfFont.regular.name &&
|
||||||
|
pdfFont.regular.name
|
||||||
|
.replace(pattern, "")
|
||||||
|
.toLowerCase()
|
||||||
|
.startsWith(name)
|
||||||
|
) {
|
||||||
|
maybe.push(pdfFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe.length >= 1) {
|
||||||
|
if (maybe.length !== 1 && mustWarn) {
|
||||||
|
warn(`XFA - Too many choices to guess the correct font: ${fontName}`);
|
||||||
|
}
|
||||||
|
this.cache.set(fontName, maybe[0]);
|
||||||
|
return maybe[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mustWarn && !this.warned.has(fontName)) {
|
||||||
|
this.warned.add(fontName);
|
||||||
|
warn(`XFA - Cannot find the font: ${fontName}`);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { FontFinder };
|
@ -190,8 +190,8 @@ function setMinMaxDimensions(node, style) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function layoutText(text, xfaFont, fonts, width) {
|
function layoutText(text, xfaFont, fontFinder, width) {
|
||||||
const measure = new TextMeasure(xfaFont, fonts);
|
const measure = new TextMeasure(xfaFont, fontFinder);
|
||||||
if (typeof text === "string") {
|
if (typeof text === "string") {
|
||||||
measure.addString(text);
|
measure.addString(text);
|
||||||
} else {
|
} else {
|
||||||
@ -448,13 +448,20 @@ function fixTextIndent(styles) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFonts(family) {
|
function getFonts(family, fontFinder) {
|
||||||
if (family.startsWith("'") || family.startsWith('"')) {
|
if (family.startsWith("'") || family.startsWith('"')) {
|
||||||
family = family.slice(1, family.length - 1);
|
family = family.slice(1, family.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fonts = [`"${family}"`, `"${family}-PdfJS-XFA"`];
|
const pdfFont = fontFinder.find(family);
|
||||||
return fonts.join(",");
|
if (pdfFont) {
|
||||||
|
const { fontFamily } = pdfFont.regular.cssFontInfo;
|
||||||
|
if (fontFamily !== family) {
|
||||||
|
return `"${family}","${fontFamily}"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `"${family}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
$clean,
|
$clean,
|
||||||
$content,
|
$content,
|
||||||
$finalize,
|
$finalize,
|
||||||
|
$globalData,
|
||||||
$isCDATAXml,
|
$isCDATAXml,
|
||||||
$nsAttributes,
|
$nsAttributes,
|
||||||
$onChild,
|
$onChild,
|
||||||
@ -33,6 +34,7 @@ class XFAParser extends XMLParserBase {
|
|||||||
super();
|
super();
|
||||||
this._builder = new Builder();
|
this._builder = new Builder();
|
||||||
this._stack = [];
|
this._stack = [];
|
||||||
|
this._globalData = Object.create(null);
|
||||||
this._ids = new Map();
|
this._ids = new Map();
|
||||||
this._current = this._builder.buildRoot(this._ids);
|
this._current = this._builder.buildRoot(this._ids);
|
||||||
this._errorCode = XMLParserErrorCode.NoError;
|
this._errorCode = XMLParserErrorCode.NoError;
|
||||||
@ -135,6 +137,7 @@ class XFAParser extends XMLParserBase {
|
|||||||
namespace,
|
namespace,
|
||||||
prefixes,
|
prefixes,
|
||||||
});
|
});
|
||||||
|
node[$globalData] = this._globalData;
|
||||||
|
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
// No children: just push the node into its parent.
|
// No children: just push the node into its parent.
|
||||||
@ -154,6 +157,7 @@ class XFAParser extends XMLParserBase {
|
|||||||
const node = this._current;
|
const node = this._current;
|
||||||
if (node[$isCDATAXml]() && typeof node[$content] === "string") {
|
if (node[$isCDATAXml]() && typeof node[$content] === "string") {
|
||||||
const parser = new XFAParser();
|
const parser = new XFAParser();
|
||||||
|
parser._globalData = this._globalData;
|
||||||
const root = parser.parse(node[$content]);
|
const root = parser.parse(node[$content]);
|
||||||
node[$content] = null;
|
node[$content] = null;
|
||||||
node[$onChild](root);
|
node[$onChild](root);
|
||||||
|
@ -23,7 +23,6 @@ import {
|
|||||||
$extra,
|
$extra,
|
||||||
$finalize,
|
$finalize,
|
||||||
$flushHTML,
|
$flushHTML,
|
||||||
$fonts,
|
|
||||||
$getAvailableSpace,
|
$getAvailableSpace,
|
||||||
$getChildren,
|
$getChildren,
|
||||||
$getContainedChildren,
|
$getContainedChildren,
|
||||||
@ -31,6 +30,7 @@ import {
|
|||||||
$getParent,
|
$getParent,
|
||||||
$getSubformParent,
|
$getSubformParent,
|
||||||
$getTemplateRoot,
|
$getTemplateRoot,
|
||||||
|
$globalData,
|
||||||
$hasItem,
|
$hasItem,
|
||||||
$hasSettableValue,
|
$hasSettableValue,
|
||||||
$ids,
|
$ids,
|
||||||
@ -1441,7 +1441,7 @@ class Draw extends XFAObject {
|
|||||||
|
|
||||||
if ((this.w === "" || this.h === "") && this.value) {
|
if ((this.w === "" || this.h === "") && this.value) {
|
||||||
const maxWidth = this.w === "" ? availableSpace.width : this.w;
|
const maxWidth = this.w === "" ? availableSpace.width : this.w;
|
||||||
const fonts = this[$getTemplateRoot]()[$fonts];
|
const fontFinder = this[$globalData].fontFinder;
|
||||||
let font = this.font;
|
let font = this.font;
|
||||||
if (!font) {
|
if (!font) {
|
||||||
let parent = this[$getParent]();
|
let parent = this[$getParent]();
|
||||||
@ -1464,7 +1464,7 @@ class Draw extends XFAObject {
|
|||||||
const res = layoutText(
|
const res = layoutText(
|
||||||
this.value.exData[$content],
|
this.value.exData[$content],
|
||||||
font,
|
font,
|
||||||
fonts,
|
fontFinder,
|
||||||
maxWidth
|
maxWidth
|
||||||
);
|
);
|
||||||
width = res.width;
|
width = res.width;
|
||||||
@ -1472,7 +1472,7 @@ class Draw extends XFAObject {
|
|||||||
} else {
|
} else {
|
||||||
const text = this.value[$text]();
|
const text = this.value[$text]();
|
||||||
if (text) {
|
if (text) {
|
||||||
const res = layoutText(text, font, fonts, maxWidth);
|
const res = layoutText(text, font, fontFinder, maxWidth);
|
||||||
width = res.width;
|
width = res.width;
|
||||||
height = res.height;
|
height = res.height;
|
||||||
}
|
}
|
||||||
@ -2660,7 +2660,7 @@ class Font extends XFAObject {
|
|||||||
style.fontSize = fontSize;
|
style.fontSize = fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
style.fontFamily = getFonts(this.typeface);
|
style.fontFamily = getFonts(this.typeface, this[$globalData].fontFinder);
|
||||||
|
|
||||||
if (this.underline !== 0) {
|
if (this.underline !== 0) {
|
||||||
style.textDecoration = "underline";
|
style.textDecoration = "underline";
|
||||||
|
@ -17,19 +17,16 @@ const WIDTH_FACTOR = 1.2;
|
|||||||
const HEIGHT_FACTOR = 1.2;
|
const HEIGHT_FACTOR = 1.2;
|
||||||
|
|
||||||
class FontInfo {
|
class FontInfo {
|
||||||
constructor(xfaFont, fonts) {
|
constructor(xfaFont, fontFinder) {
|
||||||
if (!xfaFont) {
|
if (!xfaFont) {
|
||||||
[this.pdfFont, this.xfaFont] = this.defaultFont(fonts);
|
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.xfaFont = xfaFont;
|
this.xfaFont = xfaFont;
|
||||||
let typeface = fonts[xfaFont.typeface];
|
const typeface = fontFinder.find(xfaFont.typeface);
|
||||||
if (!typeface) {
|
if (!typeface) {
|
||||||
typeface = fonts[`${xfaFont.typeface}-PdfJS-XFA`];
|
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
|
||||||
}
|
|
||||||
if (!typeface) {
|
|
||||||
[this.pdfFont, this.xfaFont] = this.defaultFont(fonts);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,18 +44,17 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.pdfFont) {
|
if (!this.pdfFont) {
|
||||||
[this.pdfFont, this.xfaFont] = this.defaultFont(fonts);
|
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultFont(fonts) {
|
defaultFont(fontFinder) {
|
||||||
// TODO: Add a default font based on Liberation.
|
// TODO: Add a default font based on Liberation.
|
||||||
const font =
|
const font =
|
||||||
fonts.Helvetica ||
|
fontFinder.find("Helvetica", false) ||
|
||||||
fonts["Myriad Pro"] ||
|
fontFinder.find("Myriad Pro", false) ||
|
||||||
fonts.Arial ||
|
fontFinder.find("Arial", false) ||
|
||||||
fonts.ArialMT ||
|
fontFinder.getDefault();
|
||||||
Object.values(fonts)[0];
|
|
||||||
if (font && font.regular) {
|
if (font && font.regular) {
|
||||||
const pdfFont = font.regular;
|
const pdfFont = font.regular;
|
||||||
const info = pdfFont.cssFontInfo;
|
const info = pdfFont.cssFontInfo;
|
||||||
@ -82,9 +78,9 @@ class FontInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FontSelector {
|
class FontSelector {
|
||||||
constructor(defaultXfaFont, fonts) {
|
constructor(defaultXfaFont, fontFinder) {
|
||||||
this.fonts = fonts;
|
this.fontFinder = fontFinder;
|
||||||
this.stack = [new FontInfo(defaultXfaFont, fonts)];
|
this.stack = [new FontInfo(defaultXfaFont, fontFinder)];
|
||||||
}
|
}
|
||||||
|
|
||||||
pushFont(xfaFont) {
|
pushFont(xfaFont) {
|
||||||
@ -95,7 +91,7 @@ class FontSelector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fontInfo = new FontInfo(xfaFont, this.fonts);
|
const fontInfo = new FontInfo(xfaFont, this.fontFinder);
|
||||||
if (!fontInfo.pdfFont) {
|
if (!fontInfo.pdfFont) {
|
||||||
fontInfo.pdfFont = lastFont.pdfFont;
|
fontInfo.pdfFont = lastFont.pdfFont;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ const $dump = Symbol();
|
|||||||
const $extra = Symbol("extra");
|
const $extra = Symbol("extra");
|
||||||
const $finalize = Symbol();
|
const $finalize = Symbol();
|
||||||
const $flushHTML = Symbol();
|
const $flushHTML = Symbol();
|
||||||
const $fonts = Symbol();
|
|
||||||
const $getAttributeIt = Symbol();
|
const $getAttributeIt = Symbol();
|
||||||
const $getAvailableSpace = Symbol();
|
const $getAvailableSpace = Symbol();
|
||||||
const $getChildrenByClass = Symbol();
|
const $getChildrenByClass = Symbol();
|
||||||
@ -49,6 +48,7 @@ const $getSubformParent = Symbol();
|
|||||||
const $getParent = Symbol();
|
const $getParent = Symbol();
|
||||||
const $getTemplateRoot = Symbol();
|
const $getTemplateRoot = Symbol();
|
||||||
const $global = Symbol();
|
const $global = Symbol();
|
||||||
|
const $globalData = Symbol();
|
||||||
const $hasItem = Symbol();
|
const $hasItem = Symbol();
|
||||||
const $hasSettableValue = Symbol();
|
const $hasSettableValue = Symbol();
|
||||||
const $ids = Symbol();
|
const $ids = Symbol();
|
||||||
@ -107,6 +107,7 @@ class XFAObject {
|
|||||||
this[_parent] = null;
|
this[_parent] = null;
|
||||||
this[_children] = [];
|
this[_children] = [];
|
||||||
this[$uid] = `${name}${uid++}`;
|
this[$uid] = `${name}${uid++}`;
|
||||||
|
this[$globalData] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[$onChild](child) {
|
[$onChild](child) {
|
||||||
@ -986,7 +987,6 @@ export {
|
|||||||
$extra,
|
$extra,
|
||||||
$finalize,
|
$finalize,
|
||||||
$flushHTML,
|
$flushHTML,
|
||||||
$fonts,
|
|
||||||
$getAttributeIt,
|
$getAttributeIt,
|
||||||
$getAvailableSpace,
|
$getAvailableSpace,
|
||||||
$getChildren,
|
$getChildren,
|
||||||
@ -1001,6 +1001,7 @@ export {
|
|||||||
$getSubformParent,
|
$getSubformParent,
|
||||||
$getTemplateRoot,
|
$getTemplateRoot,
|
||||||
$global,
|
$global,
|
||||||
|
$globalData,
|
||||||
$hasItem,
|
$hasItem,
|
||||||
$hasSettableValue,
|
$hasSettableValue,
|
||||||
$ids,
|
$ids,
|
||||||
|
@ -19,6 +19,7 @@ import {
|
|||||||
$content,
|
$content,
|
||||||
$extra,
|
$extra,
|
||||||
$getChildren,
|
$getChildren,
|
||||||
|
$globalData,
|
||||||
$nodeName,
|
$nodeName,
|
||||||
$onText,
|
$onText,
|
||||||
$pushGlyphs,
|
$pushGlyphs,
|
||||||
@ -91,13 +92,13 @@ const StyleMapping = new Map([
|
|||||||
["margin-right", value => measureToString(getMeasurement(value))],
|
["margin-right", value => measureToString(getMeasurement(value))],
|
||||||
["margin-top", value => measureToString(getMeasurement(value))],
|
["margin-top", value => measureToString(getMeasurement(value))],
|
||||||
["text-indent", value => measureToString(getMeasurement(value))],
|
["text-indent", value => measureToString(getMeasurement(value))],
|
||||||
["font-family", value => getFonts(value)],
|
["font-family", (value, fontFinder) => getFonts(value, fontFinder)],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const spacesRegExp = /\s+/g;
|
const spacesRegExp = /\s+/g;
|
||||||
const crlfRegExp = /[\r\n]+/g;
|
const crlfRegExp = /[\r\n]+/g;
|
||||||
|
|
||||||
function mapStyle(styleStr) {
|
function mapStyle(styleStr, fontFinder) {
|
||||||
const style = Object.create(null);
|
const style = Object.create(null);
|
||||||
if (!styleStr) {
|
if (!styleStr) {
|
||||||
return style;
|
return style;
|
||||||
@ -112,7 +113,7 @@ function mapStyle(styleStr) {
|
|||||||
if (typeof mapping === "string") {
|
if (typeof mapping === "string") {
|
||||||
newValue = mapping;
|
newValue = mapping;
|
||||||
} else {
|
} else {
|
||||||
newValue = mapping(value);
|
newValue = mapping(value, fontFinder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key.endsWith("scale")) {
|
if (key.endsWith("scale")) {
|
||||||
@ -218,7 +219,7 @@ class XhtmlObject extends XmlObject {
|
|||||||
name: this[$nodeName],
|
name: this[$nodeName],
|
||||||
attributes: {
|
attributes: {
|
||||||
href: this.href,
|
href: this.href,
|
||||||
style: mapStyle(this.style),
|
style: mapStyle(this.style, this[$globalData].fontFinder),
|
||||||
},
|
},
|
||||||
children,
|
children,
|
||||||
value: this[$content] || "",
|
value: this[$content] || "",
|
||||||
|
1
test/pdfs/xfa_bug1716980.pdf.link
Normal file
1
test/pdfs/xfa_bug1716980.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://bugzilla.mozilla.org/attachment.cgi?id=9227656
|
@ -938,6 +938,14 @@
|
|||||||
"enableXfa": true,
|
"enableXfa": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "xfa_bug1716980",
|
||||||
|
"file": "pdfs/xfa_bug1716980.pdf",
|
||||||
|
"md5": "3d7598b9548d78f209d013c485162e9a",
|
||||||
|
"link": true,
|
||||||
|
"rounds": 1,
|
||||||
|
"enableXfa": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "xfa_bug1716809",
|
{ "id": "xfa_bug1716809",
|
||||||
"file": "pdfs/xfa_bug1716809.pdf",
|
"file": "pdfs/xfa_bug1716809.pdf",
|
||||||
"md5": "7192f9e27e8b84776d107f57cbe353d5",
|
"md5": "7192f9e27e8b84776d107f57cbe353d5",
|
||||||
|
@ -73,6 +73,7 @@ describe("XFAFactory", function () {
|
|||||||
</xdp:xdp>
|
</xdp:xdp>
|
||||||
`;
|
`;
|
||||||
const factory = new XFAFactory({ "xdp:xdp": xml });
|
const factory = new XFAFactory({ "xdp:xdp": xml });
|
||||||
|
factory.setFonts([]);
|
||||||
|
|
||||||
expect(factory.numberPages).toEqual(2);
|
expect(factory.numberPages).toEqual(2);
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ describe("XFAFactory", function () {
|
|||||||
]);
|
]);
|
||||||
expect(draw.attributes.style).toEqual({
|
expect(draw.attributes.style).toEqual({
|
||||||
color: "#0c1722",
|
color: "#0c1722",
|
||||||
fontFamily: '"FooBar","FooBar-PdfJS-XFA"',
|
fontFamily: '"FooBar"',
|
||||||
fontSize: "6.93px",
|
fontSize: "6.93px",
|
||||||
margin: "1px 4px 2px 3px",
|
margin: "1px 4px 2px 3px",
|
||||||
verticalAlign: "2px",
|
verticalAlign: "2px",
|
||||||
|
Loading…
Reference in New Issue
Block a user