Skip to content

Commit

Permalink
Add the font Linux Libertine as a possible substitution for Times New…
Browse files Browse the repository at this point in the history
… Roman

and try to load the font family (guessed from the font name) before trying
the local substitution.
The local(...) command expects to have a real font name and not a predefined
substitution it's why we try the font family.
  • Loading branch information
calixteman committed Jan 16, 2024
1 parent 51413be commit 10389c5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 14 deletions.
50 changes: 48 additions & 2 deletions src/core/font_substitutions.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const substitutionMap = new Map([
"Thorndale",
"TeX Gyre Termes",
"FreeSerif",
"Linux Libertine O",
"Libertinus Serif",
"DejaVu Serif",
"Bitstream Vera Serif",
"Ubuntu",
Expand Down Expand Up @@ -148,6 +150,8 @@ const substitutionMap = new Map([
"Cumberland",
"TeX Gyre Cursor",
"FreeMono",
"Linux Libertine Mono O",
"Libertinus Mono",
],
style: NORMAL,
ultimate: "monospace",
Expand Down Expand Up @@ -323,6 +327,48 @@ function getStyleToAppend(style) {
return "";
}

function getFamilyName(str) {
// See https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/14d466b30a8ab4a9d789977ed94f2c30e7209267/src/fcname.c#L137.
const keywords = new Set([
"thin",
"extralight",
"ultralight",
"demilight",
"semilight",
"light",
"book",
"regular",
"normal",
"medium",
"demibold",
"semibold",
"bold",
"extrabold",
"ultrabold",
"black",
"heavy",
"extrablack",
"ultrablack",
"roman",
"italic",
"oblique",
"ultracondensed",
"extracondensed",
"condensed",
"semicondensed",
"normal",
"semiexpanded",
"expanded",
"extraexpanded",
"ultraexpanded",
"bolditalic",
]);
return str
.split(/[- ,+]+/g)
.filter(tok => !keywords.has(tok.toLowerCase()))
.join(" ");
}

/**
* Generate font description.
* @param {Object} param0, font substitution description.
Expand Down Expand Up @@ -470,7 +516,7 @@ function getFontSubstitution(
(italic && ITALIC) ||
NORMAL;
substitutionInfo = {
css: loadedName,
css: `"${getFamilyName(baseFontName)}",${loadedName}`,
guessFallback: true,
loadedName,
baseFontName,
Expand All @@ -492,7 +538,7 @@ function getFontSubstitution(
const fallback = guessFallback ? "" : `,${ultimate}`;

substitutionInfo = {
css: `${loadedName}${fallback}`,
css: `"${getFamilyName(baseFontName)}",${loadedName}${fallback}`,
guessFallback,
loadedName,
baseFontName,
Expand Down
32 changes: 20 additions & 12 deletions test/unit/font_substitutions_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+)$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+)$/);
});

it("should substitute an unknown bold font", () => {
Expand All @@ -63,7 +63,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+)$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+)$/);
});

it("should substitute an unknown italic font", () => {
Expand All @@ -86,7 +86,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+)$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+)$/);
});

it("should substitute an unknown bold italic font", () => {
Expand All @@ -109,7 +109,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+)$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+)$/);
});

it("should substitute an unknown font but with a standard font", () => {
Expand Down Expand Up @@ -140,7 +140,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+),sans-serif$/);
});

it("should substitute an unknown font but with a standard italic font", () => {
Expand Down Expand Up @@ -173,7 +173,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+),sans-serif$/);
});

it("should substitute an unknown font but with a standard bold font", () => {
Expand Down Expand Up @@ -205,7 +205,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+),sans-serif$/);
});

it("should substitute an unknown font but with a standard bold italic font", () => {
Expand Down Expand Up @@ -240,7 +240,7 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(/^"Foo",g_d(\d+)_sf(\d+),sans-serif$/);
});

it("should substitute Calibri", () => {
Expand Down Expand Up @@ -271,7 +271,9 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(
/^"Calibri",g_d(\d+)_sf(\d+),sans-serif$/
);
});

it("should substitute Calibri-Bold", () => {
Expand Down Expand Up @@ -304,7 +306,9 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(
/^"Calibri",g_d(\d+)_sf(\d+),sans-serif$/
);
});

it("should substitute Arial Black", () => {
Expand Down Expand Up @@ -337,7 +341,9 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(
/^"ArialBlack",g_d(\d+)_sf(\d+),sans-serif$/
);
});

it("should substitute Arial Black Bold", () => {
Expand Down Expand Up @@ -370,6 +376,8 @@ describe("getFontSubstitution", function () {
},
})
);
expect(fontSubstitution.css).toMatch(/^g_d(\d+)_sf(\d+),sans-serif$/);
expect(fontSubstitution.css).toMatch(
/^"ArialBlack",g_d(\d+)_sf(\d+),sans-serif$/
);
});
});

0 comments on commit 10389c5

Please sign in to comment.