From ddcf02f9d0377afe6a35dbbb09a29b4bd52efe2e Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Tue, 23 Jul 2024 13:36:40 -0700 Subject: Add background styling to span / rich text --- core/src/renderer/null.rs | 4 ++++ core/src/text.rs | 39 ++++++++++++++++++++++++++++++- core/src/text/paragraph.rs | 6 ++++- examples/markdown/src/main.rs | 9 ++++--- graphics/src/text/paragraph.rs | 53 +++++++++++++++++++++++++++++++++++++++++- widget/src/markdown.rs | 24 ++++++++++++------- widget/src/text/rich.rs | 22 ++++++++++++++++-- 7 files changed, 141 insertions(+), 16 deletions(-) diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index d8d3c50a..5c7513c6 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -111,6 +111,10 @@ impl text::Paragraph for () { fn hit_span(&self, _point: Point) -> Option { None } + + fn span_bounds(&self, _index: usize) -> Vec { + vec![] + } } impl text::Editor for () { diff --git a/core/src/text.rs b/core/src/text.rs index aa24d85f..0bdc6851 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -8,7 +8,7 @@ pub use highlighter::Highlighter; pub use paragraph::Paragraph; use crate::alignment; -use crate::{Color, Pixels, Point, Rectangle, Size}; +use crate::{Border, Color, Pixels, Point, Rectangle, Size}; use std::borrow::Cow; use std::hash::{Hash, Hasher}; @@ -235,6 +235,8 @@ pub struct Span<'a, Link = (), Font = crate::Font> { pub font: Option, /// The [`Color`] of the [`Span`]. pub color: Option, + /// The [`Background`] of the [`Span`]. + pub background: Option, /// The link of the [`Span`]. pub link: Option, } @@ -248,6 +250,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> { line_height: None, font: None, color: None, + background: None, link: None, } } @@ -288,6 +291,21 @@ impl<'a, Link, Font> Span<'a, Link, Font> { self } + /// Sets the [`Background`] of the [`Span`]. + pub fn background(mut self, background: impl Into) -> Self { + self.background = Some(background.into()); + self + } + + /// Sets the [`Background`] of the [`Span`], if any. + pub fn background_maybe( + mut self, + background: Option>, + ) -> Self { + self.background = background.map(Into::into); + self + } + /// Sets the link of the [`Span`]. pub fn link(mut self, link: impl Into) -> Self { self.link = Some(link.into()); @@ -308,6 +326,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> { line_height: self.line_height, font: self.font, color: self.color, + background: self.background, link: self.link, } } @@ -406,3 +425,21 @@ into_fragment!(isize); into_fragment!(f32); into_fragment!(f64); + +/// The background style of text +#[derive(Debug, Clone, Copy)] +pub struct Background { + /// The background [`Color`] + pub color: Color, + /// The background [`Border`] + pub border: Border, +} + +impl From for Background { + fn from(color: Color) -> Self { + Background { + color, + border: Border::default(), + } + } +} diff --git a/core/src/text/paragraph.rs b/core/src/text/paragraph.rs index 26650793..04a97f35 100644 --- a/core/src/text/paragraph.rs +++ b/core/src/text/paragraph.rs @@ -1,7 +1,7 @@ //! Draw paragraphs. use crate::alignment; use crate::text::{Difference, Hit, Span, Text}; -use crate::{Point, Size}; +use crate::{Point, Rectangle, Size}; /// A text paragraph. pub trait Paragraph: Sized + Default { @@ -42,6 +42,10 @@ pub trait Paragraph: Sized + Default { /// that was hit. fn hit_span(&self, point: Point) -> Option; + /// Returns all bounds for the provided [`Span`] index of the [`Paragraph`]. + /// A [`Span`] can have multiple bounds for each line it's on. + fn span_bounds(&self, index: usize) -> Vec; + /// Returns the distance to the given grapheme index in the [`Paragraph`]. fn grapheme_position(&self, line: usize, index: usize) -> Option; diff --git a/examples/markdown/src/main.rs b/examples/markdown/src/main.rs index 173cb389..db40d0b9 100644 --- a/examples/markdown/src/main.rs +++ b/examples/markdown/src/main.rs @@ -28,8 +28,11 @@ impl Markdown { ( Self { content: text_editor::Content::with_text(INITIAL_CONTENT), - items: markdown::parse(INITIAL_CONTENT, theme.palette()) - .collect(), + items: markdown::parse( + INITIAL_CONTENT, + theme.extended_palette(), + ) + .collect(), theme, }, widget::focus_next(), @@ -46,7 +49,7 @@ impl Markdown { if is_edit { self.items = markdown::parse( &self.content.text(), - self.theme.palette(), + self.theme.extended_palette(), ) .collect(); } diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index da703ceb..540e669b 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -2,7 +2,7 @@ use crate::core; use crate::core::alignment; use crate::core::text::{Hit, Shaping, Span, Text}; -use crate::core::{Font, Point, Size}; +use crate::core::{Font, Point, Rectangle, Size}; use crate::text; use std::fmt; @@ -251,6 +251,57 @@ impl core::text::Paragraph for Paragraph { Some(glyph.metadata) } + fn span_bounds(&self, index: usize) -> Vec { + let internal = self.internal(); + + let mut current_bounds = None; + + let mut bounds = internal + .buffer + .layout_runs() + .flat_map(|run| { + let line_top = run.line_top; + let line_height = run.line_height; + + run.glyphs + .iter() + .map(move |glyph| (line_top, line_height, glyph)) + }) + .skip_while(|(_, _, glyph)| glyph.metadata != index) + .take_while(|(_, _, glyph)| glyph.metadata == index) + .fold(vec![], |mut spans, (line_top, line_height, glyph)| { + let y = line_top + glyph.y; + + let new_bounds = || { + Rectangle::new( + Point::new(glyph.x, y), + Size::new( + glyph.w, + glyph.line_height_opt.unwrap_or(line_height), + ), + ) + }; + + match current_bounds.as_mut() { + None => { + current_bounds = Some(new_bounds()); + } + Some(bounds) if y != bounds.y => { + spans.push(*bounds); + *bounds = new_bounds(); + } + Some(bounds) => { + bounds.width += glyph.w; + } + } + + spans + }); + + bounds.extend(current_bounds); + bounds + } + fn grapheme_position(&self, line: usize, index: usize) -> Option { use unicode_segmentation::UnicodeSegmentation; diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index 9cfd3c33..6cd8535e 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -4,9 +4,12 @@ //! in code blocks. //! //! Only the variants of [`Item`] are currently supported. +use crate::core::border; use crate::core::font::{self, Font}; use crate::core::padding; -use crate::core::theme::{self, Theme}; +use crate::core::text::Background; +use crate::core::theme::palette; +use crate::core::theme::Theme; use crate::core::{self, Element, Length, Pixels}; use crate::{column, container, rich_text, row, scrollable, span, text}; @@ -34,10 +37,10 @@ pub enum Item { } /// Parse the given Markdown content. -pub fn parse( - markdown: &str, - palette: theme::Palette, -) -> impl Iterator + '_ { +pub fn parse<'a>( + markdown: &'a str, + palette: &'a palette::Extended, +) -> impl Iterator + 'a { struct List { start: Option, items: Vec>, @@ -247,7 +250,7 @@ pub fn parse( }; let span = if let Some(link) = link.as_ref() { - span.color(palette.primary).link(link.clone()) + span.color(palette.primary.base.color).link(link.clone()) } else { span }; @@ -257,10 +260,15 @@ pub fn parse( None } pulldown_cmark::Event::Code(code) if !metadata && !table => { - let span = span(code.into_string()).font(Font::MONOSPACE); + let span = span(code.into_string()) + .font(Font::MONOSPACE) + .background(Background { + color: palette.background.weak.color, + border: border::rounded(2), + }); let span = if let Some(link) = link.as_ref() { - span.color(palette.primary).link(link.clone()) + span.color(palette.primary.base.color).link(link.clone()) } else { span }; diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index 9c0e2fac..832a3ae7 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -9,8 +9,8 @@ use crate::core::widget::text::{ }; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Clipboard, Color, Element, Event, Layout, Length, Pixels, Rectangle, - Shell, Size, Widget, + self, Clipboard, Color, Element, Event, Layout, Length, Pixels, Point, + Rectangle, Shell, Size, Widget, }; use std::borrow::Cow; @@ -246,6 +246,24 @@ where let style = theme.style(&self.class); + // Draw backgrounds + for (index, span) in self.spans.iter().enumerate() { + if let Some(background) = span.background { + let translation = layout.position() - Point::ORIGIN; + + for bounds in state.paragraph.span_bounds(index) { + renderer.fill_quad( + renderer::Quad { + bounds: bounds + translation, + border: background.border, + ..Default::default() + }, + background.color, + ); + } + } + } + text::draw( renderer, defaults, -- cgit From 4dc7b9b9619010b50ec6df837bd945ff0f675781 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 13:15:04 +0200 Subject: Use dark background for inline code in `markdown` widget --- examples/markdown/src/main.rs | 9 +++------ widget/src/markdown.rs | 14 +++++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/markdown/src/main.rs b/examples/markdown/src/main.rs index db40d0b9..efe5b324 100644 --- a/examples/markdown/src/main.rs +++ b/examples/markdown/src/main.rs @@ -28,11 +28,8 @@ impl Markdown { ( Self { content: text_editor::Content::with_text(INITIAL_CONTENT), - items: markdown::parse( - INITIAL_CONTENT, - theme.extended_palette(), - ) - .collect(), + items: markdown::parse(INITIAL_CONTENT, &theme.palette()) + .collect(), theme, }, widget::focus_next(), @@ -49,7 +46,7 @@ impl Markdown { if is_edit { self.items = markdown::parse( &self.content.text(), - self.theme.extended_palette(), + &self.theme.palette(), ) .collect(); } diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index 6cd8535e..362aba67 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -8,9 +8,8 @@ use crate::core::border; use crate::core::font::{self, Font}; use crate::core::padding; use crate::core::text::Background; -use crate::core::theme::palette; -use crate::core::theme::Theme; -use crate::core::{self, Element, Length, Pixels}; +use crate::core::theme::{self, Theme}; +use crate::core::{self, color, Color, Element, Length, Pixels}; use crate::{column, container, rich_text, row, scrollable, span, text}; pub use pulldown_cmark::HeadingLevel; @@ -39,7 +38,7 @@ pub enum Item { /// Parse the given Markdown content. pub fn parse<'a>( markdown: &'a str, - palette: &'a palette::Extended, + palette: &'a theme::Palette, ) -> impl Iterator + 'a { struct List { start: Option, @@ -250,7 +249,7 @@ pub fn parse<'a>( }; let span = if let Some(link) = link.as_ref() { - span.color(palette.primary.base.color).link(link.clone()) + span.color(palette.primary).link(link.clone()) } else { span }; @@ -262,13 +261,14 @@ pub fn parse<'a>( pulldown_cmark::Event::Code(code) if !metadata && !table => { let span = span(code.into_string()) .font(Font::MONOSPACE) + .color(Color::WHITE) .background(Background { - color: palette.background.weak.color, + color: color!(0x111111), border: border::rounded(2), }); let span = if let Some(link) = link.as_ref() { - span.color(palette.primary.base.color).link(link.clone()) + span.color(palette.primary).link(link.clone()) } else { span }; -- cgit From f7fe1edcbbfde71d801379805b4605ff36075b11 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 13:44:08 +0200 Subject: Improve ergonomics of `span` background highlighting --- core/src/text.rs | 85 +++++++++++++++++++++++++++++++++---------------- widget/src/markdown.rs | 7 ++-- widget/src/text/rich.rs | 6 ++-- 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/core/src/text.rs b/core/src/text.rs index 0bdc6851..d54c8e6c 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -8,7 +8,7 @@ pub use highlighter::Highlighter; pub use paragraph::Paragraph; use crate::alignment; -use crate::{Border, Color, Pixels, Point, Rectangle, Size}; +use crate::{Background, Border, Color, Pixels, Point, Rectangle, Size}; use std::borrow::Cow; use std::hash::{Hash, Hasher}; @@ -235,10 +235,19 @@ pub struct Span<'a, Link = (), Font = crate::Font> { pub font: Option, /// The [`Color`] of the [`Span`]. pub color: Option, - /// The [`Background`] of the [`Span`]. - pub background: Option, /// The link of the [`Span`]. pub link: Option, + /// The [`Highlight`] of the [`Span`]. + pub highlight: Option, +} + +/// A text highlight. +#[derive(Debug, Clone, Copy)] +pub struct Highlight { + /// The [`Background`] of the highlight. + pub background: Background, + /// The [`Border`] of the highlight. + pub border: Border, } impl<'a, Link, Font> Span<'a, Link, Font> { @@ -250,7 +259,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> { line_height: None, font: None, color: None, - background: None, + highlight: None, link: None, } } @@ -292,9 +301,8 @@ impl<'a, Link, Font> Span<'a, Link, Font> { } /// Sets the [`Background`] of the [`Span`]. - pub fn background(mut self, background: impl Into) -> Self { - self.background = Some(background.into()); - self + pub fn background(self, background: impl Into) -> Self { + self.background_maybe(Some(background)) } /// Sets the [`Background`] of the [`Span`], if any. @@ -302,7 +310,48 @@ impl<'a, Link, Font> Span<'a, Link, Font> { mut self, background: Option>, ) -> Self { - self.background = background.map(Into::into); + let Some(background) = background else { + return self; + }; + + match &mut self.highlight { + Some(highlight) => { + highlight.background = background.into(); + } + None => { + self.highlight = Some(Highlight { + background: background.into(), + border: Border::default(), + }); + } + } + + self + } + + /// Sets the [`Border`] of the [`Span`]. + pub fn border(self, border: impl Into) -> Self { + self.border_maybe(Some(border)) + } + + /// Sets the [`Border`] of the [`Span`], if any. + pub fn border_maybe(mut self, border: Option>) -> Self { + let Some(border) = border else { + return self; + }; + + match &mut self.highlight { + Some(highlight) => { + highlight.border = border.into(); + } + None => { + self.highlight = Some(Highlight { + border: border.into(), + background: Background::Color(Color::TRANSPARENT), + }); + } + } + self } @@ -326,8 +375,8 @@ impl<'a, Link, Font> Span<'a, Link, Font> { line_height: self.line_height, font: self.font, color: self.color, - background: self.background, link: self.link, + highlight: self.highlight, } } } @@ -425,21 +474,3 @@ into_fragment!(isize); into_fragment!(f32); into_fragment!(f64); - -/// The background style of text -#[derive(Debug, Clone, Copy)] -pub struct Background { - /// The background [`Color`] - pub color: Color, - /// The background [`Border`] - pub border: Border, -} - -impl From for Background { - fn from(color: Color) -> Self { - Background { - color, - border: Border::default(), - } - } -} diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index 362aba67..cb3e9cfc 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -7,7 +7,6 @@ use crate::core::border; use crate::core::font::{self, Font}; use crate::core::padding; -use crate::core::text::Background; use crate::core::theme::{self, Theme}; use crate::core::{self, color, Color, Element, Length, Pixels}; use crate::{column, container, rich_text, row, scrollable, span, text}; @@ -262,10 +261,8 @@ pub fn parse<'a>( let span = span(code.into_string()) .font(Font::MONOSPACE) .color(Color::WHITE) - .background(Background { - color: color!(0x111111), - border: border::rounded(2), - }); + .background(color!(0x111111)) + .border(border::rounded(2)); let span = if let Some(link) = link.as_ref() { span.color(palette.primary).link(link.clone()) diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index 832a3ae7..f636b219 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -248,17 +248,17 @@ where // Draw backgrounds for (index, span) in self.spans.iter().enumerate() { - if let Some(background) = span.background { + if let Some(highlight) = span.highlight { let translation = layout.position() - Point::ORIGIN; for bounds in state.paragraph.span_bounds(index) { renderer.fill_quad( renderer::Quad { bounds: bounds + translation, - border: background.border, + border: highlight.border, ..Default::default() }, - background.color, + highlight.background, ); } } -- cgit From 2796a6bc974d847580ab23c6a5f58db994883ec5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 13:56:39 +0200 Subject: Add `padding` to `text::Span` --- core/src/size.rs | 14 ++++++++++++++ core/src/text.rs | 40 ++++++++++++++++++++++++++++++---------- widget/src/markdown.rs | 3 ++- widget/src/text/rich.rs | 12 +++++++++++- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/core/src/size.rs b/core/src/size.rs index d7459355..95089236 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -99,6 +99,20 @@ impl From> for Vector { } } +impl std::ops::Add for Size +where + T: std::ops::Add, +{ + type Output = Size; + + fn add(self, rhs: Self) -> Self::Output { + Size { + width: self.width + rhs.width, + height: self.height + rhs.height, + } + } +} + impl std::ops::Sub for Size where T: std::ops::Sub, diff --git a/core/src/text.rs b/core/src/text.rs index d54c8e6c..2f085bd8 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -8,7 +8,9 @@ pub use highlighter::Highlighter; pub use paragraph::Paragraph; use crate::alignment; -use crate::{Background, Border, Color, Pixels, Point, Rectangle, Size}; +use crate::{ + Background, Border, Color, Padding, Pixels, Point, Rectangle, Size, +}; use std::borrow::Cow; use std::hash::{Hash, Hasher}; @@ -239,6 +241,10 @@ pub struct Span<'a, Link = (), Font = crate::Font> { pub link: Option, /// The [`Highlight`] of the [`Span`]. pub highlight: Option, + /// The [`Padding`] of the [`Span`]. + /// + /// Currently, it only affects the bounds of the [`Highlight`]. + pub padding: Padding, } /// A text highlight. @@ -261,6 +267,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> { color: None, highlight: None, link: None, + padding: Padding::ZERO, } } @@ -300,6 +307,18 @@ impl<'a, Link, Font> Span<'a, Link, Font> { self } + /// Sets the link of the [`Span`]. + pub fn link(mut self, link: impl Into) -> Self { + self.link = Some(link.into()); + self + } + + /// Sets the link of the [`Span`], if any. + pub fn link_maybe(mut self, link: Option>) -> Self { + self.link = link.map(Into::into); + self + } + /// Sets the [`Background`] of the [`Span`]. pub fn background(self, background: impl Into) -> Self { self.background_maybe(Some(background)) @@ -355,15 +374,15 @@ impl<'a, Link, Font> Span<'a, Link, Font> { self } - /// Sets the link of the [`Span`]. - pub fn link(mut self, link: impl Into) -> Self { - self.link = Some(link.into()); - self - } - - /// Sets the link of the [`Span`], if any. - pub fn link_maybe(mut self, link: Option>) -> Self { - self.link = link.map(Into::into); + /// Sets the [`Padding`] of the [`Span`]. + /// + /// It only affects the [`background`] and [`border`] of the + /// [`Span`], currently. + /// + /// [`background`]: Self::background + /// [`border`]: Self::border + pub fn padding(mut self, padding: impl Into) -> Self { + self.padding = padding.into(); self } @@ -377,6 +396,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> { color: self.color, link: self.link, highlight: self.highlight, + padding: self.padding, } } } diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index cb3e9cfc..c5eeaea9 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -262,7 +262,8 @@ pub fn parse<'a>( .font(Font::MONOSPACE) .color(Color::WHITE) .background(color!(0x111111)) - .border(border::rounded(2)); + .border(border::rounded(2)) + .padding(padding::left(2).right(2)); let span = if let Some(link) = link.as_ref() { span.color(palette.primary).link(link.clone()) diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index f636b219..67db31db 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -10,7 +10,7 @@ use crate::core::widget::text::{ use crate::core::widget::tree::{self, Tree}; use crate::core::{ self, Clipboard, Color, Element, Event, Layout, Length, Pixels, Point, - Rectangle, Shell, Size, Widget, + Rectangle, Shell, Size, Vector, Widget, }; use std::borrow::Cow; @@ -252,6 +252,16 @@ where let translation = layout.position() - Point::ORIGIN; for bounds in state.paragraph.span_bounds(index) { + let bounds = Rectangle::new( + bounds.position() + - Vector::new(span.padding.left, span.padding.top), + bounds.size() + + Size::new( + span.padding.horizontal(), + span.padding.vertical(), + ), + ); + renderer.fill_quad( renderer::Quad { bounds: bounds + translation, -- cgit From 2d69464846e6e1a7c59f78d894d8801ff82c5929 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 13:59:11 +0200 Subject: Make `markdown::parse` take a `Palette` value --- examples/markdown/src/main.rs | 4 ++-- widget/src/markdown.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/markdown/src/main.rs b/examples/markdown/src/main.rs index efe5b324..173cb389 100644 --- a/examples/markdown/src/main.rs +++ b/examples/markdown/src/main.rs @@ -28,7 +28,7 @@ impl Markdown { ( Self { content: text_editor::Content::with_text(INITIAL_CONTENT), - items: markdown::parse(INITIAL_CONTENT, &theme.palette()) + items: markdown::parse(INITIAL_CONTENT, theme.palette()) .collect(), theme, }, @@ -46,7 +46,7 @@ impl Markdown { if is_edit { self.items = markdown::parse( &self.content.text(), - &self.theme.palette(), + self.theme.palette(), ) .collect(); } diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index c5eeaea9..9cd4a62f 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -35,10 +35,10 @@ pub enum Item { } /// Parse the given Markdown content. -pub fn parse<'a>( - markdown: &'a str, - palette: &'a theme::Palette, -) -> impl Iterator + 'a { +pub fn parse( + markdown: &str, + palette: theme::Palette, +) -> impl Iterator + '_ { struct List { start: Option, items: Vec>, -- cgit From 2e4c55bbffb45e7112e753fd77d78071acb252b1 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 14:17:59 +0200 Subject: Use `for` loop instead of `fold` in `span_bounds` --- graphics/src/text/paragraph.rs | 58 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 540e669b..b9f9c833 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -254,9 +254,10 @@ impl core::text::Paragraph for Paragraph { fn span_bounds(&self, index: usize) -> Vec { let internal = self.internal(); + let mut bounds = Vec::new(); let mut current_bounds = None; - let mut bounds = internal + let glyphs = internal .buffer .layout_runs() .flat_map(|run| { @@ -268,35 +269,34 @@ impl core::text::Paragraph for Paragraph { .map(move |glyph| (line_top, line_height, glyph)) }) .skip_while(|(_, _, glyph)| glyph.metadata != index) - .take_while(|(_, _, glyph)| glyph.metadata == index) - .fold(vec![], |mut spans, (line_top, line_height, glyph)| { - let y = line_top + glyph.y; - - let new_bounds = || { - Rectangle::new( - Point::new(glyph.x, y), - Size::new( - glyph.w, - glyph.line_height_opt.unwrap_or(line_height), - ), - ) - }; - - match current_bounds.as_mut() { - None => { - current_bounds = Some(new_bounds()); - } - Some(bounds) if y != bounds.y => { - spans.push(*bounds); - *bounds = new_bounds(); - } - Some(bounds) => { - bounds.width += glyph.w; - } + .take_while(|(_, _, glyph)| glyph.metadata == index); + + for (line_top, line_height, glyph) in glyphs { + let y = line_top + glyph.y; + + let new_bounds = || { + Rectangle::new( + Point::new(glyph.x, y), + Size::new( + glyph.w, + glyph.line_height_opt.unwrap_or(line_height), + ), + ) + }; + + match current_bounds.as_mut() { + None => { + current_bounds = Some(new_bounds()); } - - spans - }); + Some(current_bounds) if y != current_bounds.y => { + bounds.push(*current_bounds); + *current_bounds = new_bounds(); + } + Some(current_bounds) => { + current_bounds.width += glyph.w; + } + } + } bounds.extend(current_bounds); bounds -- cgit From 41a7318e5df3a49bf6e7fc2110155f2f22ff7e60 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 28 Jul 2024 14:19:24 +0200 Subject: Remove comment in `text::Rich::draw` --- widget/src/text/rich.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index 67db31db..9935e6c5 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -246,7 +246,6 @@ where let style = theme.style(&self.class); - // Draw backgrounds for (index, span) in self.spans.iter().enumerate() { if let Some(highlight) = span.highlight { let translation = layout.position() - Point::ORIGIN; -- cgit