From f175679434328fdd9043197ba35ccf03369769cb Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 19 Mar 2024 14:55:12 +0100 Subject: [PATCH] gfx: Derive `line-through` metrics for fonts on MacOS (#31756) There is now platform-specific way to get metrics for `line-through` on MacOS and currently striking through simply does not work. The correct approach here is likely to first search for these metrics in font tables and then falling back to deriving them. Searching the font tables is a larger change, so this change adds the fallback mechanism first. This at least makes sure that strike through renders at all on Mac. In a followup change we can add support for getting metrics via HarfBuzz in a platform-independent way, which is what Gecko does. Fixes #942. --- components/gfx/platform/macos/font.rs | 17 +++++++++++++---- components/layout_2020/display_list/mod.rs | 1 - 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index 764519f8632..0535dbe22cb 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -278,6 +278,9 @@ impl FontHandleMethods for FontHandle { } fn metrics(&self) -> FontMetrics { + // TODO(mrobinson): Gecko first tries to get metrics from the SFNT tables via + // HarfBuzz and only afterward falls back to platform APIs. We should do something + // similar here. This will likely address issue #201 mentioned below. let bounding_rect: CGRect = self.ctfont.bounding_box(); let ascent = self.ctfont.ascent(); let descent = self.ctfont.descent(); @@ -294,18 +297,24 @@ impl FontHandleMethods for FontHandle { .map(Au::from_f64_px) .unwrap_or(max_advance); + let underline_size = au_from_pt(self.ctfont.underline_thickness()); + let x_height = au_from_pt(self.ctfont.x_height() * scale); + let metrics = FontMetrics { - underline_size: au_from_pt(self.ctfont.underline_thickness()), + underline_size, // TODO(Issue #201): underline metrics are not reliable. Have to pull out of font table // directly. // // see also: https://bugs.webkit.org/show_bug.cgi?id=16768 // see also: https://bugreports.qt-project.org/browse/QTBUG-13364 underline_offset: au_from_pt(self.ctfont.underline_position()), - strikeout_size: Au(0), // FIXME(Issue #942) - strikeout_offset: Au(0), // FIXME(Issue #942) + // There is no way to get these from CoreText or CoreGraphics APIs, so + // derive them from the other font metrics. These should eventually be + // found in the font tables directly when #201 is fixed. + strikeout_size: underline_size, + strikeout_offset: x_height.scale_by(0.5) + underline_size.scale_by(0.5), leading: au_from_pt(leading), - x_height: au_from_pt(self.ctfont.x_height() * scale), + x_height, em_size, ascent: au_from_pt(ascent * scale), descent: au_from_pt(descent * scale), diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 86e70481e0c..0a04908ce9b 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -428,7 +428,6 @@ impl Fragment { { let mut rect = rect; rect.origin.y += Length::from(font_metrics.ascent - font_metrics.strikeout_offset); - // XXX(ferjm) This does not work on MacOS #942 rect.size.height = Length::new(font_metrics.strikeout_size.to_nearest_pixel(dppx)); self.build_display_list_for_text_decoration(fragment, builder, &rect, &color); }