diff --git a/parley/src/layout/line/greedy.rs b/parley/src/layout/line/greedy.rs index d8a2793a..bead6738 100644 --- a/parley/src/layout/line/greedy.rs +++ b/parley/src/layout/line/greedy.rs @@ -472,6 +472,7 @@ impl<'a, B: Brush> BreakLines<'a, B> { // Default vertical alignment is to align the bottom of boxes with the text baseline. // This is equivalent to the entire height of the box being "ascent" line.metrics.ascent = line.metrics.ascent.max(item.height); + line.metrics.line_height = line.metrics.line_height.max(item.height); // Mark us as having seen non-whitespace content on this line have_metrics = true; @@ -504,12 +505,10 @@ impl<'a, B: Brush> BreakLines<'a, B> { // Compute the run's vertical metrics let run = &self.layout.runs[line_item.index]; let line_height = line_item.compute_line_height(self.layout); - line.metrics.ascent = - line.metrics.ascent.max(run.metrics.ascent * line_height); - line.metrics.descent = - line.metrics.descent.max(run.metrics.descent * line_height); - line.metrics.leading = - line.metrics.leading.max(run.metrics.leading * line_height); + line.metrics.line_height = line.metrics.line_height.max(line_height); + line.metrics.ascent = line.metrics.ascent.max(run.metrics.ascent); + line.metrics.descent = line.metrics.descent.max(run.metrics.descent); + line.metrics.leading = line.metrics.leading.max(run.metrics.leading); // Mark us as having seen non-whitespace content on this line have_metrics = true; @@ -559,7 +558,9 @@ impl<'a, B: Brush> BreakLines<'a, B> { // Round block/vertical axis metrics line.metrics.ascent = line.metrics.ascent.round(); line.metrics.descent = line.metrics.descent.round(); - line.metrics.leading = (line.metrics.leading * 0.5).round() * 2.; + line.metrics.line_height = line.metrics.line_height.round(); + line.metrics.leading = + line.metrics.line_height - (line.metrics.ascent + line.metrics.descent); // Compute let above = (line.metrics.ascent + line.metrics.leading * 0.5).round(); diff --git a/parley/src/layout/line/mod.rs b/parley/src/layout/line/mod.rs index 7943c47d..eaf15f3b 100644 --- a/parley/src/layout/line/mod.rs +++ b/parley/src/layout/line/mod.rs @@ -90,6 +90,9 @@ pub struct LineMetrics { pub descent: f32, /// Typographic leading. pub leading: f32, + /// The absolute line height (in layout units). + /// It matches the CSS definition of line height where it is derived as a multiple of the font size. + pub line_height: f32, /// Offset to the baseline. pub baseline: f32, /// Offset for alignment. @@ -101,9 +104,9 @@ pub struct LineMetrics { } impl LineMetrics { - /// Returns the size of the line (ascent + descent + leading). + /// Returns the size of the line pub fn size(&self) -> f32 { - self.ascent + self.descent + self.leading + self.line_height } } diff --git a/parley/src/layout/mod.rs b/parley/src/layout/mod.rs index 2f9f145f..b592be60 100644 --- a/parley/src/layout/mod.rs +++ b/parley/src/layout/mod.rs @@ -197,7 +197,7 @@ pub struct Style { pub underline: Option>, /// Strikethrough decoration. pub strikethrough: Option>, - /// Multiplicative line height factor. + /// Absolute line height in layout units (style line_height * font_size) pub(crate) line_height: f32, } diff --git a/parley/src/resolve/mod.rs b/parley/src/resolve/mod.rs index 6e720c3f..aad89632 100644 --- a/parley/src/resolve/mod.rs +++ b/parley/src/resolve/mod.rs @@ -423,7 +423,7 @@ impl ResolvedStyle { brush: self.brush.clone(), underline: self.underline.as_layout_decoration(&self.brush), strikethrough: self.strikethrough.as_layout_decoration(&self.brush), - line_height: self.line_height, + line_height: self.line_height * self.font_size, } } }