From a552c3bc8c91a98432cea57243ea4a1c258a425a Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Wed, 7 Jul 2021 21:10:53 +0200 Subject: [PATCH] LibTTF: Use en-us naming table if available Some fonts tend to have multiple naming tables, namely MS-Gothic has 3 tables: [macintosh, ja], [windows, en-us], [windows, ja]. --- Userland/Libraries/LibTTF/Font.cpp | 40 +++++++++++++++++++----------- Userland/Libraries/LibTTF/Tables.h | 6 +++++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibTTF/Font.cpp b/Userland/Libraries/LibTTF/Font.cpp index 8cc9d2c6f0..9836998bae 100644 --- a/Userland/Libraries/LibTTF/Font.cpp +++ b/Userland/Libraries/LibTTF/Font.cpp @@ -166,24 +166,36 @@ String Name::string_for_id(NameId id) const auto num_entries = be_u16(m_slice.offset_pointer(2)); auto string_offset = be_u16(m_slice.offset_pointer(4)); + Vector valid_ids; + for (int i = 0; i < num_entries; ++i) { auto this_id = be_u16(m_slice.offset_pointer(6 + i * 12 + 6)); - if (this_id != (u16)id) - continue; - - auto platform = be_u16(m_slice.offset_pointer(6 + i * 12 + 0)); - auto length = be_u16(m_slice.offset_pointer(6 + i * 12 + 8)); - auto offset = be_u16(m_slice.offset_pointer(6 + i * 12 + 10)); - - if (platform == (u16)Platform::Windows) { - static auto& decoder = *TextCodec::decoder_for("utf-16be"); - return decoder.to_utf8(StringView { (const char*)m_slice.offset_pointer(string_offset + offset), length }); - } - - return String((const char*)m_slice.offset_pointer(string_offset + offset), length); + if (this_id == (u16)id) + valid_ids.append(i); } - return String::empty(); + if (valid_ids.is_empty()) + return String::empty(); + + auto it = valid_ids.find_if([this](auto const& i) { + // check if font has naming table for en-US language id + auto platform = be_u16(m_slice.offset_pointer(6 + i * 12 + 0)); + auto language_id = be_u16(m_slice.offset_pointer(6 + i * 12 + 4)); + return (platform == (u16)Platform::Macintosh && language_id == (u16)MacintoshLanguage::English) + || (platform == (u16)Platform::Windows && language_id == (u16)WindowsLanguage::EnglishUnitedStates); + }); + auto i = it != valid_ids.end() ? *it : valid_ids.first(); + + auto platform = be_u16(m_slice.offset_pointer(6 + i * 12 + 0)); + auto length = be_u16(m_slice.offset_pointer(6 + i * 12 + 8)); + auto offset = be_u16(m_slice.offset_pointer(6 + i * 12 + 10)); + + if (platform == (u16)Platform::Windows) { + static auto& decoder = *TextCodec::decoder_for("utf-16be"); + return decoder.to_utf8(StringView { (const char*)m_slice.offset_pointer(string_offset + offset), length }); + } + + return String((const char*)m_slice.offset_pointer(string_offset + offset), length); } GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const diff --git a/Userland/Libraries/LibTTF/Tables.h b/Userland/Libraries/LibTTF/Tables.h index 2ced8f09a2..4cf9971c43 100644 --- a/Userland/Libraries/LibTTF/Tables.h +++ b/Userland/Libraries/LibTTF/Tables.h @@ -133,6 +133,12 @@ public: Macintosh = 1, Windows = 3, }; + enum class MacintoshLanguage { + English = 0, + }; + enum class WindowsLanguage { + EnglishUnitedStates = 0x0409, + }; static Optional from_slice(const ReadonlyBytes&); String family_name() const { return string_for_id(NameId::FamilyName); }