mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:47:35 +00:00
LibTTF: Parse OS/2 tables
The OS/2 table contains nice typographic ascent/descent information.
This commit is contained in:
parent
3b1e05f714
commit
e984200206
3 changed files with 48 additions and 2 deletions
|
@ -274,6 +274,7 @@ Result<NonnullRefPtr<Font>, String> Font::try_load_from_offset(ReadonlyBytes buf
|
||||||
Optional<ReadonlyBytes> opt_cmap_slice = {};
|
Optional<ReadonlyBytes> opt_cmap_slice = {};
|
||||||
Optional<ReadonlyBytes> opt_loca_slice = {};
|
Optional<ReadonlyBytes> opt_loca_slice = {};
|
||||||
Optional<ReadonlyBytes> opt_glyf_slice = {};
|
Optional<ReadonlyBytes> opt_glyf_slice = {};
|
||||||
|
Optional<ReadonlyBytes> opt_os2_slice = {};
|
||||||
|
|
||||||
Optional<Head> opt_head = {};
|
Optional<Head> opt_head = {};
|
||||||
Optional<Name> opt_name = {};
|
Optional<Name> opt_name = {};
|
||||||
|
@ -282,6 +283,7 @@ Result<NonnullRefPtr<Font>, String> Font::try_load_from_offset(ReadonlyBytes buf
|
||||||
Optional<Hmtx> opt_hmtx = {};
|
Optional<Hmtx> opt_hmtx = {};
|
||||||
Optional<Cmap> opt_cmap = {};
|
Optional<Cmap> opt_cmap = {};
|
||||||
Optional<Loca> opt_loca = {};
|
Optional<Loca> opt_loca = {};
|
||||||
|
Optional<OS2> opt_os2 = {};
|
||||||
|
|
||||||
auto num_tables = be_u16(buffer.offset_pointer(offset + (u32)Offsets::NumTables));
|
auto num_tables = be_u16(buffer.offset_pointer(offset + (u32)Offsets::NumTables));
|
||||||
if (buffer.size() < offset + (u32)Sizes::OffsetTable + num_tables * (u32)Sizes::TableRecord)
|
if (buffer.size() < offset + (u32)Sizes::OffsetTable + num_tables * (u32)Sizes::TableRecord)
|
||||||
|
@ -318,6 +320,8 @@ Result<NonnullRefPtr<Font>, String> Font::try_load_from_offset(ReadonlyBytes buf
|
||||||
opt_loca_slice = buffer_here;
|
opt_loca_slice = buffer_here;
|
||||||
} else if (tag == tag_from_str("glyf")) {
|
} else if (tag == tag_from_str("glyf")) {
|
||||||
opt_glyf_slice = buffer_here;
|
opt_glyf_slice = buffer_here;
|
||||||
|
} else if (tag == tag_from_str("OS/2")) {
|
||||||
|
opt_os2_slice = buffer_here;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,6 +357,10 @@ Result<NonnullRefPtr<Font>, String> Font::try_load_from_offset(ReadonlyBytes buf
|
||||||
return String { "Could not load Glyf" };
|
return String { "Could not load Glyf" };
|
||||||
auto glyf = Glyf(opt_glyf_slice.value());
|
auto glyf = Glyf(opt_glyf_slice.value());
|
||||||
|
|
||||||
|
if (!opt_os2_slice.has_value())
|
||||||
|
return String { "Could not load OS/2" };
|
||||||
|
auto os2 = OS2(opt_os2_slice.value());
|
||||||
|
|
||||||
// Select cmap table. FIXME: Do this better. Right now, just looks for platform "Windows"
|
// 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"
|
// and corresponding encoding "Unicode full repertoire", or failing that, "Unicode BMP"
|
||||||
for (u32 i = 0; i < cmap.num_subtables(); i++) {
|
for (u32 i = 0; i < cmap.num_subtables(); i++) {
|
||||||
|
@ -373,7 +381,7 @@ Result<NonnullRefPtr<Font>, String> Font::try_load_from_offset(ReadonlyBytes buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return adopt_ref(*new Font(move(buffer), move(head), move(name), move(hhea), move(maxp), move(hmtx), move(cmap), move(loca), move(glyf)));
|
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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaledFontMetrics Font::metrics(float x_scale, float y_scale) const
|
ScaledFontMetrics Font::metrics(float x_scale, float y_scale) const
|
||||||
|
@ -551,4 +559,19 @@ u8 ScaledFont::glyph_fixed_width() const
|
||||||
return glyph_metrics(glyph_id_for_code_point(' ')).advance_width;
|
return glyph_metrics(glyph_id_for_code_point(' ')).advance_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i16 OS2::typographic_ascender() const
|
||||||
|
{
|
||||||
|
return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicAscender));
|
||||||
|
}
|
||||||
|
|
||||||
|
i16 OS2::typographic_descender() const
|
||||||
|
{
|
||||||
|
return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicDescender));
|
||||||
|
}
|
||||||
|
|
||||||
|
i16 OS2::typographic_line_gap() const
|
||||||
|
{
|
||||||
|
return be_i16(m_slice.offset_pointer((u32)Offsets::TypographicLineGap));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ private:
|
||||||
|
|
||||||
static Result<NonnullRefPtr<Font>, String> try_load_from_offset(ReadonlyBytes, unsigned index = 0);
|
static Result<NonnullRefPtr<Font>, String> 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)
|
Font(ReadonlyBytes bytes, Head&& head, Name&& name, Hhea&& hhea, Maxp&& maxp, Hmtx&& hmtx, Cmap&& cmap, Loca&& loca, Glyf&& glyf, OS2&& os2)
|
||||||
: m_buffer(move(bytes))
|
: m_buffer(move(bytes))
|
||||||
, m_head(move(head))
|
, m_head(move(head))
|
||||||
, m_name(move(name))
|
, m_name(move(name))
|
||||||
|
@ -83,6 +83,7 @@ private:
|
||||||
, m_loca(move(loca))
|
, m_loca(move(loca))
|
||||||
, m_glyf(move(glyf))
|
, m_glyf(move(glyf))
|
||||||
, m_cmap(move(cmap))
|
, m_cmap(move(cmap))
|
||||||
|
, m_os2(move(os2))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +100,7 @@ private:
|
||||||
Loca m_loca;
|
Loca m_loca;
|
||||||
Glyf m_glyf;
|
Glyf m_glyf;
|
||||||
Cmap m_cmap;
|
Cmap m_cmap;
|
||||||
|
OS2 m_os2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScaledFont : public Gfx::Font {
|
class ScaledFont : public Gfx::Font {
|
||||||
|
|
|
@ -126,6 +126,27 @@ private:
|
||||||
u32 m_number_of_h_metrics { 0 };
|
u32 m_number_of_h_metrics { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OS2 {
|
||||||
|
public:
|
||||||
|
enum class Offsets {
|
||||||
|
TypographicAscender = 68,
|
||||||
|
TypographicDescender = 70,
|
||||||
|
TypographicLineGap = 72,
|
||||||
|
};
|
||||||
|
|
||||||
|
i16 typographic_ascender() const;
|
||||||
|
i16 typographic_descender() const;
|
||||||
|
i16 typographic_line_gap() const;
|
||||||
|
|
||||||
|
explicit OS2(ReadonlyBytes const& slice)
|
||||||
|
: m_slice(slice)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReadonlyBytes m_slice;
|
||||||
|
};
|
||||||
|
|
||||||
class Name {
|
class Name {
|
||||||
public:
|
public:
|
||||||
enum class Platform {
|
enum class Platform {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue