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
Notes: sideshowbarker 2024-07-17 08:36:27 +09:00
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)
{
if (slice.size() < (size_t)Sizes::Table) {
if (slice.size() < sizeof(FontHeaderTable)) {
return {};
}
return Head(slice);
@ -60,43 +60,42 @@ Optional<Head> Head::from_slice(ReadonlyBytes slice)
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
{
return be_i16(m_slice.offset_pointer((u32)Offsets::XMin));
return header().x_min;
}
i16 Head::ymin() const
{
return be_i16(m_slice.offset_pointer((u32)Offsets::YMin));
return header().y_min;
}
i16 Head::xmax() const
{
return be_i16(m_slice.offset_pointer((u32)Offsets::XMax));
return header().x_max;
}
i16 Head::ymax() const
{
return be_i16(m_slice.offset_pointer((u32)Offsets::YMax));
return header().y_max;
}
u16 Head::style() const
{
return be_u16(m_slice.offset_pointer((u32)Offsets::Style));
return header().mac_style;
}
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
{
i16 raw = be_i16(m_slice.offset_pointer((u32)Offsets::IndexToLocFormat));
switch (raw) {
switch (header().index_to_loc_format) {
case 0:
return IndexToLocFormat::Offset16;
case 1:

View file

@ -19,6 +19,15 @@ enum class IndexToLocFormat {
Offset32,
};
struct Fixed {
BigEndian<u16> integer;
BigEndian<u16> fraction;
};
struct LongDateTime {
BigEndian<u64> value;
};
// https://learn.microsoft.com/en-us/typography/opentype/spec/head
// head: Font Header Table
class Head {
@ -34,20 +43,29 @@ public:
IndexToLocFormat index_to_loc_format() const;
private:
enum class Offsets {
UnitsPerEM = 18,
XMin = 36,
YMin = 38,
XMax = 40,
YMax = 42,
Style = 44,
LowestRecPPEM = 46,
IndexToLocFormat = 50,
};
enum class Sizes {
Table = 54,
struct FontHeaderTable {
BigEndian<u16> major_version;
BigEndian<u16> minor_version;
Fixed font_revision;
BigEndian<u32> checksum_adjustment;
BigEndian<u32> magic_number;
BigEndian<u16> flags;
BigEndian<u16> units_per_em;
LongDateTime created;
LongDateTime modified;
BigEndian<i16> x_min;
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)
: m_slice(slice)
{