mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-26 10:08:06 +02:00
XFA - Fix font scale factors (bug 1720888)
- All the scale factors in for the substitution font were wrong because of different glyph positions between Liberation and the other ones: - regenerate all the factors - Text may have polish chars for example and in this case the glyph widths were wrong: - treat substitution font as a composite one - add a map glyphIndex to unicode for Liberation in order to generate width array for cid font
This commit is contained in:
parent
ac5c4b7fd0
commit
4a4591bd2c
17 changed files with 1614 additions and 1248 deletions
|
@ -23,6 +23,7 @@ import {
|
|||
CalibriRegularFactors,
|
||||
CalibriRegularMetrics,
|
||||
} from "./calibri_factors.js";
|
||||
import { Dict, Name } from "./primitives.js";
|
||||
import {
|
||||
HelveticaBoldFactors,
|
||||
HelveticaBoldItalicFactors,
|
||||
|
@ -34,9 +35,13 @@ import {
|
|||
HelveticaRegularMetrics,
|
||||
} from "./helvetica_factors.js";
|
||||
import {
|
||||
LiberationSansBoldItalicMapping,
|
||||
LiberationSansBoldItalicWidths,
|
||||
LiberationSansBoldMapping,
|
||||
LiberationSansBoldWidths,
|
||||
LiberationSansItalicMapping,
|
||||
LiberationSansItalicWidths,
|
||||
LiberationSansRegularMapping,
|
||||
LiberationSansRegularWidths,
|
||||
} from "./liberationsans_widths.js";
|
||||
import {
|
||||
|
@ -67,12 +72,14 @@ const getXFAFontMap = getLookupTableFactory(function (t) {
|
|||
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"] =
|
||||
|
@ -82,6 +89,7 @@ const getXFAFontMap = getLookupTableFactory(function (t) {
|
|||
name: "LiberationSans-Italic",
|
||||
factors: MyriadProItalicFactors,
|
||||
baseWidths: LiberationSansItalicWidths,
|
||||
baseMapping: LiberationSansItalicMapping,
|
||||
metrics: MyriadProItalicMetrics,
|
||||
};
|
||||
t["MyriadPro-BoldIt"] =
|
||||
|
@ -91,6 +99,7 @@ const getXFAFontMap = getLookupTableFactory(function (t) {
|
|||
name: "LiberationSans-BoldItalic",
|
||||
factors: MyriadProBoldItalicFactors,
|
||||
baseWidths: LiberationSansBoldItalicWidths,
|
||||
baseMapping: LiberationSansBoldItalicMapping,
|
||||
metrics: MyriadProBoldItalicMetrics,
|
||||
};
|
||||
t.ArialMT =
|
||||
|
@ -99,89 +108,105 @@ const getXFAFontMap = getLookupTableFactory(function (t) {
|
|||
{
|
||||
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,
|
||||
};
|
||||
});
|
||||
|
@ -198,11 +223,80 @@ function getXfaFontWidths(name) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { baseWidths, factors } = info;
|
||||
const { baseWidths, baseMapping, factors } = info;
|
||||
let rescaledBaseWidths;
|
||||
if (!factors) {
|
||||
return baseWidths;
|
||||
rescaledBaseWidths = baseWidths;
|
||||
} else {
|
||||
rescaledBaseWidths = baseWidths.map((w, i) => w * factors[i]);
|
||||
}
|
||||
return 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;
|
||||
}
|
||||
|
||||
export { getXfaFontName, getXfaFontWidths };
|
||||
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 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue