diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index c371e05403..0527d09a56 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -297,14 +297,14 @@ Optional Kern::read_glyph_kerning_format0(ReadonlyBytes slice, u16 left_gly DeprecatedString 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)); + auto const count = header().count; + auto const storage_offset = header().storage_offset; 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) + for (size_t i = 0; i < count; ++i) { + auto this_id = header().name_record[i].name_id; + if (this_id == to_underlying(id)) valid_ids.append(i); } @@ -313,23 +313,26 @@ DeprecatedString Name::string_for_id(NameId id) const 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 const& name_record = header().name_record[i]; + auto const platform_id = name_record.platform_id; + auto const language_id = name_record.language_id; + return (platform_id == to_underlying(Platform::Macintosh) && language_id == to_underlying(MacintoshLanguage::English)) + || (platform_id == to_underlying(Platform::Windows) && language_id == to_underlying(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)); + auto const& name_record = header().name_record[i]; - if (platform == (u16)Platform::Windows) { + auto const platform_id = name_record.platform_id; + auto const length = name_record.length; + auto const offset = name_record.string_offset; + + if (platform_id == to_underlying(Platform::Windows)) { static auto& decoder = *TextCodec::decoder_for("utf-16be"); - return decoder.to_utf8(StringView { (char const*)m_slice.offset_pointer(string_offset + offset), length }); + return decoder.to_utf8(StringView { (char const*)m_slice.offset_pointer(storage_offset + offset), length }); } - return DeprecatedString((char const*)m_slice.offset_pointer(string_offset + offset), length); + return DeprecatedString((char const*)m_slice.offset_pointer(storage_offset + offset), length); } GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index 59e9ed1d20..8e0f013a54 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -36,6 +36,7 @@ struct Version16Dot16 { using FWord = BigEndian; using UFWord = BigEndian; using Tag = BigEndian; +using Offset16 = BigEndian; // https://learn.microsoft.com/en-us/typography/opentype/spec/head // head: Font Header Table @@ -253,15 +254,15 @@ private: // name: Naming Table class Name { public: - enum class Platform { + enum class Platform : u16 { Unicode = 0, Macintosh = 1, Windows = 3, }; - enum class MacintoshLanguage { + enum class MacintoshLanguage : u16 { English = 0, }; - enum class WindowsLanguage { + enum class WindowsLanguage : u16 { EnglishUnitedStates = 0x0409, }; static Optional from_slice(ReadonlyBytes); @@ -272,7 +273,27 @@ public: DeprecatedString typographic_subfamily_name() const { return string_for_id(NameId::TypographicSubfamilyName); } private: - enum class NameId { + // https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-records + struct NameRecord { + BigEndian platform_id; + BigEndian encoding_id; + BigEndian language_id; + BigEndian name_id; + BigEndian length; + Offset16 string_offset; + }; + + // https://learn.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-0 + struct NamingTableVersion0 { + BigEndian version; + BigEndian count; + Offset16 storage_offset; + NameRecord name_record[0]; + }; + + NamingTableVersion0 const& header() const { return *bit_cast(m_slice.data()); } + + enum class NameId : u16 { Copyright = 0, FamilyName = 1, SubfamilyName = 2, @@ -293,7 +314,7 @@ private: { } - DeprecatedString string_for_id(NameId id) const; + DeprecatedString string_for_id(NameId) const; ReadonlyBytes m_slice; };