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

LibGfx: Use ErrorOr to report failure to load OpenFont tables

This commit is contained in:
Sam Atkins 2023-10-21 17:33:46 +01:00 committed by Andreas Kling
parent 1ab03ff963
commit 72483673d2
7 changed files with 51 additions and 64 deletions

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Error.h>
#include <AK/Format.h>
#include <AK/Optional.h>
#include <LibGfx/Font/OpenType/Cmap.h>
@ -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> Cmap::from_slice(ReadonlyBytes slice)
ErrorOr<Cmap> 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);
}

View file

@ -93,7 +93,7 @@ public:
u16 m_encoding_id { 0 };
};
static Optional<Cmap> from_slice(ReadonlyBytes);
static ErrorOr<Cmap> from_slice(ReadonlyBytes);
u32 num_subtables() const;
Optional<Subtable> subtable(u32 index) const;
void set_active_index(u32 index) { m_active_index = index; }

View file

@ -129,16 +129,6 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
Optional<ReadonlyBytes> opt_fpgm_slice = {};
Optional<ReadonlyBytes> opt_prep_slice = {};
Optional<Head> opt_head = {};
Optional<Name> opt_name = {};
Optional<Hhea> opt_hhea = {};
Optional<Maxp> opt_maxp = {};
Optional<Hmtx> opt_hmtx = {};
Optional<Cmap> opt_cmap = {};
Optional<OS2> opt_os2 = {};
Optional<Kern> opt_kern = {};
Optional<Fpgm> opt_fpgm = {};
Optional<Prep> opt_prep = {};
Optional<CBLC> cblc;
Optional<CBDT> cbdt;
Optional<GPOS> gpos;
@ -188,36 +178,33 @@ ErrorOr<NonnullRefPtr<Font>> 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> 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> glyf;
if (opt_glyf_slice.has_value()) {

View file

@ -176,18 +176,16 @@ Optional<Glyf::Glyph::ComponentIterator::Item> Glyf::Glyph::ComponentIterator::n
};
}
Optional<Loca> Loca::from_slice(ReadonlyBytes slice, u32 num_glyphs, IndexToLocFormat index_to_loc_format)
ErrorOr<Loca> 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);

View file

@ -23,7 +23,7 @@ namespace OpenType {
// loca: Index to Location
class Loca {
public:
static Optional<Loca> from_slice(ReadonlyBytes, u32 num_glyphs, IndexToLocFormat);
static ErrorOr<Loca> from_slice(ReadonlyBytes, u32 num_glyphs, IndexToLocFormat);
u32 get_glyph_offset(u32 glyph_id) const;
private:

View file

@ -26,11 +26,11 @@ static u32 tag_from_str(char const* str)
return be_u32((u8 const*)str);
}
Optional<Head> Head::from_slice(ReadonlyBytes slice)
ErrorOr<Head> 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> Hhea::from_slice(ReadonlyBytes slice)
ErrorOr<Hhea> 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> Maxp::from_slice(ReadonlyBytes slice)
ErrorOr<Maxp> 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> Hmtx::from_slice(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics)
ErrorOr<Hmtx> 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> Name::from_slice(ReadonlyBytes slice)
ErrorOr<Name> Name::from_slice(ReadonlyBytes slice)
{
return Name(slice);
}

View file

@ -87,7 +87,7 @@ namespace OpenType {
// head: Font Header Table
class Head {
public:
static Optional<Head> from_slice(ReadonlyBytes);
static ErrorOr<Head> 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<Hhea> from_slice(ReadonlyBytes);
static ErrorOr<Hhea> 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<Maxp> from_slice(ReadonlyBytes);
static ErrorOr<Maxp> from_slice(ReadonlyBytes);
u16 num_glyphs() const;
@ -254,7 +254,7 @@ private:
// hmtx: Horizontal Metrics Table
class Hmtx {
public:
static Optional<Hmtx> from_slice(ReadonlyBytes, u32 num_glyphs, u32 number_of_h_metrics);
static ErrorOr<Hmtx> 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<Name> from_slice(ReadonlyBytes);
static ErrorOr<Name> from_slice(ReadonlyBytes);
String family_name() const { return string_for_id(NameId::FamilyName); }
String subfamily_name() const { return string_for_id(NameId::SubfamilyName); }