Merge pull request #16420 from calixteman/simplify_subst
Simplify the code to generate font substitution information
This commit is contained in:
commit
107874fcd4
@ -59,10 +59,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Times-Bold",
|
"Times-Bold",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Times-Roman",
|
alias: "Times-Roman",
|
||||||
append: "Bold",
|
|
||||||
},
|
|
||||||
style: BOLD,
|
style: BOLD,
|
||||||
ultimate: "serif",
|
ultimate: "serif",
|
||||||
},
|
},
|
||||||
@ -70,10 +67,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Times-Italic",
|
"Times-Italic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Times-Roman",
|
alias: "Times-Roman",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
style: ITALIC,
|
style: ITALIC,
|
||||||
ultimate: "serif",
|
ultimate: "serif",
|
||||||
},
|
},
|
||||||
@ -81,10 +75,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Times-BoldItalic",
|
"Times-BoldItalic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Times-Roman",
|
alias: "Times-Roman",
|
||||||
append: "Bold Italic",
|
|
||||||
},
|
|
||||||
style: BOLDITALIC,
|
style: BOLDITALIC,
|
||||||
ultimate: "serif",
|
ultimate: "serif",
|
||||||
},
|
},
|
||||||
@ -120,10 +111,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Helvetica-Bold",
|
"Helvetica-Bold",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Helvetica",
|
alias: "Helvetica",
|
||||||
append: "Bold",
|
|
||||||
},
|
|
||||||
path: "LiberationSans-Bold.ttf",
|
path: "LiberationSans-Bold.ttf",
|
||||||
style: BOLD,
|
style: BOLD,
|
||||||
ultimate: "sans-serif",
|
ultimate: "sans-serif",
|
||||||
@ -132,10 +120,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Helvetica-Oblique",
|
"Helvetica-Oblique",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Helvetica",
|
alias: "Helvetica",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
path: "LiberationSans-Italic.ttf",
|
path: "LiberationSans-Italic.ttf",
|
||||||
style: ITALIC,
|
style: ITALIC,
|
||||||
ultimate: "sans-serif",
|
ultimate: "sans-serif",
|
||||||
@ -144,10 +129,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Helvetica-BoldOblique",
|
"Helvetica-BoldOblique",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Helvetica",
|
alias: "Helvetica",
|
||||||
append: "Bold Italic",
|
|
||||||
},
|
|
||||||
path: "LiberationSans-BoldItalic.ttf",
|
path: "LiberationSans-BoldItalic.ttf",
|
||||||
style: BOLDITALIC,
|
style: BOLDITALIC,
|
||||||
ultimate: "sans-serif",
|
ultimate: "sans-serif",
|
||||||
@ -174,10 +156,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Courier-Bold",
|
"Courier-Bold",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Courier",
|
alias: "Courier",
|
||||||
append: "Bold",
|
|
||||||
},
|
|
||||||
style: BOLD,
|
style: BOLD,
|
||||||
ultimate: "monospace",
|
ultimate: "monospace",
|
||||||
},
|
},
|
||||||
@ -185,10 +164,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Courier-Oblique",
|
"Courier-Oblique",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Courier",
|
alias: "Courier",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
style: ITALIC,
|
style: ITALIC,
|
||||||
ultimate: "monospace",
|
ultimate: "monospace",
|
||||||
},
|
},
|
||||||
@ -196,10 +172,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Courier-BoldOblique",
|
"Courier-BoldOblique",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Courier",
|
alias: "Courier",
|
||||||
append: "Bold Italic",
|
|
||||||
},
|
|
||||||
style: BOLDITALIC,
|
style: BOLDITALIC,
|
||||||
ultimate: "monospace",
|
ultimate: "monospace",
|
||||||
},
|
},
|
||||||
@ -207,7 +180,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialBlack",
|
"ArialBlack",
|
||||||
{
|
{
|
||||||
prepend: ["Arial Black"],
|
local: ["Arial Black"],
|
||||||
style: {
|
style: {
|
||||||
style: "normal",
|
style: "normal",
|
||||||
weight: "900",
|
weight: "900",
|
||||||
@ -224,10 +197,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialBlack-Italic",
|
"ArialBlack-Italic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "ArialBlack",
|
alias: "ArialBlack",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
style: {
|
style: {
|
||||||
style: "italic",
|
style: "italic",
|
||||||
weight: "900",
|
weight: "900",
|
||||||
@ -244,7 +214,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialNarrow",
|
"ArialNarrow",
|
||||||
{
|
{
|
||||||
prepend: [
|
local: [
|
||||||
"Arial Narrow",
|
"Arial Narrow",
|
||||||
"Liberation Sans Narrow",
|
"Liberation Sans Narrow",
|
||||||
"Helvetica Condensed",
|
"Helvetica Condensed",
|
||||||
@ -258,10 +228,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialNarrow-Bold",
|
"ArialNarrow-Bold",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "ArialNarrow",
|
alias: "ArialNarrow",
|
||||||
append: "Bold",
|
|
||||||
},
|
|
||||||
style: BOLD,
|
style: BOLD,
|
||||||
fallback: "Helvetica-Bold",
|
fallback: "Helvetica-Bold",
|
||||||
},
|
},
|
||||||
@ -269,10 +236,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialNarrow-Italic",
|
"ArialNarrow-Italic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "ArialNarrow",
|
alias: "ArialNarrow",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
style: ITALIC,
|
style: ITALIC,
|
||||||
fallback: "Helvetica-Oblique",
|
fallback: "Helvetica-Oblique",
|
||||||
},
|
},
|
||||||
@ -280,10 +244,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"ArialNarrow-BoldItalic",
|
"ArialNarrow-BoldItalic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "ArialNarrow",
|
alias: "ArialNarrow",
|
||||||
append: "Bold Italic",
|
|
||||||
},
|
|
||||||
style: BOLDITALIC,
|
style: BOLDITALIC,
|
||||||
fallback: "Helvetica-BoldOblique",
|
fallback: "Helvetica-BoldOblique",
|
||||||
},
|
},
|
||||||
@ -291,7 +252,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Calibri",
|
"Calibri",
|
||||||
{
|
{
|
||||||
prepend: ["Calibri", "Carlito"],
|
local: ["Calibri", "Carlito"],
|
||||||
style: NORMAL,
|
style: NORMAL,
|
||||||
fallback: "Helvetica",
|
fallback: "Helvetica",
|
||||||
},
|
},
|
||||||
@ -299,10 +260,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Calibri-Bold",
|
"Calibri-Bold",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Calibri",
|
alias: "Calibri",
|
||||||
append: "Bold",
|
|
||||||
},
|
|
||||||
style: BOLD,
|
style: BOLD,
|
||||||
fallback: "Helvetica-Bold",
|
fallback: "Helvetica-Bold",
|
||||||
},
|
},
|
||||||
@ -310,10 +268,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Calibri-Italic",
|
"Calibri-Italic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Calibri",
|
alias: "Calibri",
|
||||||
append: "Italic",
|
|
||||||
},
|
|
||||||
style: ITALIC,
|
style: ITALIC,
|
||||||
fallback: "Helvetica-Oblique",
|
fallback: "Helvetica-Oblique",
|
||||||
},
|
},
|
||||||
@ -321,10 +276,7 @@ const substitutionMap = new Map([
|
|||||||
[
|
[
|
||||||
"Calibri-BoldItalic",
|
"Calibri-BoldItalic",
|
||||||
{
|
{
|
||||||
local: {
|
|
||||||
alias: "Calibri",
|
alias: "Calibri",
|
||||||
append: "Bold Italic",
|
|
||||||
},
|
|
||||||
style: BOLDITALIC,
|
style: BOLDITALIC,
|
||||||
fallback: "Helvetica-BoldOblique",
|
fallback: "Helvetica-BoldOblique",
|
||||||
},
|
},
|
||||||
@ -333,39 +285,92 @@ const substitutionMap = new Map([
|
|||||||
|
|
||||||
const fontAliases = new Map([["Arial-Black", "ArialBlack"]]);
|
const fontAliases = new Map([["Arial-Black", "ArialBlack"]]);
|
||||||
|
|
||||||
/**
|
function getStyleToAppend(style) {
|
||||||
* Create the src path to use to load a font (see FontFace).
|
switch (style) {
|
||||||
* @param {Array<String>} prepend A list of font names to search first.
|
case BOLD:
|
||||||
* @param {String} appendToPrepended A String to append to the list of fonts in
|
return "Bold";
|
||||||
* prepend.
|
case ITALIC:
|
||||||
* @param {Array<String>|Object} local A list of font names to search. If an
|
return "Italic";
|
||||||
* Object is passed, then local.alias is the name of an other substition font
|
case BOLDITALIC:
|
||||||
* and local.append is a String to append to the list of fonts in the alias.
|
return "Bold Italic";
|
||||||
* For example if local.alias is "Foo" and local.append is "Bold" then the
|
default:
|
||||||
* list of fonts will be "FooSubst1 Bold", "FooSubst2 Bold", etc.
|
if (style?.weight === "bold") {
|
||||||
* @returns an String with the local fonts.
|
return "Bold";
|
||||||
*/
|
|
||||||
function makeLocal(prepend, appendToPrepended, local) {
|
|
||||||
let append = "";
|
|
||||||
if (!Array.isArray(local)) {
|
|
||||||
// We are getting our list of fonts in the alias and we'll append Bold,
|
|
||||||
// Italic or both.
|
|
||||||
append = ` ${local.append}`;
|
|
||||||
local = substitutionMap.get(local.alias).local;
|
|
||||||
}
|
}
|
||||||
if (appendToPrepended) {
|
if (style?.style === "italic") {
|
||||||
appendToPrepended = ` ${appendToPrepended}`;
|
return "Italic";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
let prependedPaths = "";
|
/**
|
||||||
if (prepend) {
|
* Generate font description.
|
||||||
prependedPaths =
|
* @param {Object} param0, font substitution description.
|
||||||
prepend.map(name => `local(${name}${appendToPrepended})`).join(",") + ",";
|
* @param {Array<String>} src, contains src values (local(...) or url(...)).
|
||||||
|
* @param {String} localFontPath, path to local fonts.
|
||||||
|
* @param {boolean} useFallback, whether to use fallback font.
|
||||||
|
* @param {boolean} usePath, whether to use path to font.
|
||||||
|
* @param {String} append, style (Bold, Italic, ...) to append to font name.
|
||||||
|
* @return {Object} { style, ultimate }.
|
||||||
|
*/
|
||||||
|
function generateFont(
|
||||||
|
{ alias, local, path, fallback, style, ultimate },
|
||||||
|
src,
|
||||||
|
localFontPath,
|
||||||
|
useFallback = true,
|
||||||
|
usePath = true,
|
||||||
|
append = ""
|
||||||
|
) {
|
||||||
|
const result = {
|
||||||
|
style: null,
|
||||||
|
ultimate: null,
|
||||||
|
};
|
||||||
|
if (local) {
|
||||||
|
const extra = append ? ` ${append}` : "";
|
||||||
|
for (const name of local) {
|
||||||
|
src.push(`local(${name}${extra})`);
|
||||||
}
|
}
|
||||||
return (
|
}
|
||||||
prependedPaths + local.map(name => `local(${name}${append})`).join(",")
|
if (alias) {
|
||||||
|
const substitution = substitutionMap.get(alias);
|
||||||
|
const aliasAppend = append || getStyleToAppend(style);
|
||||||
|
Object.assign(
|
||||||
|
result,
|
||||||
|
generateFont(
|
||||||
|
substitution,
|
||||||
|
src,
|
||||||
|
localFontPath,
|
||||||
|
/* useFallback = */ useFallback && !fallback,
|
||||||
|
/* usePath = */ usePath && !path,
|
||||||
|
aliasAppend
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (style) {
|
||||||
|
result.style = style;
|
||||||
|
}
|
||||||
|
if (ultimate) {
|
||||||
|
result.ultimate = ultimate;
|
||||||
|
}
|
||||||
|
if (useFallback && fallback) {
|
||||||
|
const fallbackInfo = substitutionMap.get(fallback);
|
||||||
|
const { ultimate: fallbackUltimate } = generateFont(
|
||||||
|
fallbackInfo,
|
||||||
|
src,
|
||||||
|
localFontPath,
|
||||||
|
useFallback,
|
||||||
|
/* usePath = */ usePath && !path,
|
||||||
|
append
|
||||||
|
);
|
||||||
|
result.ultimate ||= fallbackUltimate;
|
||||||
|
}
|
||||||
|
if (usePath && path && localFontPath) {
|
||||||
|
src.push(`url(${localFontPath}${path})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a font substitution for a given font.
|
* Get a font substitution for a given font.
|
||||||
@ -453,50 +458,23 @@ function getFontSubstitution(
|
|||||||
return substitutionInfo;
|
return substitutionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (substitution.alias) {
|
const src = [];
|
||||||
// If we've an alias, use the substitution for the alias.
|
|
||||||
// For example, ArialBlack-Bold is an alias for ArialBlack because the bold
|
|
||||||
// version of Arial Black is not available.
|
|
||||||
substitution = substitutionMap.get(substitution.alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { fallback, style } = substitution;
|
|
||||||
|
|
||||||
// Prepend the fonts to test before the fallback font.
|
|
||||||
let prepend = substitution.prepend;
|
|
||||||
let appendToPrepended = "";
|
|
||||||
|
|
||||||
if (fallback) {
|
|
||||||
// We've a fallback font: this one is a standard font we want to use in case
|
|
||||||
// nothing has been found from the prepend list.
|
|
||||||
if (substitution.local) {
|
|
||||||
prepend ||= substitutionMap.get(substitution.local.alias).prepend;
|
|
||||||
appendToPrepended = substitution.local.append;
|
|
||||||
}
|
|
||||||
substitution = substitutionMap.get(fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { local, path, ultimate } = substitution;
|
|
||||||
let src = makeLocal(prepend, appendToPrepended, local);
|
|
||||||
if (path && localFontPath !== null) {
|
|
||||||
// PDF.js embeds some fonts we can use.
|
|
||||||
src += `,url(${localFontPath}${path})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maybe the OS will have the exact font we want so just prepend it to the
|
// Maybe the OS will have the exact font we want so just prepend it to the
|
||||||
// list.
|
// list.
|
||||||
if (mustAddBaseFont && validateFontName(baseFontName)) {
|
if (mustAddBaseFont && validateFontName(baseFontName)) {
|
||||||
src = `local(${baseFontName}),${src}`;
|
src.push(`local(${baseFontName})`);
|
||||||
}
|
}
|
||||||
|
const { style, ultimate } = generateFont(substitution, src, localFontPath);
|
||||||
|
|
||||||
substitutionInfo = {
|
substitutionInfo = {
|
||||||
css: `${loadedName},${ultimate}`,
|
css: `${loadedName},${ultimate}`,
|
||||||
guessFallback: false,
|
guessFallback: false,
|
||||||
loadedName,
|
loadedName,
|
||||||
src,
|
src: src.join(","),
|
||||||
style,
|
style,
|
||||||
};
|
};
|
||||||
systemFontCache.set(key, substitutionInfo);
|
systemFontCache.set(key, substitutionInfo);
|
||||||
|
|
||||||
return substitutionInfo;
|
return substitutionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user