GL backend: Properly clip Text that has too many lines for its height

Qt already does that
This commit is contained in:
Olivier Goffart 2021-06-10 10:52:04 +02:00
parent ffb0a9881b
commit 9b8efbf5ad

View file

@ -622,20 +622,22 @@ impl ItemRenderer for GLItemRenderer {
TextVerticalAlignment::bottom => max_height - text_size.height, TextVerticalAlignment::bottom => max_height - text_size.height,
}; };
let mut draw_line = |canvas: &mut femtovg::Canvas<_>, to_draw: &str| { let mut draw_line = |canvas: &mut femtovg::Canvas<_>, to_draw: &str, y: &mut f32| {
let text_metrics = canvas.measure_text(0., 0., to_draw, paint).unwrap(); if *y >= 0. {
let translate_x = match horizontal_alignment { let text_metrics = canvas.measure_text(0., 0., to_draw, paint).unwrap();
TextHorizontalAlignment::left => 0., let translate_x = match horizontal_alignment {
TextHorizontalAlignment::center => max_width / 2. - text_metrics.width() / 2., TextHorizontalAlignment::left => 0.,
TextHorizontalAlignment::right => max_width - text_metrics.width(), TextHorizontalAlignment::center => max_width / 2. - text_metrics.width() / 2.,
}; TextHorizontalAlignment::right => max_width - text_metrics.width(),
canvas.fill_text(translate_x, y, to_draw, paint).unwrap(); };
y += font_metrics.height(); canvas.fill_text(translate_x, *y, to_draw, paint).unwrap();
}
*y += font_metrics.height();
}; };
if wrap { if wrap {
let mut start = 0; let mut start = 0;
while start < string.len() { while start < string.len() && y + font_metrics.height() <= max_height {
let index = canvas.break_text(max_width, &string[start..], paint).unwrap(); let index = canvas.break_text(max_width, &string[start..], paint).unwrap();
if index == 0 { if index == 0 {
// FIXME the word is too big to be shown, but we should still break, ideally // FIXME the word is too big to be shown, but we should still break, ideally
@ -643,12 +645,15 @@ impl ItemRenderer for GLItemRenderer {
} }
let index = start + index; let index = start + index;
// trim is there to remove the \n // trim is there to remove the \n
draw_line(&mut canvas, string[start..index].trim()); draw_line(&mut canvas, string[start..index].trim(), &mut y);
start = index; start = index;
} }
} else { } else {
let elide = text.overflow() == TextOverflow::elide; let elide = text.overflow() == TextOverflow::elide;
'lines: for line in string.lines() { 'lines: for line in string.lines() {
if y + font_metrics.height() > max_height {
break;
}
let text_metrics = canvas.measure_text(0., 0., line, paint).unwrap(); let text_metrics = canvas.measure_text(0., 0., line, paint).unwrap();
if text_metrics.width() > max_width { if text_metrics.width() > max_width {
let w = max_width let w = max_width
@ -664,15 +669,15 @@ impl ItemRenderer for GLItemRenderer {
let txt = &line[..glyph.byte_index]; let txt = &line[..glyph.byte_index];
if elide { if elide {
let elided = format!("{}", txt); let elided = format!("{}", txt);
draw_line(&mut canvas, &elided); draw_line(&mut canvas, &elided, &mut y);
} else { } else {
draw_line(&mut canvas, txt); draw_line(&mut canvas, txt, &mut y);
} }
continue 'lines; continue 'lines;
} }
} }
} }
draw_line(&mut canvas, line); draw_line(&mut canvas, line, &mut y);
} }
} }
} }