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

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

This commit is contained in:
Andreas Kling 2022-12-19 17:52:44 +01:00
parent e6551e685d
commit 5d8feab131
3 changed files with 48 additions and 21 deletions

View file

@ -485,7 +485,7 @@ ErrorOr<NonnullRefPtr<Font>> 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<size_t>(OS2::Offsets::End))));
Optional<OS2> 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;
}
}

View file

@ -52,7 +52,7 @@ private:
static ErrorOr<NonnullRefPtr<Font>> 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>&& kern)
Font(ReadonlyBytes bytes, Head&& head, Name&& name, Hhea&& hhea, Maxp&& maxp, Hmtx&& hmtx, Cmap&& cmap, Loca&& loca, Glyf&& glyf, Optional<OS2> os2, Optional<Kern>&& 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<OS2> m_os2;
Optional<Kern> m_kern;
};

View file

@ -35,6 +35,7 @@ struct Version16Dot16 {
using FWord = BigEndian<i16>;
using UFWord = BigEndian<u16>;
using Tag = BigEndian<u32>;
// 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<u16> version;
BigEndian<i16> avg_char_width;
BigEndian<u16> us_weight_class;
BigEndian<u16> us_width_class;
BigEndian<u16> fs_type;
BigEndian<i16> y_subscript_x_size;
BigEndian<i16> y_subscript_y_size;
BigEndian<i16> y_subscript_x_offset;
BigEndian<i16> y_subscript_y_offset;
BigEndian<i16> y_superscript_x_size;
BigEndian<i16> y_superscript_y_size;
BigEndian<i16> y_superscript_x_offset;
BigEndian<i16> y_superscript_y_offset;
BigEndian<i16> y_strikeout_size;
BigEndian<i16> y_strikeout_position;
BigEndian<i16> s_family_class;
u8 panose[10];
BigEndian<u32> ul_unicode_range1;
BigEndian<u32> ul_unicode_range2;
BigEndian<u32> ul_unicode_range3;
BigEndian<u32> ul_unicode_range4;
Tag ach_vend_id;
BigEndian<u16> fs_selection;
BigEndian<u16> fs_first_char_index;
BigEndian<u16> us_last_char_index;
BigEndian<i16> s_typo_ascender;
BigEndian<i16> s_typo_descender;
BigEndian<i16> s_typo_line_gap;
BigEndian<u16> us_win_ascent;
BigEndian<u16> us_win_descent;
};
Version0 const& header() const { return *bit_cast<Version0 const*>(m_slice.data()); }
ReadonlyBytes m_slice;
};