Support max_width and text::Alignment for canvas::Text

This commit is contained in:
Héctor Ramón Jiménez 2025-04-30 04:19:15 +02:00
parent 6ebf386249
commit 97b4ed0d84
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
13 changed files with 139 additions and 127 deletions

View file

@ -58,15 +58,7 @@ impl Cache {
text::to_shaping(key.shaping),
);
let (bounds, has_rtl) = text::measure(&buffer);
if has_rtl {
buffer.set_size(
font_system,
Some(bounds.width),
Some(bounds.height),
);
}
let bounds = text::align(&mut buffer, font_system, key.align_x);
let _ = entry.insert(Entry {
buffer,
@ -123,6 +115,8 @@ pub struct Key<'a> {
pub bounds: Size,
/// The shaping strategy of the text.
pub shaping: text::Shaping,
/// The alignment of the text.
pub align_x: text::Alignment,
}
impl Key<'_> {
@ -134,6 +128,7 @@ impl Key<'_> {
self.bounds.width.to_bits().hash(&mut hasher);
self.bounds.height.to_bits().hash(&mut hasher);
self.shaping.hash(&mut hasher);
self.align_x.hash(&mut hasher);
hasher.finish()
}

View file

@ -89,7 +89,8 @@ impl core::text::Paragraph for Paragraph {
text::to_shaping(text.shaping),
);
let min_bounds = align(&mut buffer, &mut font_system, text.align_x);
let min_bounds =
text::align(&mut buffer, font_system.raw(), text.align_x);
Self(Arc::new(Internal {
buffer,
@ -159,7 +160,8 @@ impl core::text::Paragraph for Paragraph {
None,
);
let min_bounds = align(&mut buffer, &mut font_system, text.align_x);
let min_bounds =
text::align(&mut buffer, font_system.raw(), text.align_x);
Self(Arc::new(Internal {
buffer,
@ -186,8 +188,11 @@ impl core::text::Paragraph for Paragraph {
Some(new_bounds.height),
);
let min_bounds =
align(&mut paragraph.buffer, &mut font_system, paragraph.align_x);
let min_bounds = text::align(
&mut paragraph.buffer,
font_system.raw(),
paragraph.align_x,
);
paragraph.bounds = new_bounds;
paragraph.min_bounds = min_bounds;
@ -357,45 +362,6 @@ impl core::text::Paragraph for Paragraph {
}
}
fn align(
buffer: &mut cosmic_text::Buffer,
font_system: &mut text::FontSystem,
alignment: Alignment,
) -> Size {
let (min_bounds, has_rtl) = text::measure(buffer);
let mut needs_relayout = has_rtl;
if let Some(align) = text::to_align(alignment) {
let has_multiple_lines = buffer.lines.len() > 1
|| buffer.lines.first().is_some_and(|line| {
line.layout_opt().is_some_and(|layout| layout.len() > 1)
});
if has_multiple_lines {
for line in &mut buffer.lines {
let _ = line.set_align(Some(align));
}
needs_relayout = true;
} else if let Some(line) = buffer.lines.first_mut() {
needs_relayout = line.set_align(None);
}
}
// TODO: Avoid relayout with some changes to `cosmic-text` (?)
if needs_relayout {
log::trace!("Relayouting paragraph...");
buffer.set_size(
font_system.raw(),
Some(min_bounds.width),
Some(min_bounds.height),
);
}
min_bounds
}
impl Default for Paragraph {
fn default() -> Self {
Self(Arc::new(Internal::default()))