Replace skip_shaping boolean with Shaping enum

This commit is contained in:
Héctor Ramón Jiménez 2023-04-21 20:24:44 +02:00
parent ad111a1df1
commit 0f055c0a13
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
5 changed files with 67 additions and 62 deletions

View file

@ -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

View file

@ -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<Align>,
shape_opt: Option<ShapeLine>,
layout_opt: Option<Vec<LayoutLine>>,
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<T: Into<String>>(text: T, attrs_list: AttrsList, skip_shaping: bool) -> Self {
pub fn new<T: Into<String>>(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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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<ShapeGlyph> {
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<usize>,
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<usize>,
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
};