Browse Source

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].
LuK1337 4 years ago
parent
commit
a552c3bc8c
2 changed files with 28 additions and 10 deletions
  1. 22 10
      Userland/Libraries/LibTTF/Font.cpp
  2. 6 0
      Userland/Libraries/LibTTF/Tables.h

+ 22 - 10
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<int> 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;
+        if (this_id == (u16)id)
+            valid_ids.append(i);
+    }
 
+    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 length = be_u16(m_slice.offset_pointer(6 + i * 12 + 8));
-        auto offset = be_u16(m_slice.offset_pointer(6 + i * 12 + 10));
+        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();
 
-        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 });
-        }
+    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));
 
-        return String((const char*)m_slice.offset_pointer(string_offset + offset), length);
+    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::empty();
+    return String((const char*)m_slice.offset_pointer(string_offset + offset), length);
 }
 
 GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const

+ 6 - 0
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<Name> from_slice(const ReadonlyBytes&);
 
     String family_name() const { return string_for_id(NameId::FamilyName); }