diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Cmap.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Cmap.cpp index 7f6b862ccd..88842f80d0 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Cmap.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Cmap.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -180,10 +181,11 @@ u32 Cmap::glyph_id_for_code_point(u32 code_point) const return subtable.glyph_id_for_code_point(code_point); } -Optional Cmap::from_slice(ReadonlyBytes slice) +ErrorOr Cmap::from_slice(ReadonlyBytes slice) { if (slice.size() < (size_t)Sizes::TableHeader) - return {}; + return Error::from_string_literal("Could not load Cmap: Not enough data"); + return Cmap(slice); } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Cmap.h b/Userland/Libraries/LibGfx/Font/OpenType/Cmap.h index 049c356796..d5e4deeb1e 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Cmap.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Cmap.h @@ -93,7 +93,7 @@ public: u16 m_encoding_id { 0 }; }; - static Optional from_slice(ReadonlyBytes); + static ErrorOr from_slice(ReadonlyBytes); u32 num_subtables() const; Optional subtable(u32 index) const; void set_active_index(u32 index) { m_active_index = index; } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index 5420a6fb51..adb4b00682 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -129,16 +129,6 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 Optional opt_fpgm_slice = {}; Optional opt_prep_slice = {}; - Optional opt_head = {}; - Optional opt_name = {}; - Optional opt_hhea = {}; - Optional opt_maxp = {}; - Optional opt_hmtx = {}; - Optional opt_cmap = {}; - Optional opt_os2 = {}; - Optional opt_kern = {}; - Optional opt_fpgm = {}; - Optional opt_prep = {}; Optional cblc; Optional cbdt; Optional gpos; @@ -188,36 +178,33 @@ ErrorOr> Font::try_load_from_offset(ReadonlyBytes buffer, u3 } } - if (!opt_head_slice.has_value() || !(opt_head = Head::from_slice(opt_head_slice.value())).has_value()) - return Error::from_string_literal("Could not load Head"); - auto head = opt_head.value(); + if (!opt_head_slice.has_value()) + return Error::from_string_literal("Font is missing Head"); + auto head = TRY(Head::from_slice(opt_head_slice.value())); - if (!opt_name_slice.has_value() || !(opt_name = Name::from_slice(opt_name_slice.value())).has_value()) - return Error::from_string_literal("Could not load Name"); - auto name = opt_name.value(); + if (!opt_name_slice.has_value()) + return Error::from_string_literal("Font is missing Name"); + auto name = TRY(Name::from_slice(opt_name_slice.value())); - if (!opt_hhea_slice.has_value() || !(opt_hhea = Hhea::from_slice(opt_hhea_slice.value())).has_value()) - return Error::from_string_literal("Could not load Hhea"); - auto hhea = opt_hhea.value(); + if (!opt_hhea_slice.has_value()) + return Error::from_string_literal("Font is missing Hhea"); + auto hhea = TRY(Hhea::from_slice(opt_hhea_slice.value())); - if (!opt_maxp_slice.has_value() || !(opt_maxp = Maxp::from_slice(opt_maxp_slice.value())).has_value()) - return Error::from_string_literal("Could not load Maxp"); - auto maxp = opt_maxp.value(); + if (!opt_maxp_slice.has_value()) + return Error::from_string_literal("Font is missing Maxp"); + auto maxp = TRY(Maxp::from_slice(opt_maxp_slice.value())); - if (!opt_hmtx_slice.has_value() || !(opt_hmtx = Hmtx::from_slice(opt_hmtx_slice.value(), maxp.num_glyphs(), hhea.number_of_h_metrics())).has_value()) - return Error::from_string_literal("Could not load Hmtx"); - auto hmtx = opt_hmtx.value(); + if (!opt_hmtx_slice.has_value()) + return Error::from_string_literal("Font is missing Hmtx"); + auto hmtx = TRY(Hmtx::from_slice(opt_hmtx_slice.value(), maxp.num_glyphs(), hhea.number_of_h_metrics())); - if (!opt_cmap_slice.has_value() || !(opt_cmap = Cmap::from_slice(opt_cmap_slice.value())).has_value()) - return Error::from_string_literal("Could not load Cmap"); - auto cmap = opt_cmap.value(); + if (!opt_cmap_slice.has_value()) + return Error::from_string_literal("Font is missing Cmap"); + auto cmap = TRY(Cmap::from_slice(opt_cmap_slice.value())); Optional loca; - if (opt_loca_slice.has_value()) { - loca = Loca::from_slice(opt_loca_slice.value(), maxp.num_glyphs(), head.index_to_loc_format()); - if (!loca.has_value()) - return Error::from_string_literal("Could not load Loca"); - } + if (opt_loca_slice.has_value()) + loca = TRY(Loca::from_slice(opt_loca_slice.value(), maxp.num_glyphs(), head.index_to_loc_format())); Optional glyf; if (opt_glyf_slice.has_value()) { diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp index 92f7db75c6..1ea8794e5d 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp @@ -176,18 +176,16 @@ Optional Glyf::Glyph::ComponentIterator::n }; } -Optional Loca::from_slice(ReadonlyBytes slice, u32 num_glyphs, IndexToLocFormat index_to_loc_format) +ErrorOr Loca::from_slice(ReadonlyBytes slice, u32 num_glyphs, IndexToLocFormat index_to_loc_format) { switch (index_to_loc_format) { case IndexToLocFormat::Offset16: - if (slice.size() < num_glyphs * 2) { - return {}; - } + if (slice.size() < num_glyphs * 2) + return Error::from_string_literal("Could not load Loca: Not enough data"); break; case IndexToLocFormat::Offset32: - if (slice.size() < num_glyphs * 4) { - return {}; - } + if (slice.size() < num_glyphs * 4) + return Error::from_string_literal("Could not load Loca: Not enough data"); break; } return Loca(slice, num_glyphs, index_to_loc_format); diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.h b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.h index c70c947327..13d201c625 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.h @@ -23,7 +23,7 @@ namespace OpenType { // loca: Index to Location class Loca { public: - static Optional from_slice(ReadonlyBytes, u32 num_glyphs, IndexToLocFormat); + static ErrorOr from_slice(ReadonlyBytes, u32 num_glyphs, IndexToLocFormat); u32 get_glyph_offset(u32 glyph_id) const; private: diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp index 56c3dfd32b..8547072686 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp @@ -26,11 +26,11 @@ static u32 tag_from_str(char const* str) return be_u32((u8 const*)str); } -Optional Head::from_slice(ReadonlyBytes slice) +ErrorOr Head::from_slice(ReadonlyBytes slice) { - if (slice.size() < sizeof(FontHeaderTable)) { - return {}; - } + if (slice.size() < sizeof(FontHeaderTable)) + return Error::from_string_literal("Could not load Head: Not enough data"); + return Head(slice); } @@ -81,11 +81,11 @@ IndexToLocFormat Head::index_to_loc_format() const } } -Optional Hhea::from_slice(ReadonlyBytes slice) +ErrorOr Hhea::from_slice(ReadonlyBytes slice) { - if (slice.size() < sizeof(HorizontalHeaderTable)) { - return {}; - } + if (slice.size() < sizeof(HorizontalHeaderTable)) + return Error::from_string_literal("Could not load Hhea: Not enough data"); + return Hhea(slice); } @@ -114,11 +114,11 @@ u16 Hhea::number_of_h_metrics() const return header().number_of_h_metrics; } -Optional Maxp::from_slice(ReadonlyBytes slice) +ErrorOr Maxp::from_slice(ReadonlyBytes slice) { - if (slice.size() < sizeof(MaximumProfileVersion0_5)) { - return {}; - } + if (slice.size() < sizeof(MaximumProfileVersion0_5)) + return Error::from_string_literal("Could not load Maxp: Not enough data"); + return Maxp(slice); } @@ -127,10 +127,10 @@ u16 Maxp::num_glyphs() const return header().num_glyphs; } -Optional Hmtx::from_slice(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics) +ErrorOr Hmtx::from_slice(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics) { if (slice.size() < number_of_h_metrics * sizeof(LongHorMetric) + (num_glyphs - number_of_h_metrics) * sizeof(u16)) { - return {}; + return Error::from_string_literal("Could not load Hmtx: Not enough data"); } return Hmtx(slice, num_glyphs, number_of_h_metrics); } @@ -153,7 +153,7 @@ GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const }; } -Optional Name::from_slice(ReadonlyBytes slice) +ErrorOr Name::from_slice(ReadonlyBytes slice) { return Name(slice); } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index e4a0e3c978..c49108db95 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -87,7 +87,7 @@ namespace OpenType { // head: Font Header Table class Head { public: - static Optional from_slice(ReadonlyBytes); + static ErrorOr from_slice(ReadonlyBytes); u16 units_per_em() const; i16 xmin() const; i16 ymin() const; @@ -134,7 +134,7 @@ private: // hhea - Horizontal Header Table class Hhea { public: - static Optional from_slice(ReadonlyBytes); + static ErrorOr from_slice(ReadonlyBytes); i16 ascender() const; i16 descender() const; i16 line_gap() const; @@ -175,7 +175,7 @@ private: // Maxp: Maximum Profile class Maxp { public: - static Optional from_slice(ReadonlyBytes); + static ErrorOr from_slice(ReadonlyBytes); u16 num_glyphs() const; @@ -254,7 +254,7 @@ private: // hmtx: Horizontal Metrics Table class Hmtx { public: - static Optional from_slice(ReadonlyBytes, u32 num_glyphs, u32 number_of_h_metrics); + static ErrorOr from_slice(ReadonlyBytes, u32 num_glyphs, u32 number_of_h_metrics); GlyphHorizontalMetrics get_glyph_horizontal_metrics(u32 glyph_id) const; private: @@ -373,7 +373,7 @@ public: enum class WindowsLanguage : u16 { EnglishUnitedStates = 0x0409, }; - static Optional from_slice(ReadonlyBytes); + static ErrorOr from_slice(ReadonlyBytes); String family_name() const { return string_for_id(NameId::FamilyName); } String subfamily_name() const { return string_for_id(NameId::SubfamilyName); }