vcl/source/font/PhysicalFontCollection.cxx | 50 +++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-)
New commits: commit 02e0a8ee3c287e47d5931c37d94fa531f5cf6fbb Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Jul 31 18:49:47 2025 +0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Aug 1 09:16:45 2025 +0200 Use known compatible substitutions for Bundes* fonts As recommended on https://styleguide.bundesregierung.de/sg-de/basiselemente/schriften. Because of https://github.com/google/fonts/issues/9720, we have to use MS fonts as first choice; and use another attempt on the first result, when it's also absent on system, to get our bundled fonts. Change-Id: I2ac0731be468a8d12c4bb8ef61726bae341b3b07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188669 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/vcl/source/font/PhysicalFontCollection.cxx b/vcl/source/font/PhysicalFontCollection.cxx index 9ce93fea5b1f..e22978481ff6 100644 --- a/vcl/source/font/PhysicalFontCollection.cxx +++ b/vcl/source/font/PhysicalFontCollection.cxx @@ -930,23 +930,32 @@ std::unique_ptr<PhysicalFontFaceCollection> PhysicalFontCollection::GetFontFaceC // These are the metric-compatible replacement fonts that are bundled with // LibreOffice, we prefer them over generic substitutions that might be // provided by the system. -const std::vector<std::pair<OUString, OUString>> aMetricCompatibleMap = +constexpr std::pair<std::u16string_view, std::u16string_view> aMetricCompatibleMap[] = { - { "Times New Roman", "Liberation Serif" }, - { "Arial", "Liberation Sans" }, - { "Arial Narrow", "Liberation Sans Narrow" }, - { "Courier New", "Liberation Mono" }, - { "Cambria", "Caladea" }, - { "Calibri", "Carlito" }, + { u"Times New Roman", u"Liberation Serif" }, + { u"Arial", u"Liberation Sans" }, + { u"Arial Narrow", u"Liberation Sans Narrow" }, + { u"Courier New", u"Liberation Mono" }, + { u"Cambria", u"Caladea" }, + { u"Calibri", u"Carlito" }, + + // Official replacements for Bundes* fonts. https://github.com/google/fonts/issues/9720 + // prevents from using Carlito as direct metric-compatible replacement. + { u"BundesSans", u"Calibri" }, + { u"BundesSans Office", u"Calibri" }, + { u"BundesSans Regular", u"Calibri" }, + { u"BundesSerif", u"Cambria" }, + { u"BundesSerif Office", u"Cambria" }, + { u"BundesSerif Regular", u"Cambria" }, }; -static bool FindMetricCompatibleFont(FontSelectPattern& rFontSelData) +static bool FindMetricCompatibleFont_impl(FontSelectPattern& rFontSelData) { - for (const auto& aSub : aMetricCompatibleMap) + for (const auto& [font, metric_compatible_font] : aMetricCompatibleMap) { - if (rFontSelData.maSearchName == GetEnglishSearchFontName(aSub.first)) + if (rFontSelData.maSearchName == GetEnglishSearchFontName(font)) { - rFontSelData.maSearchName = aSub.second; + rFontSelData.maSearchName = GetEnglishSearchFontName(metric_compatible_font); return true; } } @@ -972,6 +981,19 @@ PhysicalFontFamily* PhysicalFontCollection::FindFontFamily(FontSelectPattern& rF return pFont; } + auto FindMetricCompatibleFont = [this](FontSelectPattern& rFontSelData) -> PhysicalFontFamily* + { + while (FindMetricCompatibleFont_impl(rFontSelData)) + { + if (auto* pFont = ImplFindFontFamilyBySearchName(rFontSelData.maSearchName)) + return pFont; + // Try again, with the updated maSearchName: maybe there is a metric-compatible font + // for metric-compatible font? E.g., Bundes* family of fonts has preferred substitute + // MS fonts; and those have their substitutions. + } + return nullptr; + }; + bool bMultiToken = false; sal_Int32 nTokenPos = 0; OUString& aSearchName = rFSD.maSearchName; // TODO: get rid of reference @@ -1030,6 +1052,9 @@ PhysicalFontFamily* PhysicalFontCollection::FindFontFamily(FontSelectPattern& rF if( pFoundData ) return pFoundData; + if (pFoundData = FindMetricCompatibleFont(rFSD); pFoundData) + return pFoundData; + // some systems provide special customization // e.g. they suggest "serif" as UI-font, but this name cannot be used directly // because the system wants to map it to another font first, e.g. "Helvetica" @@ -1051,8 +1076,7 @@ PhysicalFontFamily* PhysicalFontCollection::FindFontFamily(FontSelectPattern& rF return pFoundData; } - if (FindMetricCompatibleFont(rFSD) || - (mpPreMatchHook && mpPreMatchHook->FindFontSubstitute(rFSD))) + if (mpPreMatchHook && mpPreMatchHook->FindFontSubstitute(rFSD)) { aSearchName = GetEnglishSearchFontName(aSearchName); }