diff options
author | 2024-07-17 22:04:11 +0200 | |
---|---|---|
committer | 2024-07-17 22:04:11 +0200 | |
commit | 910eb72a0620b34e5b3d7793bbd5ab7290e08dd6 (patch) | |
tree | 0a0940d56a9bc4147b7ef06fe9fb5099c761090a /graphics | |
parent | ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f (diff) | |
download | iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.tar.gz iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.tar.bz2 iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.zip |
Implement `rich_text` widget and `markdown` example
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/src/text.rs | 13 | ||||
-rw-r--r-- | graphics/src/text/paragraph.rs | 80 |
2 files changed, 85 insertions, 8 deletions
diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 30269e69..23ec14d4 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -232,13 +232,14 @@ impl PartialEq for Raw { /// Measures the dimensions of the given [`cosmic_text::Buffer`]. pub fn measure(buffer: &cosmic_text::Buffer) -> Size { - let (width, total_lines) = buffer - .layout_runs() - .fold((0.0, 0usize), |(width, total_lines), run| { - (run.line_w.max(width), total_lines + 1) - }); + let (width, height) = + buffer + .layout_runs() + .fold((0.0, 0.0), |(width, height), run| { + (run.line_w.max(width), height + run.line_height) + }); - Size::new(width, total_lines as f32 * buffer.metrics().line_height) + Size::new(width, height) } /// Returns the attributes of the given [`Font`]. diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index ea59c0af..37fa97f2 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -1,7 +1,7 @@ //! Draw paragraphs. use crate::core; use crate::core::alignment; -use crate::core::text::{Hit, Shaping, Text}; +use crate::core::text::{Hit, Shaping, Span, Text}; use crate::core::{Font, Point, Size}; use crate::text; @@ -60,7 +60,7 @@ impl core::text::Paragraph for Paragraph { type Font = Font; fn with_text(text: Text<&str>) -> Self { - log::trace!("Allocating paragraph: {}", text.content); + log::trace!("Allocating plain paragraph: {}", text.content); let mut font_system = text::font_system().write().expect("Write font system"); @@ -100,6 +100,82 @@ impl core::text::Paragraph for Paragraph { })) } + fn with_spans(text: Text<&[Span<'_>]>) -> Self { + log::trace!("Allocating rich paragraph: {:?}", text.content); + + let mut font_system = + text::font_system().write().expect("Write font system"); + + let mut buffer = cosmic_text::Buffer::new( + font_system.raw(), + cosmic_text::Metrics::new( + text.size.into(), + text.line_height.to_absolute(text.size).into(), + ), + ); + + buffer.set_size( + font_system.raw(), + Some(text.bounds.width), + Some(text.bounds.height), + ); + + buffer.set_rich_text( + font_system.raw(), + text.content.iter().map(|span| { + let attrs = cosmic_text::Attrs::new(); + + let attrs = if let Some(font) = span.font { + attrs + .family(text::to_family(font.family)) + .weight(text::to_weight(font.weight)) + .stretch(text::to_stretch(font.stretch)) + .style(text::to_style(font.style)) + } else { + text::to_attributes(text.font) + }; + + let attrs = match (span.size, span.line_height) { + (None, None) => attrs, + _ => { + let size = span.size.unwrap_or(text.size); + + attrs.metrics(cosmic_text::Metrics::new( + size.into(), + span.line_height + .unwrap_or(text.line_height) + .to_absolute(size) + .into(), + )) + } + }; + + let attrs = if let Some(color) = span.color { + attrs.color(text::to_color(color)) + } else { + attrs + }; + + (span.text.as_ref(), attrs) + }), + text::to_attributes(text.font), + text::to_shaping(text.shaping), + ); + + let min_bounds = text::measure(&buffer); + + Self(Arc::new(Internal { + buffer, + font: text.font, + horizontal_alignment: text.horizontal_alignment, + vertical_alignment: text.vertical_alignment, + shaping: text.shaping, + bounds: text.bounds, + min_bounds, + version: font_system.version(), + })) + } + fn resize(&mut self, new_bounds: Size) { let paragraph = Arc::make_mut(&mut self.0); |