mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
🐛 Ensure line height is properly handled on line breaks
This commit is contained in:
parent
b40b1fa2e4
commit
eeee52a738
4 changed files with 1306 additions and 113 deletions
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 233 KiB After Width: | Height: | Size: 153 KiB |
|
@ -12,6 +12,7 @@ pub fn render(
|
||||||
.surfaces
|
.surfaces
|
||||||
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
||||||
|
|
||||||
|
let mut offset_y = 0.0;
|
||||||
let container_height = shape.selrect().height();
|
let container_height = shape.selrect().height();
|
||||||
|
|
||||||
for builder in paragraphs {
|
for builder in paragraphs {
|
||||||
|
@ -19,15 +20,19 @@ pub fn render(
|
||||||
skia_paragraph.layout(shape.bounds().width());
|
skia_paragraph.layout(shape.bounds().width());
|
||||||
let paragraph_height: f32 = skia_paragraph.height();
|
let paragraph_height: f32 = skia_paragraph.height();
|
||||||
|
|
||||||
let offset_y = match shape.vertical_align() {
|
let paragraph_offset_y = match shape.vertical_align() {
|
||||||
VerticalAlign::Center => (container_height - paragraph_height) / 2.0,
|
VerticalAlign::Center => (container_height - paragraph_height) / 2.0,
|
||||||
VerticalAlign::Bottom => container_height - paragraph_height,
|
VerticalAlign::Bottom => container_height - paragraph_height,
|
||||||
_ => 0.0,
|
_ => 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
offset_y += paragraph_offset_y;
|
||||||
|
|
||||||
let xy = (shape.selrect().x(), shape.selrect().y() + offset_y);
|
let xy = (shape.selrect().x(), shape.selrect().y() + offset_y);
|
||||||
skia_paragraph.paint(canvas, xy);
|
skia_paragraph.paint(canvas, xy);
|
||||||
|
|
||||||
|
offset_y += paragraph_height;
|
||||||
|
|
||||||
for line_metrics in skia_paragraph.get_line_metrics().iter() {
|
for line_metrics in skia_paragraph.get_line_metrics().iter() {
|
||||||
let style_metrics: Vec<_> = line_metrics
|
let style_metrics: Vec<_> = line_metrics
|
||||||
.get_style_metrics(line_metrics.start_index..line_metrics.end_index)
|
.get_style_metrics(line_metrics.start_index..line_metrics.end_index)
|
||||||
|
@ -38,6 +43,11 @@ pub fn render(
|
||||||
let total_line_width = line_metrics.width as f32;
|
let total_line_width = line_metrics.width as f32;
|
||||||
let total_chars = line_metrics.end_index - line_metrics.start_index;
|
let total_chars = line_metrics.end_index - line_metrics.start_index;
|
||||||
|
|
||||||
|
// No text decoration for empty lines
|
||||||
|
if total_chars == 0 || style_metrics.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (i, (index, style_metric)) in style_metrics.iter().enumerate() {
|
for (i, (index, style_metric)) in style_metrics.iter().enumerate() {
|
||||||
let text_style = style_metric.text_style;
|
let text_style = style_metric.text_style;
|
||||||
let font_metrics = style_metric.font_metrics;
|
let font_metrics = style_metric.font_metrics;
|
||||||
|
|
|
@ -275,6 +275,26 @@ impl Paragraph {
|
||||||
1 => skia::textlayout::TextDirection::RTL,
|
1 => skia::textlayout::TextDirection::RTL,
|
||||||
_ => skia::textlayout::TextDirection::LTR,
|
_ => skia::textlayout::TextDirection::LTR,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Force minimum line height for empty lines using strut style
|
||||||
|
if !self.children.is_empty() {
|
||||||
|
let reference_child = self
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.find(|child| !child.text.trim().is_empty())
|
||||||
|
.unwrap_or(&self.children[0]);
|
||||||
|
|
||||||
|
let mut strut_style = skia::textlayout::StrutStyle::default();
|
||||||
|
strut_style.set_font_size(reference_child.font_size);
|
||||||
|
strut_style.set_height(self.line_height);
|
||||||
|
strut_style.set_height_override(true);
|
||||||
|
strut_style.set_half_leading(false);
|
||||||
|
strut_style.set_leading(0.0);
|
||||||
|
strut_style.set_strut_enabled(true);
|
||||||
|
strut_style.set_force_strut_height(true);
|
||||||
|
style.set_strut_style(strut_style);
|
||||||
|
}
|
||||||
|
|
||||||
style
|
style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +359,7 @@ impl TextLeaf {
|
||||||
style.set_letter_spacing(paragraph.letter_spacing);
|
style.set_letter_spacing(paragraph.letter_spacing);
|
||||||
style.set_height(paragraph.line_height);
|
style.set_height(paragraph.line_height);
|
||||||
style.set_height_override(true);
|
style.set_height_override(true);
|
||||||
|
style.set_half_leading(false);
|
||||||
|
|
||||||
style.set_decoration_type(match self.text_decoration {
|
style.set_decoration_type(match self.text_decoration {
|
||||||
0 => skia::textlayout::TextDecoration::NO_DECORATION,
|
0 => skia::textlayout::TextDecoration::NO_DECORATION,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue