Reapply "tdf#63011 vcl: Use localized font family names as aliases"

This reverts commit 3b43be508d.

Modifies the original implementation to skip parsing font names when
SAL_NON_APPLICATION_FONT_USE=abort. This recovers the original Windows
testsuite execution time, and otherwise doesn't affect tests since that
environment variable is meant to prevent font fallback.

This change had an outsized effect on Windows test execution time, but
does not seem to have a significant effect on Windows desktop
performance. Out of an abundance of caution, this change also includes
some small optimizations which should reduce the amount of I/O which is
done while parsing localized font names.

Change-Id: Idc80f20d859863e02788a301c1f3af15ab0e8a4f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203280
Tested-by: Jenkins
Reviewed-by: Jonathan Clark <jonathan@libreoffice.org>
This commit is contained in:
Jonathan Clark
2026-04-07 17:19:11 +02:00
parent 7c0d875aca
commit c93a99c3a1
10 changed files with 208 additions and 77 deletions
+1
View File
@@ -149,6 +149,7 @@ private:
VclPtr<OutputDevice> mpDev;
VclPtr<OutputDevice> mpDev2;
std::vector<std::unique_ptr<ImplFontListNameInfo>> m_Entries;
std::unordered_map<OUString, OUString> maAliases;
SVT_DLLPRIVATE ImplFontListNameInfo* ImplFind( std::u16string_view rSearchName, sal_uInt32* pIndex ) const;
SVT_DLLPRIVATE ImplFontListNameInfo* ImplFindByName( std::u16string_view rStr ) const;
+1
View File
@@ -1181,6 +1181,7 @@ public:
FontMetric GetFontMetricFromCollection( int nDevFontIndex ) const;
int GetFontFaceCollectionCount() const;
const std::unordered_map<OUString, OUString>& GetFontFamilyAliases() const;
bool IsFontAvailable( std::u16string_view rFontName ) const;
+21 -1
View File
@@ -243,7 +243,17 @@ ImplFontListNameInfo* FontList::ImplFind(std::u16string_view rSearchName, sal_uI
ImplFontListNameInfo* FontList::ImplFindByName(std::u16string_view rStr) const
{
OUString aSearchName = ImplMakeSearchStringFromName(rStr);
return ImplFind( aSearchName, nullptr );
if (auto* pFont = ImplFind(aSearchName, nullptr); pFont != nullptr)
{
return pFont;
}
if (auto it = maAliases.find(aSearchName); it != maAliases.end())
{
return ImplFind(it->second, nullptr);
}
return nullptr;
}
void FontList::ImplInsertFonts(OutputDevice* pDevice, bool bInsertData)
@@ -345,6 +355,16 @@ void FontList::ImplInsertFonts(OutputDevice* pDevice, bool bInsertData)
if ( pData )
pData->mnType |= nType;
}
if (bInsertData)
{
const auto& rAliases = pDevice->GetFontFamilyAliases();
for (const auto& rAlias : rAliases)
{
maAliases.insert_or_assign(ImplMakeSearchString(rAlias.first),
ImplMakeSearchString(rAlias.second));
}
}
}
FontList::FontList(OutputDevice* pDevice, OutputDevice* pDevice2)
+8 -1
View File
@@ -47,6 +47,8 @@ namespace vcl::font
class VCL_PLUGIN_PUBLIC PhysicalFontCollection final
{
public:
typedef std::unordered_map<OUString, OUString> FontFamilyAliases;
explicit PhysicalFontCollection();
~PhysicalFontCollection();
@@ -57,11 +59,13 @@ public:
// find the device font family
vcl::font::PhysicalFontFamily* FindFontFamily( std::u16string_view rFontName ) const;
vcl::font::PhysicalFontFamily* FindOrCreateFontFamily( const OUString &rFamilyName );
std::tuple<vcl::font::PhysicalFontFamily*, bool> FindOrCreateFontFamily( const OUString &rFamilyName );
SAL_DLLPRIVATE vcl::font::PhysicalFontFamily* FindFontFamily( vcl::font::FontSelectPattern& ) const;
vcl::font::PhysicalFontFamily* FindFontFamilyByTokenNames(std::u16string_view rTokenStr) const;
vcl::font::PhysicalFontFamily* FindFontFamilyByAttributes(ImplFontAttrs nSearchType, FontWeight, FontWidth,
FontItalic, std::u16string_view rSearchFamily) const;
void AddFontFamilyAlias(const OUString& rAlias, const OUString& rFamilyName);
const FontFamilyAliases& GetFontFamilyNameAliases() const;
// suggest fonts for glyph fallback
SAL_DLLPRIVATE vcl::font::PhysicalFontFamily* GetGlyphFallbackFont( vcl::font::FontSelectPattern&,
@@ -82,6 +86,9 @@ private:
typedef std::unordered_map<OUString, std::unique_ptr<vcl::font::PhysicalFontFamily>> PhysicalFontFamilies;
PhysicalFontFamilies maPhysicalFontFamilies;
FontFamilyAliases maFontLookupAliases; // maps normalized localized names
FontFamilyAliases maFontFamilyNameAliases; // maps verbatim localized names
vcl::font::PreMatchFontSubstitution* mpPreMatchHook; // device specific prematch substitution
vcl::font::GlyphFallbackFontSubstitution* mpFallbackHook; // device specific glyph fallback substitution
+2
View File
@@ -183,6 +183,8 @@ public:
OUString GetName(NameID, const LanguageTag&) const;
OUString GetName(NameID aNameID) const { return GetName(aNameID, LanguageTag(LANGUAGE_NONE)); }
std::vector<OUString> GetAliases() const;
virtual hb_face_t* GetHbFace() const;
virtual hb_blob_t* GetHbTable(hb_tag_t) const
{
+64 -52
View File
@@ -57,6 +57,7 @@ public:
void testShouldFindOtherStyleFamily();
void testShouldNotFindOtherStyleFamily();
void testShouldFindSchoolbookFamily();
void testFontFamilyAliases();
CPPUNIT_TEST_SUITE(VclPhysicalFontCollectionTest);
CPPUNIT_TEST(testShouldCreateAndAddFontFamilyToCollection);
@@ -88,6 +89,7 @@ public:
CPPUNIT_TEST(testShouldFindOtherStyleFamily);
CPPUNIT_TEST(testShouldNotFindOtherStyleFamily);
CPPUNIT_TEST(testShouldFindSchoolbookFamily);
CPPUNIT_TEST(testFontFamilyAliases);
CPPUNIT_TEST_SUITE_END();
};
@@ -98,15 +100,17 @@ void VclPhysicalFontCollectionTest::testShouldCreateAndAddFontFamilyToCollection
aFontCollection.Count());
// please note that fonts created this way are NOT normalized and will not be found if you search for them in the collection
vcl::font::PhysicalFontFamily* pFontFamily
auto[pFontFamily, bNewFamily]
= aFontCollection.FindOrCreateFontFamily(u"Test Font Family Name"_ustr);
CPPUNIT_ASSERT_MESSAGE("Font family was not newly created", bNewFamily);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Does not have only one font family in collection",
static_cast<int>(1), aFontCollection.Count());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Font family name not correct", u"Test Font Family Name"_ustr,
pFontFamily->GetSearchName());
vcl::font::PhysicalFontFamily* pFontFamily2
auto[pFontFamily2, bNewFamily2]
= aFontCollection.FindOrCreateFontFamily(u"Test Font Family Name"_ustr);
CPPUNIT_ASSERT_MESSAGE("Font family was newly created", !bNewFamily2);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Still only one font family in collection", static_cast<int>(1),
aFontCollection.Count());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Font family name not correct", u"Test Font Family Name"_ustr,
@@ -176,8 +180,8 @@ void VclPhysicalFontCollectionTest::testShouldFindCJKFamily()
vcl::font::PhysicalFontCollection aFontCollection;
// interestingly, you need to normalize the name still
vcl::font::PhysicalFontFamily* pFontFamily = aFontCollection.FindOrCreateFontFamily(
GetEnglishSearchFontName(u"시험")); // Korean for "test"
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(
GetEnglishSearchFontName(u"시험"))); // Korean for "test"
AddNormalFontFace(pFontFamily, u"시험"_ustr);
vcl::font::PhysicalFontFamily* pCJKFamily = aFontCollection.FindFontFamilyByAttributes(
@@ -190,8 +194,8 @@ void VclPhysicalFontCollectionTest::testShouldFindCJKFamily()
void VclPhysicalFontCollectionTest::testShouldNotFindCJKFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"No CJK characters"));
auto* pFontFamily = std::get<0>(
aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"No CJK characters")));
AddNormalFontFace(pFontFamily, u"No CJK characters"_ustr);
CPPUNIT_ASSERT_MESSAGE("family found",
@@ -202,8 +206,7 @@ void VclPhysicalFontCollectionTest::testShouldNotFindCJKFamily()
void VclPhysicalFontCollectionTest::testShouldFindStarsymbolFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"starsymbol"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"starsymbol"_ustr));
AddNormalFontFace(pFontFamily, u"starsymbol"_ustr);
CPPUNIT_ASSERT_MESSAGE("starsymbol created", pFontFamily);
@@ -219,12 +222,12 @@ void VclPhysicalFontCollectionTest::testShouldFindOpensymbolFamilyWithMultipleSy
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pOpenSymbolFamily
= aFontCollection.FindOrCreateFontFamily(u"opensymbol"_ustr);
auto* pOpenSymbolFamily
= std::get<0>(aFontCollection.FindOrCreateFontFamily(u"opensymbol"_ustr));
AddNormalFontFace(pOpenSymbolFamily, u"opensymbol"_ustr);
vcl::font::PhysicalFontFamily* pWingDingsFontFamily
= aFontCollection.FindOrCreateFontFamily(u"wingdings"_ustr);
auto* pWingDingsFontFamily
= std::get<0>(aFontCollection.FindOrCreateFontFamily(u"wingdings"_ustr));
AddNormalFontFace(pWingDingsFontFamily, u"wingdings"_ustr);
vcl::font::PhysicalFontFamily* pStarsymbolFamily = aFontCollection.FindFontFamilyByAttributes(
@@ -237,8 +240,7 @@ void VclPhysicalFontCollectionTest::testShouldFindOpensymbolFamilyWithMultipleSy
void VclPhysicalFontCollectionTest::testShouldFindSymboltypeFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testsymbol"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testsymbol"_ustr));
AddNormalFontFace(pFontFamily, u"testsymbol"_ustr);
@@ -254,8 +256,7 @@ void VclPhysicalFontCollectionTest::testShouldFindSymbolFamilyByMatchType()
// TODO: figure out how to test matchtype with ImplFontAttrs::Full
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"symbols"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"symbols"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"symbols"_ustr);
@@ -273,8 +274,8 @@ void VclPhysicalFontCollectionTest::testShouldFindSymbolFamilyByMatchType()
void VclPhysicalFontCollectionTest::testImpossibleSymbolFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testsymbolfamily"_ustr);
auto* pFontFamily
= std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testsymbolfamily"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"testsymbolfamily"_ustr);
@@ -292,8 +293,7 @@ void VclPhysicalFontCollectionTest::testImpossibleSymbolFamily()
void VclPhysicalFontCollectionTest::testShouldNotFindSymbolFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"symbol"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"symbol"_ustr));
AddNormalFontFace(pFontFamily, u"symbol"_ustr);
CPPUNIT_ASSERT_MESSAGE(
@@ -307,8 +307,8 @@ void VclPhysicalFontCollectionTest::testShouldMatchFamilyName()
// note that for this test, it is irrelevant what the search name is for PhysicalFontFamily,
// the font searches the family name and uses the search parameter of FindFontFamilyByAttributes()
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"Matching family name"_ustr);
auto* pFontFamily
= std::get<0>(aFontCollection.FindOrCreateFontFamily(u"Matching family name"_ustr));
AddNormalFontFace(pFontFamily, GetEnglishSearchFontName(u"Matching family name"));
CPPUNIT_ASSERT_MESSAGE("No family found",
@@ -320,8 +320,7 @@ void VclPhysicalFontCollectionTest::testShouldMatchFamilyName()
void VclPhysicalFontCollectionTest::testShouldMatchBrushScriptFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"script"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"script"_ustr));
AddNormalFontFace(pFontFamily, u"script"_ustr);
CPPUNIT_ASSERT_MESSAGE("Brush script family not found",
@@ -333,8 +332,7 @@ void VclPhysicalFontCollectionTest::testShouldMatchBrushScriptFamily()
void VclPhysicalFontCollectionTest::testShouldNotMatchBrushScriptFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testfamily"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testfamily"_ustr));
AddNormalFontFace(pFontFamily, u"testfamily"_ustr);
CPPUNIT_ASSERT_MESSAGE("Brush script family found",
@@ -349,8 +347,8 @@ void VclPhysicalFontCollectionTest::testShouldMatchFixedFamily()
// note that for this test, it is irrelevant what the search name is for PhysicalFontFamily,
// the font searches the family name and uses the search parameter of FindFontFamilyByAttributes()
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Matching family name"));
auto* pFontFamily = std::get<0>(
aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Matching family name")));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(GetEnglishSearchFontName(u"Matching family name"));
@@ -371,8 +369,8 @@ void VclPhysicalFontCollectionTest::testShouldNotMatchFixedFamily()
// note that for this test, it is irrelevant what the search name is for PhysicalFontFamily,
// the font searches the family name and uses the search parameter of FindFontFamilyByAttributes()
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Matching family name"));
auto* pFontFamily = std::get<0>(
aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Matching family name")));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(GetEnglishSearchFontName(u"Matching family name"));
@@ -390,8 +388,7 @@ void VclPhysicalFontCollectionTest::testShouldNotMatchFixedFamily()
void VclPhysicalFontCollectionTest::testShouldMatchSerifFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"serif"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"serif"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"serif"_ustr);
@@ -408,8 +405,7 @@ void VclPhysicalFontCollectionTest::testShouldMatchSerifFamily()
void VclPhysicalFontCollectionTest::testShouldNotMatchSerifFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"sansseriftest"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"sansseriftest"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"sansseriftest"_ustr);
@@ -426,8 +422,7 @@ void VclPhysicalFontCollectionTest::testShouldNotMatchSerifFamily()
void VclPhysicalFontCollectionTest::testShouldMatchSansSerifFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"sansserif"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"sansserif"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"sansserif"_ustr);
@@ -445,8 +440,7 @@ void VclPhysicalFontCollectionTest::testShouldMatchSansSerifFamily()
void VclPhysicalFontCollectionTest::testShouldNotMatchSansSerifFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"serif"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"serif"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"serif"_ustr);
@@ -463,8 +457,7 @@ void VclPhysicalFontCollectionTest::testShouldNotMatchSansSerifFamily()
void VclPhysicalFontCollectionTest::testShouldMatchDecorativeFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"decorative"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"decorative"_ustr));
FontAttributes aFontAttr;
aFontAttr.SetFamilyName(u"decorative"_ustr);
@@ -482,8 +475,7 @@ void VclPhysicalFontCollectionTest::testShouldMatchDecorativeFamily()
void VclPhysicalFontCollectionTest::testShouldFindTitlingFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testtitling"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testtitling"_ustr));
AddNormalFontFace(pFontFamily, u"testtitling"_ustr);
CPPUNIT_ASSERT_MESSAGE("Titling family not found", aFontCollection.FindFontFamilyByAttributes(
@@ -494,8 +486,7 @@ void VclPhysicalFontCollectionTest::testShouldFindTitlingFamily()
void VclPhysicalFontCollectionTest::testShouldFindCapitalsFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testcaps"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testcaps"_ustr));
AddNormalFontFace(pFontFamily, u"testcaps"_ustr);
CPPUNIT_ASSERT_MESSAGE("All-caps family not found", aFontCollection.FindFontFamilyByAttributes(
@@ -506,8 +497,8 @@ void VclPhysicalFontCollectionTest::testShouldFindCapitalsFamily()
void VclPhysicalFontCollectionTest::testShouldFindFamilyName()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Test font name"));
auto* pFontFamily = std::get<0>(
aFontCollection.FindOrCreateFontFamily(GetEnglishSearchFontName(u"Test font name")));
AddNormalFontFace(pFontFamily, GetEnglishSearchFontName(u"Test font name"));
CPPUNIT_ASSERT_MESSAGE("Cannot find font name",
@@ -519,8 +510,7 @@ void VclPhysicalFontCollectionTest::testShouldFindFamilyName()
void VclPhysicalFontCollectionTest::testShouldFindOtherStyleFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testoldstyle"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testoldstyle"_ustr));
AddNormalFontFace(pFontFamily, u"testoldstyle"_ustr);
CPPUNIT_ASSERT_MESSAGE("Did not find font name", aFontCollection.FindFontFamilyByAttributes(
@@ -531,8 +521,7 @@ void VclPhysicalFontCollectionTest::testShouldFindOtherStyleFamily()
void VclPhysicalFontCollectionTest::testShouldNotFindOtherStyleFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"monotype"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"monotype"_ustr));
AddNormalFontFace(pFontFamily, u"monotype"_ustr);
CPPUNIT_ASSERT_MESSAGE("Found font name", !aFontCollection.FindFontFamilyByAttributes(
@@ -543,8 +532,7 @@ void VclPhysicalFontCollectionTest::testShouldNotFindOtherStyleFamily()
void VclPhysicalFontCollectionTest::testShouldFindSchoolbookFamily()
{
vcl::font::PhysicalFontCollection aFontCollection;
vcl::font::PhysicalFontFamily* pFontFamily
= aFontCollection.FindOrCreateFontFamily(u"testschoolbook"_ustr);
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testschoolbook"_ustr));
AddNormalFontFace(pFontFamily, u"testschoolbook"_ustr);
CPPUNIT_ASSERT_MESSAGE("Did not find font name", aFontCollection.FindFontFamilyByAttributes(
@@ -552,6 +540,30 @@ void VclPhysicalFontCollectionTest::testShouldFindSchoolbookFamily()
WIDTH_NORMAL, ITALIC_NORMAL, u""));
}
void VclPhysicalFontCollectionTest::testFontFamilyAliases()
{
vcl::font::PhysicalFontCollection aFontCollection;
auto* pFontFamily = std::get<0>(aFontCollection.FindOrCreateFontFamily(u"testfont"_ustr));
AddNormalFontFace(pFontFamily, u"testfont"_ustr);
aFontCollection.AddFontFamilyAlias(u"Some Alias"_ustr, u"Test Font"_ustr);
CPPUNIT_ASSERT_MESSAGE("Did not find with real name",
aFontCollection.FindFontFamily(u"Test Font"));
CPPUNIT_ASSERT_MESSAGE("Did not find with alias",
aFontCollection.FindFontFamily(u"Some Alias"));
CPPUNIT_ASSERT_MESSAGE("Did not find with normalized alias",
aFontCollection.FindFontFamily(u"somealias"));
const auto& rAliases = aFontCollection.GetFontFamilyNameAliases();
CPPUNIT_ASSERT_EQUAL(size_t(1), rAliases.size());
for (const auto& rEm : rAliases)
{
CPPUNIT_ASSERT_EQUAL(u"Some Alias"_ustr, rEm.first);
CPPUNIT_ASSERT_EQUAL(u"Test Font"_ustr, rEm.second);
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(VclPhysicalFontCollectionTest);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+62 -19
View File
@@ -98,6 +98,8 @@ void PhysicalFontCollection::Clear()
// clear all entries in the device font list
maPhysicalFontFamilies.clear();
maFontLookupAliases.clear();
maFontFamilyNameAliases.clear();
// match data must be recalculated too
mbMatchData = false;
@@ -294,11 +296,43 @@ PhysicalFontFamily* PhysicalFontCollection::GetGlyphFallbackFont(FontSelectPatte
void PhysicalFontCollection::Add(PhysicalFontFace* pNewData)
{
OUString aSearchName = GetEnglishSearchFontName( pNewData->GetFamilyName() );
OUString aSearchName = GetEnglishSearchFontName(pNewData->GetFamilyName());
PhysicalFontFamily* pFoundData = FindOrCreateFontFamily(aSearchName);
auto [pFoundData, bFamilyIsNew] = FindOrCreateFontFamily(aSearchName);
pFoundData->AddFontFace( pNewData );
pFoundData->AddFontFace(pNewData);
// tdf#63011: To reduce the performance impact of extracting localized font family
// names from font files, only do this for the first font in a new family. Also,
// skip parsing fonts when running tests that block font fallback.
static const bool bAbortOnFontSubstitute = []
{
const char* pEnv = getenv("SAL_NON_APPLICATION_FONT_USE");
return pEnv && strcmp(pEnv, "abort") == 0;
}();
if (bFamilyIsNew && !bAbortOnFontSubstitute)
{
for (const OUString& rStr : pNewData->GetAliases())
{
AddFontFamilyAlias(rStr, pNewData->GetFamilyName());
}
}
}
void PhysicalFontCollection::AddFontFamilyAlias(const OUString& rAlias, const OUString& rFamilyName)
{
if (rAlias != rFamilyName)
{
maFontLookupAliases.insert_or_assign(GetEnglishSearchFontName(rAlias),
GetEnglishSearchFontName(rFamilyName));
maFontFamilyNameAliases.insert_or_assign(rAlias, rFamilyName);
}
}
const PhysicalFontCollection::FontFamilyAliases& PhysicalFontCollection::GetFontFamilyNameAliases() const
{
return maFontFamilyNameAliases;
}
// find the font from the normalized font family name
@@ -307,12 +341,20 @@ PhysicalFontFamily* PhysicalFontCollection::ImplFindFontFamilyBySearchName(const
// must be called with a normalized name.
assert( GetEnglishSearchFontName( rSearchName ) == rSearchName );
PhysicalFontFamilies::const_iterator it = maPhysicalFontFamilies.find( rSearchName );
if( it == maPhysicalFontFamilies.end() )
return nullptr;
if (auto it = maPhysicalFontFamilies.find(rSearchName); it != maPhysicalFontFamilies.end())
{
return it->second.get();
}
PhysicalFontFamily* pFoundData = (*it).second.get();
return pFoundData;
if (auto it = maFontLookupAliases.find(rSearchName); it != maFontLookupAliases.end())
{
if (auto jt = maPhysicalFontFamilies.find(it->second); jt != maPhysicalFontFamilies.end())
{
return jt->second.get();
}
}
return nullptr;
}
PhysicalFontFamily* PhysicalFontCollection::FindFontFamily(std::u16string_view rFontName) const
@@ -320,21 +362,19 @@ PhysicalFontFamily* PhysicalFontCollection::FindFontFamily(std::u16string_view r
return ImplFindFontFamilyBySearchName( GetEnglishSearchFontName( rFontName ) );
}
PhysicalFontFamily *PhysicalFontCollection::FindOrCreateFontFamily(OUString const& rFamilyName)
std::tuple<PhysicalFontFamily*, bool>
PhysicalFontCollection::FindOrCreateFontFamily(OUString const& rFamilyName)
{
PhysicalFontFamilies::const_iterator it = maPhysicalFontFamilies.find( rFamilyName );
PhysicalFontFamily* pFoundData = nullptr;
if( it != maPhysicalFontFamilies.end() )
pFoundData = (*it).second.get();
if( !pFoundData )
if (auto it = maPhysicalFontFamilies.find(rFamilyName); it != maPhysicalFontFamilies.end())
{
pFoundData = new PhysicalFontFamily(rFamilyName);
maPhysicalFontFamilies[ rFamilyName ].reset(pFoundData);
return std::make_tuple((*it).second.get(), false);
}
return pFoundData;
auto pNewData = std::make_unique<PhysicalFontFamily>(rFamilyName);
auto* pReturnFamily = pNewData.get();
maPhysicalFontFamilies.insert_or_assign(rFamilyName, std::move(pNewData));
return std::make_tuple(pReturnFamily, true);
}
PhysicalFontFamily* PhysicalFontCollection::FindFontFamilyByTokenNames(std::u16string_view rTokenStr) const
@@ -911,6 +951,9 @@ std::shared_ptr<PhysicalFontCollection> PhysicalFontCollection::Clone() const
pFontFace->UpdateCloneFontList(*xClonedCollection);
}
xClonedCollection->maFontLookupAliases = maFontLookupAliases;
xClonedCollection->maFontFamilyNameAliases = maFontFamilyNameAliases;
return xClonedCollection;
}
+39
View File
@@ -764,6 +764,45 @@ OUString PhysicalFontFace::GetName(NameID aNameID, const LanguageTag& rLanguageT
return sName;
}
std::vector<OUString> PhysicalFontFace::GetAliases() const
{
std::vector<OUString> aNames;
auto* pHbFace = GetHbFace();
unsigned int nEntries = 0;
const hb_ot_name_entry_t* aEntries = hb_ot_name_list_names(pHbFace, &nEntries);
std::vector<char16_t> aBuf;
for (unsigned int i = 0; i < nEntries; ++i)
{
if (aEntries[i].name_id != HB_OT_NAME_ID_FONT_FAMILY)
{
continue;
}
auto nName = hb_ot_name_get_utf16(pHbFace, aEntries[i].name_id, aEntries[i].language,
nullptr, nullptr);
if (nName)
{
++nName;
aBuf.clear();
aBuf.resize(nName, 0);
hb_ot_name_get_utf16(pHbFace, aEntries[i].name_id, aEntries[i].language, &nName,
reinterpret_cast<uint16_t*>(aBuf.data()));
OUString sName{ aBuf.data(), static_cast<sal_Int32>(nName) };
if (GetFamilyName() != sName)
{
aNames.push_back(std::move(sName));
}
}
}
return aNames;
}
const std::vector<vcl::font::Variation>&
PhysicalFontFace::GetVariations(const LogicalFontInstance&) const
{
+4 -4
View File
@@ -253,14 +253,14 @@ void PhysicalFontFamily::UpdateCloneFontList(vcl::font::PhysicalFontCollection&
for (auto const& font : maFontFaces)
{
PhysicalFontFace *pFoundFontFace = font.get();
PhysicalFontFace* pFoundFontFace = font.get();
if (!pFamily)
{ // tdf#98989 lazy create as family without faces won't work
pFamily = rFontCollection.FindOrCreateFontFamily(aFamilyName);
{ // tdf#98989 lazy create as family without faces won't work
pFamily = std::get<0>(rFontCollection.FindOrCreateFontFamily(aFamilyName));
}
assert(pFamily);
pFamily->AddFontFace( pFoundFontFace );
pFamily->AddFontFace(pFoundFontFace);
}
}
}
+6
View File
@@ -119,6 +119,12 @@ int OutputDevice::GetFontFaceCollectionCount() const
return mpFontFaceCollection->Count();
}
const std::unordered_map<OUString, OUString>& OutputDevice::GetFontFamilyAliases() const
{
ImplInitFontList();
return mxFontCollection->GetFontFamilyNameAliases();
}
bool OutputDevice::IsFontAvailable( std::u16string_view rFontName ) const
{
ImplInitFontList();