mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 15:27:35 +00:00
LibGfx/OpenType: Clean up "name" table reading
Use a C++ struct to read out the header, and make the rest of the code more idiomatic.
This commit is contained in:
parent
5d8feab131
commit
afba67f3a2
2 changed files with 44 additions and 20 deletions
|
@ -297,14 +297,14 @@ Optional<i16> Kern::read_glyph_kerning_format0(ReadonlyBytes slice, u16 left_gly
|
||||||
|
|
||||||
DeprecatedString Name::string_for_id(NameId id) const
|
DeprecatedString Name::string_for_id(NameId id) const
|
||||||
{
|
{
|
||||||
auto num_entries = be_u16(m_slice.offset_pointer(2));
|
auto const count = header().count;
|
||||||
auto string_offset = be_u16(m_slice.offset_pointer(4));
|
auto const storage_offset = header().storage_offset;
|
||||||
|
|
||||||
Vector<int> valid_ids;
|
Vector<int> valid_ids;
|
||||||
|
|
||||||
for (int i = 0; i < num_entries; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
auto this_id = be_u16(m_slice.offset_pointer(6 + i * 12 + 6));
|
auto this_id = header().name_record[i].name_id;
|
||||||
if (this_id == (u16)id)
|
if (this_id == to_underlying(id))
|
||||||
valid_ids.append(i);
|
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) {
|
auto it = valid_ids.find_if([this](auto const& i) {
|
||||||
// check if font has naming table for en-US language id
|
// check if font has naming table for en-US language id
|
||||||
auto platform = be_u16(m_slice.offset_pointer(6 + i * 12 + 0));
|
auto const& name_record = header().name_record[i];
|
||||||
auto language_id = be_u16(m_slice.offset_pointer(6 + i * 12 + 4));
|
auto const platform_id = name_record.platform_id;
|
||||||
return (platform == (u16)Platform::Macintosh && language_id == (u16)MacintoshLanguage::English)
|
auto const language_id = name_record.language_id;
|
||||||
|| (platform == (u16)Platform::Windows && language_id == (u16)WindowsLanguage::EnglishUnitedStates);
|
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 i = it != valid_ids.end() ? *it : valid_ids.first();
|
||||||
|
|
||||||
auto platform = be_u16(m_slice.offset_pointer(6 + i * 12 + 0));
|
auto const& name_record = header().name_record[i];
|
||||||
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) {
|
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");
|
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
|
GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct Version16Dot16 {
|
||||||
using FWord = BigEndian<i16>;
|
using FWord = BigEndian<i16>;
|
||||||
using UFWord = BigEndian<u16>;
|
using UFWord = BigEndian<u16>;
|
||||||
using Tag = BigEndian<u32>;
|
using Tag = BigEndian<u32>;
|
||||||
|
using Offset16 = BigEndian<u16>;
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/head
|
// https://learn.microsoft.com/en-us/typography/opentype/spec/head
|
||||||
// head: Font Header Table
|
// head: Font Header Table
|
||||||
|
@ -253,15 +254,15 @@ private:
|
||||||
// name: Naming Table
|
// name: Naming Table
|
||||||
class Name {
|
class Name {
|
||||||
public:
|
public:
|
||||||
enum class Platform {
|
enum class Platform : u16 {
|
||||||
Unicode = 0,
|
Unicode = 0,
|
||||||
Macintosh = 1,
|
Macintosh = 1,
|
||||||
Windows = 3,
|
Windows = 3,
|
||||||
};
|
};
|
||||||
enum class MacintoshLanguage {
|
enum class MacintoshLanguage : u16 {
|
||||||
English = 0,
|
English = 0,
|
||||||
};
|
};
|
||||||
enum class WindowsLanguage {
|
enum class WindowsLanguage : u16 {
|
||||||
EnglishUnitedStates = 0x0409,
|
EnglishUnitedStates = 0x0409,
|
||||||
};
|
};
|
||||||
static Optional<Name> from_slice(ReadonlyBytes);
|
static Optional<Name> from_slice(ReadonlyBytes);
|
||||||
|
@ -272,7 +273,27 @@ public:
|
||||||
DeprecatedString typographic_subfamily_name() const { return string_for_id(NameId::TypographicSubfamilyName); }
|
DeprecatedString typographic_subfamily_name() const { return string_for_id(NameId::TypographicSubfamilyName); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class NameId {
|
// https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-records
|
||||||
|
struct NameRecord {
|
||||||
|
BigEndian<u16> platform_id;
|
||||||
|
BigEndian<u16> encoding_id;
|
||||||
|
BigEndian<u16> language_id;
|
||||||
|
BigEndian<u16> name_id;
|
||||||
|
BigEndian<u16> length;
|
||||||
|
Offset16 string_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-0
|
||||||
|
struct NamingTableVersion0 {
|
||||||
|
BigEndian<u16> version;
|
||||||
|
BigEndian<u16> count;
|
||||||
|
Offset16 storage_offset;
|
||||||
|
NameRecord name_record[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
NamingTableVersion0 const& header() const { return *bit_cast<NamingTableVersion0 const*>(m_slice.data()); }
|
||||||
|
|
||||||
|
enum class NameId : u16 {
|
||||||
Copyright = 0,
|
Copyright = 0,
|
||||||
FamilyName = 1,
|
FamilyName = 1,
|
||||||
SubfamilyName = 2,
|
SubfamilyName = 2,
|
||||||
|
@ -293,7 +314,7 @@ private:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DeprecatedString string_for_id(NameId id) const;
|
DeprecatedString string_for_id(NameId) const;
|
||||||
|
|
||||||
ReadonlyBytes m_slice;
|
ReadonlyBytes m_slice;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue