1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:57:45 +00:00

LibGfx/OpenType: Read "head" table using a C++ struct

Instead of fidgeting with offsets and manually reading out big-endian
values, we now declare the "head" table as a C++ struct and use the
BigEndian<T> template to deal with byte order.
This commit is contained in:
Andreas Kling 2022-12-19 13:24:22 +01:00
parent 23638a3b3a
commit 61be11960b
2 changed files with 39 additions and 22 deletions

View file

@ -52,7 +52,7 @@ u32 tag_from_str(char const* str)
Optional<Head> Head::from_slice(ReadonlyBytes slice) Optional<Head> Head::from_slice(ReadonlyBytes slice)
{ {
if (slice.size() < (size_t)Sizes::Table) { if (slice.size() < sizeof(FontHeaderTable)) {
return {}; return {};
} }
return Head(slice); return Head(slice);
@ -60,43 +60,42 @@ Optional<Head> Head::from_slice(ReadonlyBytes slice)
u16 Head::units_per_em() const u16 Head::units_per_em() const
{ {
return be_u16(m_slice.offset_pointer((u32)Offsets::UnitsPerEM)); return header().units_per_em;
} }
i16 Head::xmin() const i16 Head::xmin() const
{ {
return be_i16(m_slice.offset_pointer((u32)Offsets::XMin)); return header().x_min;
} }
i16 Head::ymin() const i16 Head::ymin() const
{ {
return be_i16(m_slice.offset_pointer((u32)Offsets::YMin)); return header().y_min;
} }
i16 Head::xmax() const i16 Head::xmax() const
{ {
return be_i16(m_slice.offset_pointer((u32)Offsets::XMax)); return header().x_max;
} }
i16 Head::ymax() const i16 Head::ymax() const
{ {
return be_i16(m_slice.offset_pointer((u32)Offsets::YMax)); return header().y_max;
} }
u16 Head::style() const u16 Head::style() const
{ {
return be_u16(m_slice.offset_pointer((u32)Offsets::Style)); return header().mac_style;
} }
u16 Head::lowest_recommended_ppem() const u16 Head::lowest_recommended_ppem() const
{ {
return be_u16(m_slice.offset_pointer((u32)Offsets::LowestRecPPEM)); return header().lowest_rec_ppem;
} }
IndexToLocFormat Head::index_to_loc_format() const IndexToLocFormat Head::index_to_loc_format() const
{ {
i16 raw = be_i16(m_slice.offset_pointer((u32)Offsets::IndexToLocFormat)); switch (header().index_to_loc_format) {
switch (raw) {
case 0: case 0:
return IndexToLocFormat::Offset16; return IndexToLocFormat::Offset16;
case 1: case 1:

View file

@ -19,6 +19,15 @@ enum class IndexToLocFormat {
Offset32, Offset32,
}; };
struct Fixed {
BigEndian<u16> integer;
BigEndian<u16> fraction;
};
struct LongDateTime {
BigEndian<u64> value;
};
// 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
class Head { class Head {
@ -34,20 +43,29 @@ public:
IndexToLocFormat index_to_loc_format() const; IndexToLocFormat index_to_loc_format() const;
private: private:
enum class Offsets { struct FontHeaderTable {
UnitsPerEM = 18, BigEndian<u16> major_version;
XMin = 36, BigEndian<u16> minor_version;
YMin = 38, Fixed font_revision;
XMax = 40, BigEndian<u32> checksum_adjustment;
YMax = 42, BigEndian<u32> magic_number;
Style = 44, BigEndian<u16> flags;
LowestRecPPEM = 46, BigEndian<u16> units_per_em;
IndexToLocFormat = 50, LongDateTime created;
}; LongDateTime modified;
enum class Sizes { BigEndian<i16> x_min;
Table = 54, BigEndian<i16> y_min;
BigEndian<i16> x_max;
BigEndian<i16> y_max;
BigEndian<u16> mac_style;
BigEndian<u16> lowest_rec_ppem;
BigEndian<i16> font_direction_hint;
BigEndian<i16> index_to_loc_format;
BigEndian<i16> glyph_data_format;
}; };
FontHeaderTable const& header() const { return *bit_cast<FontHeaderTable const*>(m_slice.data()); }
Head(ReadonlyBytes slice) Head(ReadonlyBytes slice)
: m_slice(slice) : m_slice(slice)
{ {