diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index 981cecbdf2..8da71fcc67 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -396,6 +396,8 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 Optional opt_glyf_slice = {}; Optional opt_os2_slice = {}; Optional opt_kern_slice = {}; + Optional opt_fpgm_slice = {}; + Optional opt_prep_slice = {}; Optional opt_head = {}; Optional opt_name = {}; @@ -406,6 +408,8 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 Optional opt_loca = {}; Optional opt_os2 = {}; Optional opt_kern = {}; + Optional opt_fpgm = {}; + Optional opt_prep = {}; auto num_tables = be_u16(buffer.offset_pointer(offset + (u32)Offsets::NumTables)); if (buffer.size() < offset + (u32)Sizes::OffsetTable + num_tables * (u32)Sizes::TableRecord) @@ -446,6 +450,10 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 opt_os2_slice = buffer_here; } else if (tag == tag_from_str("kern")) { opt_kern_slice = buffer_here; + } else if (tag == tag_from_str("fpgm")) { + opt_fpgm_slice = buffer_here; + } else if (tag == tag_from_str("prep")) { + opt_prep_slice = buffer_here; } } @@ -489,6 +497,14 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 if (opt_kern_slice.has_value()) kern = TRY(Kern::from_slice(opt_kern_slice.value())); + Optional fpgm; + if (opt_fpgm_slice.has_value()) + fpgm = Fpgm(opt_fpgm_slice.value()); + + Optional prep; + if (opt_prep_slice.has_value()) + prep = Prep(opt_prep_slice.value()); + // Select cmap table. FIXME: Do this better. Right now, just looks for platform "Windows" // and corresponding encoding "Unicode full repertoire", or failing that, "Unicode BMP" for (u32 i = 0; i < cmap.num_subtables(); i++) { @@ -516,7 +532,7 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 } } - return adopt_ref(*new Font(move(buffer), move(head), move(name), move(hhea), move(maxp), move(hmtx), move(cmap), move(loca), move(glyf), move(os2), move(kern))); + return adopt_ref(*new Font(move(buffer), move(head), move(name), move(hhea), move(maxp), move(hmtx), move(cmap), move(loca), move(glyf), move(os2), move(kern), move(fpgm), move(prep))); } Gfx::ScaledFontMetrics Font::metrics([[maybe_unused]] float x_scale, float y_scale) const diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.h b/Userland/Libraries/LibGfx/Font/OpenType/Font.h index e7d3643ad5..d84c7ffac2 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, Optional 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, Optional fpgm, Optional prep) : m_buffer(move(bytes)) , m_head(move(head)) , m_name(move(name)) @@ -64,6 +64,8 @@ private: , m_cmap(move(cmap)) , m_os2(move(os2)) , m_kern(move(kern)) + , m_fpgm(move(fpgm)) + , m_prep(move(prep)) { } @@ -82,6 +84,8 @@ private: Cmap m_cmap; Optional m_os2; Optional m_kern; + Optional m_fpgm; + Optional m_prep; }; } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index 30e29c0d1e..df2e1cbfd8 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -171,6 +171,36 @@ struct GlyphHorizontalMetrics { i16 left_side_bearing; }; +// https://learn.microsoft.com/en-us/typography/opentype/spec/fpgm +// fpgm: Font Program +struct Fpgm { +public: + explicit Fpgm(ReadonlyBytes slice) + : m_slice(slice) + { + } + + ReadonlyBytes program_data() const { return m_slice; } + +private: + ReadonlyBytes m_slice; +}; + +// https://learn.microsoft.com/en-us/typography/opentype/spec/prep +// prep: Control Value Program +struct Prep { +public: + explicit Prep(ReadonlyBytes slice) + : m_slice(slice) + { + } + + ReadonlyBytes program_data() const { return m_slice; } + +private: + ReadonlyBytes m_slice; +}; + // https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx // hmtx: Horizontal Metrics Table class Hmtx {