mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-23 02:55:15 +00:00
LibGfx: Remove bit casting in OpenType Name table after construction
Store the name records as a span, and a separate bytes span for the string data.
This commit is contained in:
parent
fe2e1a0282
commit
89b35c6dc8
|
@ -179,18 +179,33 @@ GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const
|
||||||
|
|
||||||
ErrorOr<Name> Name::from_slice(ReadonlyBytes slice)
|
ErrorOr<Name> Name::from_slice(ReadonlyBytes slice)
|
||||||
{
|
{
|
||||||
return Name(slice);
|
// FIXME: Support version 1 table too.
|
||||||
|
|
||||||
|
if (slice.size() < sizeof(NamingTableVersion0))
|
||||||
|
return Error::from_string_literal("Could not load Name: Not enough data");
|
||||||
|
|
||||||
|
auto& naming_table = *bit_cast<NamingTableVersion0 const*>(slice.data());
|
||||||
|
|
||||||
|
auto name_record_data_size = naming_table.count * sizeof(NameRecord);
|
||||||
|
if (slice.size() < sizeof(NamingTableVersion0) + name_record_data_size)
|
||||||
|
return Error::from_string_literal("Could not load Name: Not enough data");
|
||||||
|
ReadonlySpan<NameRecord> name_records = { bit_cast<NameRecord const*>(slice.offset_pointer(sizeof(NamingTableVersion0))), naming_table.count };
|
||||||
|
|
||||||
|
if (slice.size() < naming_table.storage_offset)
|
||||||
|
return Error::from_string_literal("Could not load Name: Not enough data");
|
||||||
|
ReadonlyBytes string_data = slice.slice(naming_table.storage_offset);
|
||||||
|
|
||||||
|
return Name(naming_table, name_records, string_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Name::string_for_id(NameId id) const
|
String Name::string_for_id(NameId id) const
|
||||||
{
|
{
|
||||||
auto const count = header().count;
|
auto const count = m_naming_table.count;
|
||||||
auto const storage_offset = header().storage_offset;
|
|
||||||
|
|
||||||
Vector<int> valid_ids;
|
Vector<int> valid_ids;
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
auto this_id = header().name_record[i].name_id;
|
auto this_id = m_name_records[i].name_id;
|
||||||
if (this_id == to_underlying(id))
|
if (this_id == to_underlying(id))
|
||||||
valid_ids.append(i);
|
valid_ids.append(i);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +215,7 @@ String 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 const& name_record = header().name_record[i];
|
auto const& name_record = m_name_records[i];
|
||||||
auto const platform_id = name_record.platform_id;
|
auto const platform_id = name_record.platform_id;
|
||||||
auto const language_id = name_record.language_id;
|
auto const language_id = name_record.language_id;
|
||||||
return (platform_id == to_underlying(Platform::Macintosh) && language_id == to_underlying(MacintoshLanguage::English))
|
return (platform_id == to_underlying(Platform::Macintosh) && language_id == to_underlying(MacintoshLanguage::English))
|
||||||
|
@ -208,7 +223,7 @@ String Name::string_for_id(NameId id) const
|
||||||
});
|
});
|
||||||
auto i = it != valid_ids.end() ? *it : valid_ids.first();
|
auto i = it != valid_ids.end() ? *it : valid_ids.first();
|
||||||
|
|
||||||
auto const& name_record = header().name_record[i];
|
auto const& name_record = m_name_records[i];
|
||||||
|
|
||||||
auto const platform_id = name_record.platform_id;
|
auto const platform_id = name_record.platform_id;
|
||||||
auto const length = name_record.length;
|
auto const length = name_record.length;
|
||||||
|
@ -216,10 +231,10 @@ String Name::string_for_id(NameId id) const
|
||||||
|
|
||||||
if (platform_id == to_underlying(Platform::Windows)) {
|
if (platform_id == to_underlying(Platform::Windows)) {
|
||||||
static auto& decoder = *TextCodec::decoder_for("utf-16be"sv);
|
static auto& decoder = *TextCodec::decoder_for("utf-16be"sv);
|
||||||
return decoder.to_utf8(StringView { (char const*)m_slice.offset(storage_offset + offset), length }).release_value_but_fixme_should_propagate_errors();
|
return decoder.to_utf8(m_string_data.slice(offset, length)).release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
return String::from_utf8(m_slice.slice(storage_offset + offset, length)).release_value_but_fixme_should_propagate_errors();
|
return String::from_utf8(m_string_data.slice(offset, length)).release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<Kern> Kern::from_slice(ReadonlyBytes slice)
|
ErrorOr<Kern> Kern::from_slice(ReadonlyBytes slice)
|
||||||
|
|
|
@ -382,12 +382,11 @@ private:
|
||||||
BigEndian<u16> version;
|
BigEndian<u16> version;
|
||||||
BigEndian<u16> count;
|
BigEndian<u16> count;
|
||||||
Offset16 storage_offset;
|
Offset16 storage_offset;
|
||||||
NameRecord name_record[0];
|
// NameRecords are stored in a separate span.
|
||||||
|
// NameRecord name_record[0];
|
||||||
};
|
};
|
||||||
static_assert(AssertSize<NamingTableVersion0, 6>());
|
static_assert(AssertSize<NamingTableVersion0, 6>());
|
||||||
|
|
||||||
NamingTableVersion0 const& header() const { return *bit_cast<NamingTableVersion0 const*>(m_slice.data()); }
|
|
||||||
|
|
||||||
enum class NameId : u16 {
|
enum class NameId : u16 {
|
||||||
Copyright = 0,
|
Copyright = 0,
|
||||||
FamilyName = 1,
|
FamilyName = 1,
|
||||||
|
@ -404,14 +403,18 @@ private:
|
||||||
TypographicSubfamilyName = 17,
|
TypographicSubfamilyName = 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
Name(ReadonlyBytes slice)
|
Name(NamingTableVersion0 const& naming_table, ReadonlySpan<NameRecord> name_records, ReadonlyBytes string_data)
|
||||||
: m_slice(slice)
|
: m_naming_table(naming_table)
|
||||||
|
, m_name_records(name_records)
|
||||||
|
, m_string_data(string_data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] String string_for_id(NameId) const;
|
[[nodiscard]] String string_for_id(NameId) const;
|
||||||
|
|
||||||
ReadonlyBytes m_slice;
|
NamingTableVersion0 const& m_naming_table;
|
||||||
|
ReadonlySpan<NameRecord> m_name_records;
|
||||||
|
ReadonlyBytes m_string_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/kern
|
// https://learn.microsoft.com/en-us/typography/opentype/spec/kern
|
||||||
|
|
Loading…
Reference in a new issue