mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 08:17:35 +00:00
LibGfx/OpenType: Load x-height metrics from OS/2 table if available
Before this change we always returned the font's point size as the x-height which was basically never correct. We now get it from the OS/2 table (if one with version >= 2 is available in the file). Otherwise we fall back to using the ascent of the 'x' glyph. Most fonts appear to have a sufficiently modern OS/2 table.
This commit is contained in:
parent
8090adf268
commit
69c33bd4ca
6 changed files with 50 additions and 1 deletions
4
Tests/LibWeb/Layout/expected/css-ex-unit.txt
Normal file
4
Tests/LibWeb/Layout/expected/css-ex-unit.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x177.132812 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x161.132812 children: not-inline
|
||||
BlockContainer <div> at (8,8) content-size 107.421875x161.132812 children: not-inline
|
8
Tests/LibWeb/Layout/input/css-ex-unit.html
Normal file
8
Tests/LibWeb/Layout/input/css-ex-unit.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!doctype html><style>
|
||||
div {
|
||||
font: 20px SerenitySans;
|
||||
width: 10ex;
|
||||
height: 15ex;
|
||||
background: red;
|
||||
}
|
||||
</style><div>
|
|
@ -574,21 +574,28 @@ Gfx::ScaledFontMetrics Font::metrics([[maybe_unused]] float x_scale, float y_sca
|
|||
i16 raw_ascender;
|
||||
i16 raw_descender;
|
||||
i16 raw_line_gap;
|
||||
Optional<i16> x_height;
|
||||
|
||||
if (m_os2.has_value() && m_os2->use_typographic_metrics()) {
|
||||
raw_ascender = m_os2->typographic_ascender();
|
||||
raw_descender = m_os2->typographic_descender();
|
||||
raw_line_gap = m_os2->typographic_line_gap();
|
||||
x_height = m_os2->x_height();
|
||||
} else {
|
||||
raw_ascender = m_hhea.ascender();
|
||||
raw_descender = m_hhea.descender();
|
||||
raw_line_gap = m_hhea.line_gap();
|
||||
}
|
||||
|
||||
if (!x_height.has_value()) {
|
||||
x_height = glyph_metrics(glyph_id_for_code_point('x'), 1, 1, 1, 1).ascender;
|
||||
}
|
||||
|
||||
return Gfx::ScaledFontMetrics {
|
||||
.ascender = static_cast<float>(raw_ascender) * y_scale,
|
||||
.descender = -static_cast<float>(raw_descender) * y_scale,
|
||||
.line_gap = static_cast<float>(raw_line_gap) * y_scale,
|
||||
.x_height = static_cast<float>(x_height.value()) * y_scale,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -854,6 +861,13 @@ bool OS2::use_typographic_metrics() const
|
|||
return header().fs_selection & 0x80;
|
||||
}
|
||||
|
||||
Optional<i16> OS2::x_height() const
|
||||
{
|
||||
if (header().version < 2)
|
||||
return {};
|
||||
return header_v2().sx_height;
|
||||
}
|
||||
|
||||
Optional<ReadonlyBytes> Font::font_program() const
|
||||
{
|
||||
if (m_fpgm.has_value())
|
||||
|
|
|
@ -243,6 +243,8 @@ public:
|
|||
|
||||
bool use_typographic_metrics() const;
|
||||
|
||||
[[nodiscard]] Optional<i16> x_height() const;
|
||||
|
||||
explicit OS2(ReadonlyBytes slice)
|
||||
: m_slice(slice)
|
||||
{
|
||||
|
@ -282,7 +284,27 @@ private:
|
|||
BigEndian<u16> us_win_descent;
|
||||
};
|
||||
|
||||
struct Version1 {
|
||||
Version0 version0;
|
||||
BigEndian<u32> ul_code_page_range1;
|
||||
BigEndian<u32> ul_code_page_range2;
|
||||
};
|
||||
|
||||
struct Version2 {
|
||||
Version1 version1;
|
||||
BigEndian<i16> sx_height;
|
||||
BigEndian<i16> s_cap_height;
|
||||
BigEndian<u16> us_default_char;
|
||||
BigEndian<u16> us_break_char;
|
||||
BigEndian<u16> us_max_context;
|
||||
};
|
||||
|
||||
Version0 const& header() const { return *bit_cast<Version0 const*>(m_slice.data()); }
|
||||
Version2 const& header_v2() const
|
||||
{
|
||||
VERIFY(header().version >= 2);
|
||||
return *bit_cast<Version2 const*>(m_slice.data());
|
||||
}
|
||||
|
||||
ReadonlyBytes m_slice;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ ScaledFont::ScaledFont(NonnullRefPtr<VectorFont> font, float point_width, float
|
|||
|
||||
m_pixel_metrics = Gfx::FontPixelMetrics {
|
||||
.size = (float)pixel_size(),
|
||||
.x_height = (float)x_height(),
|
||||
.x_height = metrics.x_height,
|
||||
.advance_of_ascii_zero = (float)glyph_width('0'),
|
||||
.glyph_spacing = (float)glyph_spacing(),
|
||||
.ascent = metrics.ascender,
|
||||
|
|
|
@ -17,6 +17,7 @@ struct ScaledFontMetrics {
|
|||
float ascender { 0 };
|
||||
float descender { 0 };
|
||||
float line_gap { 0 };
|
||||
float x_height { 0 };
|
||||
|
||||
float height() const
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue