From 0f055c0a137d031d71ed9c8e4cd1bd4d45e0b4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 21 Apr 2023 20:24:44 +0200 Subject: [PATCH] Replace `skip_shaping` boolean with `Shaping` enum --- src/buffer.rs | 15 ++++---- src/buffer_line.rs | 12 +++--- src/edit/editor.rs | 7 ++-- src/lib.rs | 4 +- src/shape.rs | 91 ++++++++++++++++++++++++---------------------- 5 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index fd3df69..826b8ef 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -12,7 +12,7 @@ use unicode_segmentation::UnicodeSegmentation; use crate::Color; use crate::{ Attrs, AttrsList, BorrowedWithFontSystem, BufferLine, FontSystem, LayoutGlyph, LayoutLine, - ShapeLine, Wrap, + ShapeLine, Shaping, Wrap, }; /// Current cursor location @@ -331,7 +331,7 @@ impl Buffer { redraw: false, wrap: Wrap::Word, }; - buffer.set_text(font_system, "", Attrs::new(), true); + buffer.set_text(font_system, "", Attrs::new(), Shaping::Basic); buffer } @@ -567,14 +567,14 @@ impl Buffer { font_system: &mut FontSystem, text: &str, attrs: Attrs, - skip_shaping: bool, + shaping: Shaping, ) { self.lines.clear(); for line in text.lines() { self.lines.push(BufferLine::new( line.to_string(), AttrsList::new(attrs), - skip_shaping, + shaping, )); } // Make sure there is always one line @@ -582,7 +582,7 @@ impl Buffer { self.lines.push(BufferLine::new( String::new(), AttrsList::new(attrs), - skip_shaping, + shaping, )); } @@ -781,9 +781,8 @@ impl<'a> BorrowedWithFontSystem<'a, Buffer> { } /// Set text of buffer, using provided attributes for each line by default - pub fn set_text(&mut self, text: &str, attrs: Attrs, skip_shaping: bool) { - self.inner - .set_text(self.font_system, text, attrs, skip_shaping); + pub fn set_text(&mut self, text: &str, attrs: Attrs, shaping: Shaping) { + self.inner.set_text(self.font_system, text, attrs, shaping); } /// Draw the buffer diff --git a/src/buffer_line.rs b/src/buffer_line.rs index 2bedd8b..4ada0f9 100644 --- a/src/buffer_line.rs +++ b/src/buffer_line.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; -use crate::{Align, AttrsList, FontSystem, LayoutLine, ShapeLine, Wrap}; +use crate::{Align, AttrsList, FontSystem, LayoutLine, ShapeLine, Shaping, Wrap}; /// A line (or paragraph) of text that is shaped and laid out pub struct BufferLine { @@ -12,14 +12,14 @@ pub struct BufferLine { align: Option, shape_opt: Option, layout_opt: Option>, - skip_shaping: bool, + shaping: Shaping, } impl BufferLine { /// Create a new line with the given text and attributes list /// Cached shaping and layout can be done using the [`Self::shape`] and /// [`Self::layout`] functions - pub fn new>(text: T, attrs_list: AttrsList, skip_shaping: bool) -> Self { + pub fn new>(text: T, attrs_list: AttrsList, shaping: Shaping) -> Self { Self { text: text.into(), attrs_list, @@ -27,7 +27,7 @@ impl BufferLine { align: None, shape_opt: None, layout_opt: None, - skip_shaping, + shaping, } } @@ -144,7 +144,7 @@ impl BufferLine { let attrs_list = self.attrs_list.split_off(index); self.reset(); - let mut new = Self::new(text, attrs_list, self.skip_shaping); + let mut new = Self::new(text, attrs_list, self.shaping); new.wrap = self.wrap; new } @@ -173,7 +173,7 @@ impl BufferLine { font_system, &self.text, &self.attrs_list, - self.skip_shaping, + self.shaping, )); self.layout_opt = None; } diff --git a/src/edit/editor.rs b/src/edit/editor.rs index 2a1d8a6..ff2f00b 100644 --- a/src/edit/editor.rs +++ b/src/edit/editor.rs @@ -12,6 +12,7 @@ use unicode_segmentation::UnicodeSegmentation; use crate::Color; use crate::{ Action, Affinity, AttrsList, Buffer, BufferLine, Cursor, Edit, FontSystem, LayoutCursor, + Shaping, }; /// A wrapper of [`Buffer`] for easy editing @@ -245,7 +246,7 @@ impl Edit for Editor { .strip_suffix(char::is_control) .unwrap_or(data_line), these_attrs, - false, + Shaping::Advanced, )); } else { panic!("str::lines() did not yield any elements"); @@ -257,7 +258,7 @@ impl Edit for Editor { .strip_suffix(char::is_control) .unwrap_or(data_line), final_attrs.split_off(remaining_split_len), - false, + Shaping::Advanced, ); tmp.append(after); self.buffer.lines.insert(insert_line, tmp); @@ -272,7 +273,7 @@ impl Edit for Editor { .strip_suffix(char::is_control) .unwrap_or(data_line), final_attrs.split_off(remaining_split_len), - false, + Shaping::Advanced, ); self.buffer.lines.insert(insert_line, tmp); self.cursor.line += 1; diff --git a/src/lib.rs b/src/lib.rs index fd12af8..f4b700e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,7 @@ //! point, you can use the `SwashCache` to rasterize glyphs into either images or pixels. //! //! ``` -//! use cosmic_text::{Attrs, Color, FontSystem, SwashCache, Buffer, Metrics}; +//! use cosmic_text::{Attrs, Color, FontSystem, SwashCache, Buffer, Metrics, Shaping}; //! //! // A FontSystem provides access to detected system fonts, create one per application //! let mut font_system = FontSystem::new(); @@ -36,7 +36,7 @@ //! let attrs = Attrs::new(); //! //! // Add some text! -//! buffer.set_text("Hello, Rust! 🦀\n", attrs, false); +//! buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced); //! //! // Perform shaping as desired //! buffer.shape_until_scroll(); diff --git a/src/shape.rs b/src/shape.rs index fcb259b..7183618 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -11,6 +11,31 @@ use unicode_segmentation::UnicodeSegmentation; use crate::fallback::FontFallbackIter; use crate::{Align, AttrsList, CacheKey, Color, Font, FontSystem, LayoutGlyph, LayoutLine, Wrap}; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Shaping { + Basic, + Advanced, +} + +impl Shaping { + fn run( + self, + font_system: &mut FontSystem, + line: &str, + attrs_list: &AttrsList, + start_run: usize, + end_run: usize, + span_rtl: bool, + ) -> Vec { + match self { + Self::Basic => shape_skip(font_system, line, attrs_list, start_run, end_run), + Self::Advanced => { + shape_run(font_system, line, attrs_list, start_run, end_run, span_rtl) + } + } + } +} + fn shape_fallback( font: &Font, line: &str, @@ -321,7 +346,7 @@ impl ShapeWord { word_range: Range, level: unicode_bidi::Level, blank: bool, - skip_shaping: bool, + shaping: Shaping, ) -> Self { let word = &line[word_range.clone()]; @@ -341,24 +366,14 @@ impl ShapeWord { let attrs_egc = attrs_list.get_span(start_egc); if !attrs.compatible(&attrs_egc) { //TODO: more efficient - if skip_shaping { - glyphs.append(&mut shape_skip( - font_system, - line, - attrs_list, - start_run, - start_egc, - )); - } else { - glyphs.append(&mut shape_run( - font_system, - line, - attrs_list, - start_run, - start_egc, - span_rtl, - )); - }; + glyphs.append(&mut shaping.run( + font_system, + line, + attrs_list, + start_run, + start_egc, + span_rtl, + )); start_run = start_egc; attrs = attrs_egc; @@ -366,24 +381,14 @@ impl ShapeWord { } if start_run < word_range.end { //TODO: more efficient - if skip_shaping { - glyphs.append(&mut shape_skip( - font_system, - line, - attrs_list, - start_run, - word_range.end, - )); - } else { - glyphs.append(&mut shape_run( - font_system, - line, - attrs_list, - start_run, - word_range.end, - span_rtl, - )); - } + glyphs.append(&mut shaping.run( + font_system, + line, + attrs_list, + start_run, + word_range.end, + span_rtl, + )); } let mut x_advance = 0.0; @@ -416,7 +421,7 @@ impl ShapeSpan { span_range: Range, line_rtl: bool, level: unicode_bidi::Level, - skip_shaping: bool, + shaping: Shaping, ) -> Self { let span = &line[span_range.start..span_range.end]; @@ -447,7 +452,7 @@ impl ShapeSpan { (span_range.start + start_word)..(span_range.start + start_lb), level, false, - skip_shaping, + shaping, )); } if start_lb < end_lb { @@ -461,7 +466,7 @@ impl ShapeSpan { ..(span_range.start + start_lb + i + c.len_utf8()), level, true, - skip_shaping, + shaping, )); } } @@ -508,7 +513,7 @@ impl ShapeLine { font_system: &mut FontSystem, line: &str, attrs_list: &AttrsList, - skip_shaping: bool, + shaping: Shaping, ) -> Self { let mut spans = Vec::new(); @@ -545,7 +550,7 @@ impl ShapeLine { start..i, line_rtl, run_level, - skip_shaping, + shaping, )); start = i; run_level = new_level; @@ -558,7 +563,7 @@ impl ShapeLine { start..line_range.end, line_rtl, run_level, - skip_shaping, + shaping, )); line_rtl };