aboutsummaryrefslogtreecommitdiffstats
path: root/components/gfx
diff options
context:
space:
mode:
authorAndreu Botella <abotella@igalia.com>2024-05-02 09:17:32 +0200
committerGitHub <noreply@github.com>2024-05-02 07:17:32 +0000
commit8ec5344f70dd1d556cacd72d778924048b0b1154 (patch)
treec75a6ef98c1085cf5f6da9f38c91c3ee573b4038 /components/gfx
parent928214518cc2ed44112295c7aae675fc29f5a50b (diff)
downloadservo-8ec5344f70dd1d556cacd72d778924048b0b1154.tar.gz
servo-8ec5344f70dd1d556cacd72d778924048b0b1154.zip
feat: Support font-relative `ch` and `ic` units (#32171)
* feat: Support font-relative `ch` and `ic` units After #31966, which made it possible for the first time to resolve font-relative CSS units, this change adds support for the `ch` and `ic` units. One difference with the `ex` unit that was added in that PR is that these units must reflect the advance width of a character (the zero digit in the case of `ch`, and the CJK water radical for `ic`) as it would be rendered by the current font group. This means that the size of these units don't only depend on the first available font, in the case where that font does not contain a glyph for that character. This is implemented by adding the advance width for these two characters as optional fields of `FontMetrics`, so the advance width computation happens in advance. Then, when the font metrics are queried as part of unit resolution, the font group is searched for the first font containing that character. This change only implements support for these units in upright typesetting modes, since Servo does not yet have support for vertical writing modes. This means that many of the WPT tests that test for the behavior of these units with vertical writing modes do not pass. This change also makes a number of WPT tests pass, which relied on the `ch` and `ic` units. It, however, also makes the test `/css/css-text/white-space/text-wrap-balance-overflow-002.html` fail, since it tests `text-wrap: balance`, which Servo does not yet implement, and it was only previously passing by chance due to the previous behavior of these units. * Revert Python 3.10-related changes to wss * Fix formatting * Remove test expectation
Diffstat (limited to 'components/gfx')
-rw-r--r--components/gfx/font.rs4
-rw-r--r--components/gfx/platform/freetype/font.rs12
-rw-r--r--components/gfx/platform/macos/font.rs12
-rw-r--r--components/gfx/platform/windows/font.rs11
4 files changed, 34 insertions, 5 deletions
diff --git a/components/gfx/font.rs b/components/gfx/font.rs
index 65c984ed3cb..1921edc1d12 100644
--- a/components/gfx/font.rs
+++ b/components/gfx/font.rs
@@ -131,6 +131,8 @@ pub struct FontMetrics {
pub max_advance: Au,
pub average_advance: Au,
pub line_gap: Au,
+ pub zero_horizontal_advance: Option<Au>,
+ pub ic_horizontal_advance: Option<Au>,
}
impl FontMetrics {
@@ -150,6 +152,8 @@ impl FontMetrics {
max_advance: Au(0),
average_advance: Au(0),
line_gap: Au(0),
+ zero_horizontal_advance: None,
+ ic_horizontal_advance: None,
}
}
}
diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs
index 33bd7be0aa0..f437dbed8c0 100644
--- a/components/gfx/platform/freetype/font.rs
+++ b/components/gfx/platform/freetype/font.rs
@@ -261,10 +261,16 @@ impl PlatformFontMethods for PlatformFont {
x_height = self.font_units_to_au(os2.sx_height as f64);
}
- let average_advance = self
+ let zero_horizontal_advance = self
.glyph_index('0')
.and_then(|idx| self.glyph_h_advance(idx))
- .map_or(max_advance, |advance| self.font_units_to_au(advance));
+ .map(Au::from_f64_px);
+ let ic_horizontal_advance = self
+ .glyph_index('\u{6C34}')
+ .and_then(|idx| self.glyph_h_advance(idx))
+ .map(Au::from_f64_px);
+
+ let average_advance = zero_horizontal_advance.unwrap_or(max_advance);
let metrics = FontMetrics {
underline_size,
@@ -279,6 +285,8 @@ impl PlatformFontMethods for PlatformFont {
max_advance,
average_advance,
line_gap: height,
+ zero_horizontal_advance,
+ ic_horizontal_advance,
};
debug!("Font metrics (@{}px): {:?}", em_size.to_f32_px(), metrics);
diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs
index 7844ecb9089..c6e009ffae8 100644
--- a/components/gfx/platform/macos/font.rs
+++ b/components/gfx/platform/macos/font.rs
@@ -259,11 +259,15 @@ impl PlatformFontMethods for PlatformFont {
let line_gap = (ascent + descent + leading + 0.5).floor();
let max_advance = Au::from_f64_px(self.ctfont.bounding_box().size.width);
- let average_advance = self
+ let zero_horizontal_advance = self
.glyph_index('0')
.and_then(|idx| self.glyph_h_advance(idx))
- .map(Au::from_f64_px)
- .unwrap_or(max_advance);
+ .map(Au::from_f64_px);
+ let ic_horizontal_advance = self
+ .glyph_index('\u{6C34}')
+ .and_then(|idx| self.glyph_h_advance(idx))
+ .map(Au::from_f64_px);
+ let average_advance = zero_horizontal_advance.unwrap_or(max_advance);
let metrics = FontMetrics {
underline_size: Au::from_f64_au(underline_thickness),
@@ -286,6 +290,8 @@ impl PlatformFontMethods for PlatformFont {
max_advance,
average_advance,
line_gap: Au::from_f64_px(line_gap),
+ zero_horizontal_advance,
+ ic_horizontal_advance,
};
debug!(
"Font metrics (@{} pt): {:?}",
diff --git a/components/gfx/platform/windows/font.rs b/components/gfx/platform/windows/font.rs
index ce28d0f378b..5debd0c64fa 100644
--- a/components/gfx/platform/windows/font.rs
+++ b/components/gfx/platform/windows/font.rs
@@ -232,6 +232,15 @@ impl PlatformFontMethods for PlatformFont {
// is pulled out here for clarity
let leading = dm.ascent - dm.capHeight;
+ let zero_horizontal_advance = self
+ .glyph_index('0')
+ .and_then(|idx| self.glyph_h_advance(idx))
+ .map(Au::from_f64_px);
+ let ic_horizontal_advance = self
+ .glyph_index('\u{6C34}')
+ .and_then(|idx| self.glyph_h_advance(idx))
+ .map(Au::from_f64_px);
+
let metrics = FontMetrics {
underline_size: au_from_du(dm.underlineThickness as i32),
underline_offset: au_from_du_s(dm.underlinePosition as i32),
@@ -245,6 +254,8 @@ impl PlatformFontMethods for PlatformFont {
max_advance: au_from_pt(0.0), // FIXME
average_advance: au_from_pt(0.0), // FIXME
line_gap: au_from_du_s((dm.ascent + dm.descent + dm.lineGap as u16) as i32),
+ zero_horizontal_advance,
+ ic_horizontal_advance,
};
debug!("Font metrics (@{} pt): {:?}", self.em_size * 12., metrics);
metrics