From 5d8feab131214cfe4fac31746a4740b8c5489d24 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 19 Dec 2022 17:52:44 +0100 Subject: [PATCH] LibGfx/OpenType: Read "os2" table using a C++ struct --- .../Libraries/LibGfx/Font/OpenType/Font.cpp | 20 ++++----- .../Libraries/LibGfx/Font/OpenType/Font.h | 4 +- .../Libraries/LibGfx/Font/OpenType/Tables.h | 45 +++++++++++++++---- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index d2ab082778..c371e05403 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -485,7 +485,7 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 return Error::from_string_literal("Could not load Glyf"); auto glyf = Glyf(opt_glyf_slice.value()); - OS2 os2(TRY(ByteBuffer::create_zeroed(static_cast(OS2::Offsets::End)))); + Optional os2; if (opt_os2_slice.has_value()) os2 = OS2(opt_os2_slice.value()); @@ -605,8 +605,8 @@ DeprecatedString Font::variant() const u16 Font::weight() const { constexpr u16 bold_bit { 1 }; - if (m_os2.weight_class()) - return m_os2.weight_class(); + if (m_os2.has_value() && m_os2->weight_class()) + return m_os2->weight_class(); if (m_head.style() & bold_bit) return 700; @@ -621,9 +621,9 @@ u8 Font::slope() const // https://docs.microsoft.com/en-us/typography/opentype/spec/head constexpr u16 italic_style_bit { 2 }; - if (m_os2.selection() & oblique_selection_bit) + if (m_os2.has_value() && m_os2->selection() & oblique_selection_bit) return 2; - if (m_os2.selection() & italic_selection_bit) + if (m_os2.has_value() && m_os2->selection() & italic_selection_bit) return 1; if (m_head.style() & italic_style_bit) return 1; @@ -640,27 +640,27 @@ bool Font::is_fixed_width() const u16 OS2::weight_class() const { - return be_u16(m_slice.offset_pointer((u32)Offsets::WeightClass)); + return header().us_weight_class; } u16 OS2::selection() const { - return be_u16(m_slice.offset_pointer((u32)Offsets::Selection)); + return header().fs_selection; } i16 OS2::typographic_ascender() const { - return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicAscender)); + return header().s_typo_ascender; } i16 OS2::typographic_descender() const { - return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicDescender)); + return header().s_typo_descender; } i16 OS2::typographic_line_gap() const { - return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicLineGap)); + return header().s_typo_line_gap; } } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.h b/Userland/Libraries/LibGfx/Font/OpenType/Font.h index 67861c9417..28c15229e6 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.h @@ -52,7 +52,7 @@ private: static ErrorOr> try_load_from_offset(ReadonlyBytes, unsigned index = 0); - Font(ReadonlyBytes bytes, Head&& head, Name&& name, Hhea&& hhea, Maxp&& maxp, Hmtx&& hmtx, Cmap&& cmap, Loca&& loca, Glyf&& glyf, OS2&& os2, Optional&& kern) + Font(ReadonlyBytes bytes, Head&& head, Name&& name, Hhea&& hhea, Maxp&& maxp, Hmtx&& hmtx, Cmap&& cmap, Loca&& loca, Glyf&& glyf, Optional os2, Optional&& kern) : m_buffer(move(bytes)) , m_head(move(head)) , m_name(move(name)) @@ -80,7 +80,7 @@ private: Loca m_loca; Glyf m_glyf; Cmap m_cmap; - OS2 m_os2; + Optional m_os2; Optional m_kern; }; diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index 1668f0e191..59e9ed1d20 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -35,6 +35,7 @@ struct Version16Dot16 { using FWord = BigEndian; using UFWord = BigEndian; +using Tag = BigEndian; // https://learn.microsoft.com/en-us/typography/opentype/spec/head // head: Font Header Table @@ -198,15 +199,6 @@ private: // OS/2: OS/2 and Windows Metrics Table class OS2 { public: - enum class Offsets { - WeightClass = 4, - Selection = 62, - TypographicAscender = 68, - TypographicDescender = 70, - TypographicLineGap = 72, - End = 78, - }; - u16 weight_class() const; u16 selection() const; i16 typographic_ascender() const; @@ -219,6 +211,41 @@ public: } private: + struct Version0 { + BigEndian version; + BigEndian avg_char_width; + BigEndian us_weight_class; + BigEndian us_width_class; + BigEndian fs_type; + BigEndian y_subscript_x_size; + BigEndian y_subscript_y_size; + BigEndian y_subscript_x_offset; + BigEndian y_subscript_y_offset; + BigEndian y_superscript_x_size; + BigEndian y_superscript_y_size; + BigEndian y_superscript_x_offset; + BigEndian y_superscript_y_offset; + BigEndian y_strikeout_size; + BigEndian y_strikeout_position; + BigEndian s_family_class; + u8 panose[10]; + BigEndian ul_unicode_range1; + BigEndian ul_unicode_range2; + BigEndian ul_unicode_range3; + BigEndian ul_unicode_range4; + Tag ach_vend_id; + BigEndian fs_selection; + BigEndian fs_first_char_index; + BigEndian us_last_char_index; + BigEndian s_typo_ascender; + BigEndian s_typo_descender; + BigEndian s_typo_line_gap; + BigEndian us_win_ascent; + BigEndian us_win_descent; + }; + + Version0 const& header() const { return *bit_cast(m_slice.data()); } + ReadonlyBytes m_slice; };