From 61be11960b901d7cc159db135b0c5bb484f40002 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 19 Dec 2022 13:24:22 +0100 Subject: [PATCH] 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 template to deal with byte order. --- .../Libraries/LibGfx/Font/OpenType/Font.cpp | 19 ++++----- .../Libraries/LibGfx/Font/OpenType/Tables.h | 42 +++++++++++++------ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index 1f1de38e640..7ccab56f726 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -52,7 +52,7 @@ u32 tag_from_str(char const* str) Optional 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::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: diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index eabd18b48a0..d49dd53deb2 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -19,6 +19,15 @@ enum class IndexToLocFormat { Offset32, }; +struct Fixed { + BigEndian integer; + BigEndian fraction; +}; + +struct LongDateTime { + BigEndian 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 major_version; + BigEndian minor_version; + Fixed font_revision; + BigEndian checksum_adjustment; + BigEndian magic_number; + BigEndian flags; + BigEndian units_per_em; + LongDateTime created; + LongDateTime modified; + BigEndian x_min; + BigEndian y_min; + BigEndian x_max; + BigEndian y_max; + BigEndian mac_style; + BigEndian lowest_rec_ppem; + BigEndian font_direction_hint; + BigEndian index_to_loc_format; + BigEndian glyph_data_format; }; + FontHeaderTable const& header() const { return *bit_cast(m_slice.data()); } + Head(ReadonlyBytes slice) : m_slice(slice) {