mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:57:45 +00:00
LibGfx: Use ErrorOr to report failure to load OpenFont tables
This commit is contained in:
parent
1ab03ff963
commit
72483673d2
7 changed files with 51 additions and 64 deletions
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/Error.h>
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <LibGfx/Font/OpenType/Cmap.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);
|
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)
|
if (slice.size() < (size_t)Sizes::TableHeader)
|
||||||
return {};
|
return Error::from_string_literal("Could not load Cmap: Not enough data");
|
||||||
|
|
||||||
return Cmap(slice);
|
return Cmap(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
u16 m_encoding_id { 0 };
|
u16 m_encoding_id { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
static Optional<Cmap> from_slice(ReadonlyBytes);
|
static ErrorOr<Cmap> from_slice(ReadonlyBytes);
|
||||||
u32 num_subtables() const;
|
u32 num_subtables() const;
|
||||||
Optional<Subtable> subtable(u32 index) const;
|
Optional<Subtable> subtable(u32 index) const;
|
||||||
void set_active_index(u32 index) { m_active_index = index; }
|
void set_active_index(u32 index) { m_active_index = index; }
|
||||||
|
|
|
@ -129,16 +129,6 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
|
||||||
Optional<ReadonlyBytes> opt_fpgm_slice = {};
|
Optional<ReadonlyBytes> opt_fpgm_slice = {};
|
||||||
Optional<ReadonlyBytes> opt_prep_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<CBLC> cblc;
|
||||||
Optional<CBDT> cbdt;
|
Optional<CBDT> cbdt;
|
||||||
Optional<GPOS> gpos;
|
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())
|
if (!opt_head_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Head");
|
return Error::from_string_literal("Font is missing Head");
|
||||||
auto head = opt_head.value();
|
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())
|
if (!opt_name_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Name");
|
return Error::from_string_literal("Font is missing Name");
|
||||||
auto name = opt_name.value();
|
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())
|
if (!opt_hhea_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Hhea");
|
return Error::from_string_literal("Font is missing Hhea");
|
||||||
auto hhea = opt_hhea.value();
|
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())
|
if (!opt_maxp_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Maxp");
|
return Error::from_string_literal("Font is missing Maxp");
|
||||||
auto maxp = opt_maxp.value();
|
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())
|
if (!opt_hmtx_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Hmtx");
|
return Error::from_string_literal("Font is missing Hmtx");
|
||||||
auto hmtx = opt_hmtx.value();
|
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())
|
if (!opt_cmap_slice.has_value())
|
||||||
return Error::from_string_literal("Could not load Cmap");
|
return Error::from_string_literal("Font is missing Cmap");
|
||||||
auto cmap = opt_cmap.value();
|
auto cmap = TRY(Cmap::from_slice(opt_cmap_slice.value()));
|
||||||
|
|
||||||
Optional<Loca> loca;
|
Optional<Loca> loca;
|
||||||
if (opt_loca_slice.has_value()) {
|
if (opt_loca_slice.has_value())
|
||||||
loca = Loca::from_slice(opt_loca_slice.value(), maxp.num_glyphs(), head.index_to_loc_format());
|
loca = TRY(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");
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<Glyf> glyf;
|
Optional<Glyf> glyf;
|
||||||
if (opt_glyf_slice.has_value()) {
|
if (opt_glyf_slice.has_value()) {
|
||||||
|
|
|
@ -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) {
|
switch (index_to_loc_format) {
|
||||||
case IndexToLocFormat::Offset16:
|
case IndexToLocFormat::Offset16:
|
||||||
if (slice.size() < num_glyphs * 2) {
|
if (slice.size() < num_glyphs * 2)
|
||||||
return {};
|
return Error::from_string_literal("Could not load Loca: Not enough data");
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case IndexToLocFormat::Offset32:
|
case IndexToLocFormat::Offset32:
|
||||||
if (slice.size() < num_glyphs * 4) {
|
if (slice.size() < num_glyphs * 4)
|
||||||
return {};
|
return Error::from_string_literal("Could not load Loca: Not enough data");
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return Loca(slice, num_glyphs, index_to_loc_format);
|
return Loca(slice, num_glyphs, index_to_loc_format);
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace OpenType {
|
||||||
// loca: Index to Location
|
// loca: Index to Location
|
||||||
class Loca {
|
class Loca {
|
||||||
public:
|
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;
|
u32 get_glyph_offset(u32 glyph_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -26,11 +26,11 @@ static u32 tag_from_str(char const* str)
|
||||||
return be_u32((u8 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)) {
|
if (slice.size() < sizeof(FontHeaderTable))
|
||||||
return {};
|
return Error::from_string_literal("Could not load Head: Not enough data");
|
||||||
}
|
|
||||||
return Head(slice);
|
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)) {
|
if (slice.size() < sizeof(HorizontalHeaderTable))
|
||||||
return {};
|
return Error::from_string_literal("Could not load Hhea: Not enough data");
|
||||||
}
|
|
||||||
return Hhea(slice);
|
return Hhea(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,11 +114,11 @@ u16 Hhea::number_of_h_metrics() const
|
||||||
return header().number_of_h_metrics;
|
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)) {
|
if (slice.size() < sizeof(MaximumProfileVersion0_5))
|
||||||
return {};
|
return Error::from_string_literal("Could not load Maxp: Not enough data");
|
||||||
}
|
|
||||||
return Maxp(slice);
|
return Maxp(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,10 +127,10 @@ u16 Maxp::num_glyphs() const
|
||||||
return header().num_glyphs;
|
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)) {
|
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);
|
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);
|
return Name(slice);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace OpenType {
|
||||||
// head: Font Header Table
|
// head: Font Header Table
|
||||||
class Head {
|
class Head {
|
||||||
public:
|
public:
|
||||||
static Optional<Head> from_slice(ReadonlyBytes);
|
static ErrorOr<Head> from_slice(ReadonlyBytes);
|
||||||
u16 units_per_em() const;
|
u16 units_per_em() const;
|
||||||
i16 xmin() const;
|
i16 xmin() const;
|
||||||
i16 ymin() const;
|
i16 ymin() const;
|
||||||
|
@ -134,7 +134,7 @@ private:
|
||||||
// hhea - Horizontal Header Table
|
// hhea - Horizontal Header Table
|
||||||
class Hhea {
|
class Hhea {
|
||||||
public:
|
public:
|
||||||
static Optional<Hhea> from_slice(ReadonlyBytes);
|
static ErrorOr<Hhea> from_slice(ReadonlyBytes);
|
||||||
i16 ascender() const;
|
i16 ascender() const;
|
||||||
i16 descender() const;
|
i16 descender() const;
|
||||||
i16 line_gap() const;
|
i16 line_gap() const;
|
||||||
|
@ -175,7 +175,7 @@ private:
|
||||||
// Maxp: Maximum Profile
|
// Maxp: Maximum Profile
|
||||||
class Maxp {
|
class Maxp {
|
||||||
public:
|
public:
|
||||||
static Optional<Maxp> from_slice(ReadonlyBytes);
|
static ErrorOr<Maxp> from_slice(ReadonlyBytes);
|
||||||
|
|
||||||
u16 num_glyphs() const;
|
u16 num_glyphs() const;
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ private:
|
||||||
// hmtx: Horizontal Metrics Table
|
// hmtx: Horizontal Metrics Table
|
||||||
class Hmtx {
|
class Hmtx {
|
||||||
public:
|
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;
|
GlyphHorizontalMetrics get_glyph_horizontal_metrics(u32 glyph_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -373,7 +373,7 @@ public:
|
||||||
enum class WindowsLanguage : u16 {
|
enum class WindowsLanguage : u16 {
|
||||||
EnglishUnitedStates = 0x0409,
|
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 family_name() const { return string_for_id(NameId::FamilyName); }
|
||||||
String subfamily_name() const { return string_for_id(NameId::SubfamilyName); }
|
String subfamily_name() const { return string_for_id(NameId::SubfamilyName); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue