Replace skip_shaping boolean with Shaping enum
This commit is contained in:
parent
ad111a1df1
commit
0f055c0a13
5 changed files with 67 additions and 62 deletions
|
|
@ -12,7 +12,7 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||||
use crate::Color;
|
use crate::Color;
|
||||||
use crate::{
|
use crate::{
|
||||||
Attrs, AttrsList, BorrowedWithFontSystem, BufferLine, FontSystem, LayoutGlyph, LayoutLine,
|
Attrs, AttrsList, BorrowedWithFontSystem, BufferLine, FontSystem, LayoutGlyph, LayoutLine,
|
||||||
ShapeLine, Wrap,
|
ShapeLine, Shaping, Wrap,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Current cursor location
|
/// Current cursor location
|
||||||
|
|
@ -331,7 +331,7 @@ impl Buffer {
|
||||||
redraw: false,
|
redraw: false,
|
||||||
wrap: Wrap::Word,
|
wrap: Wrap::Word,
|
||||||
};
|
};
|
||||||
buffer.set_text(font_system, "", Attrs::new(), true);
|
buffer.set_text(font_system, "", Attrs::new(), Shaping::Basic);
|
||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,14 +567,14 @@ impl Buffer {
|
||||||
font_system: &mut FontSystem,
|
font_system: &mut FontSystem,
|
||||||
text: &str,
|
text: &str,
|
||||||
attrs: Attrs,
|
attrs: Attrs,
|
||||||
skip_shaping: bool,
|
shaping: Shaping,
|
||||||
) {
|
) {
|
||||||
self.lines.clear();
|
self.lines.clear();
|
||||||
for line in text.lines() {
|
for line in text.lines() {
|
||||||
self.lines.push(BufferLine::new(
|
self.lines.push(BufferLine::new(
|
||||||
line.to_string(),
|
line.to_string(),
|
||||||
AttrsList::new(attrs),
|
AttrsList::new(attrs),
|
||||||
skip_shaping,
|
shaping,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// Make sure there is always one line
|
// Make sure there is always one line
|
||||||
|
|
@ -582,7 +582,7 @@ impl Buffer {
|
||||||
self.lines.push(BufferLine::new(
|
self.lines.push(BufferLine::new(
|
||||||
String::new(),
|
String::new(),
|
||||||
AttrsList::new(attrs),
|
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
|
/// 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) {
|
pub fn set_text(&mut self, text: &str, attrs: Attrs, shaping: Shaping) {
|
||||||
self.inner
|
self.inner.set_text(self.font_system, text, attrs, shaping);
|
||||||
.set_text(self.font_system, text, attrs, skip_shaping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the buffer
|
/// Draw the buffer
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
use alloc::{string::String, vec::Vec};
|
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
|
/// A line (or paragraph) of text that is shaped and laid out
|
||||||
pub struct BufferLine {
|
pub struct BufferLine {
|
||||||
|
|
@ -12,14 +12,14 @@ pub struct BufferLine {
|
||||||
align: Option<Align>,
|
align: Option<Align>,
|
||||||
shape_opt: Option<ShapeLine>,
|
shape_opt: Option<ShapeLine>,
|
||||||
layout_opt: Option<Vec<LayoutLine>>,
|
layout_opt: Option<Vec<LayoutLine>>,
|
||||||
skip_shaping: bool,
|
shaping: Shaping,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferLine {
|
impl BufferLine {
|
||||||
/// Create a new line with the given text and attributes list
|
/// Create a new line with the given text and attributes list
|
||||||
/// Cached shaping and layout can be done using the [`Self::shape`] and
|
/// Cached shaping and layout can be done using the [`Self::shape`] and
|
||||||
/// [`Self::layout`] functions
|
/// [`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 {
|
Self {
|
||||||
text: text.into(),
|
text: text.into(),
|
||||||
attrs_list,
|
attrs_list,
|
||||||
|
|
@ -27,7 +27,7 @@ impl BufferLine {
|
||||||
align: None,
|
align: None,
|
||||||
shape_opt: None,
|
shape_opt: None,
|
||||||
layout_opt: None,
|
layout_opt: None,
|
||||||
skip_shaping,
|
shaping,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ impl BufferLine {
|
||||||
let attrs_list = self.attrs_list.split_off(index);
|
let attrs_list = self.attrs_list.split_off(index);
|
||||||
self.reset();
|
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.wrap = self.wrap;
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +173,7 @@ impl BufferLine {
|
||||||
font_system,
|
font_system,
|
||||||
&self.text,
|
&self.text,
|
||||||
&self.attrs_list,
|
&self.attrs_list,
|
||||||
self.skip_shaping,
|
self.shaping,
|
||||||
));
|
));
|
||||||
self.layout_opt = None;
|
self.layout_opt = None;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||||
use crate::Color;
|
use crate::Color;
|
||||||
use crate::{
|
use crate::{
|
||||||
Action, Affinity, AttrsList, Buffer, BufferLine, Cursor, Edit, FontSystem, LayoutCursor,
|
Action, Affinity, AttrsList, Buffer, BufferLine, Cursor, Edit, FontSystem, LayoutCursor,
|
||||||
|
Shaping,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A wrapper of [`Buffer`] for easy editing
|
/// A wrapper of [`Buffer`] for easy editing
|
||||||
|
|
@ -245,7 +246,7 @@ impl Edit for Editor {
|
||||||
.strip_suffix(char::is_control)
|
.strip_suffix(char::is_control)
|
||||||
.unwrap_or(data_line),
|
.unwrap_or(data_line),
|
||||||
these_attrs,
|
these_attrs,
|
||||||
false,
|
Shaping::Advanced,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
panic!("str::lines() did not yield any elements");
|
panic!("str::lines() did not yield any elements");
|
||||||
|
|
@ -257,7 +258,7 @@ impl Edit for Editor {
|
||||||
.strip_suffix(char::is_control)
|
.strip_suffix(char::is_control)
|
||||||
.unwrap_or(data_line),
|
.unwrap_or(data_line),
|
||||||
final_attrs.split_off(remaining_split_len),
|
final_attrs.split_off(remaining_split_len),
|
||||||
false,
|
Shaping::Advanced,
|
||||||
);
|
);
|
||||||
tmp.append(after);
|
tmp.append(after);
|
||||||
self.buffer.lines.insert(insert_line, tmp);
|
self.buffer.lines.insert(insert_line, tmp);
|
||||||
|
|
@ -272,7 +273,7 @@ impl Edit for Editor {
|
||||||
.strip_suffix(char::is_control)
|
.strip_suffix(char::is_control)
|
||||||
.unwrap_or(data_line),
|
.unwrap_or(data_line),
|
||||||
final_attrs.split_off(remaining_split_len),
|
final_attrs.split_off(remaining_split_len),
|
||||||
false,
|
Shaping::Advanced,
|
||||||
);
|
);
|
||||||
self.buffer.lines.insert(insert_line, tmp);
|
self.buffer.lines.insert(insert_line, tmp);
|
||||||
self.cursor.line += 1;
|
self.cursor.line += 1;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
//! point, you can use the `SwashCache` to rasterize glyphs into either images or pixels.
|
//! 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
|
//! // A FontSystem provides access to detected system fonts, create one per application
|
||||||
//! let mut font_system = FontSystem::new();
|
//! let mut font_system = FontSystem::new();
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
//! let attrs = Attrs::new();
|
//! let attrs = Attrs::new();
|
||||||
//!
|
//!
|
||||||
//! // Add some text!
|
//! // Add some text!
|
||||||
//! buffer.set_text("Hello, Rust! 🦀\n", attrs, false);
|
//! buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced);
|
||||||
//!
|
//!
|
||||||
//! // Perform shaping as desired
|
//! // Perform shaping as desired
|
||||||
//! buffer.shape_until_scroll();
|
//! buffer.shape_until_scroll();
|
||||||
|
|
|
||||||
91
src/shape.rs
91
src/shape.rs
|
|
@ -11,6 +11,31 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||||
use crate::fallback::FontFallbackIter;
|
use crate::fallback::FontFallbackIter;
|
||||||
use crate::{Align, AttrsList, CacheKey, Color, Font, FontSystem, LayoutGlyph, LayoutLine, Wrap};
|
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(
|
fn shape_fallback(
|
||||||
font: &Font,
|
font: &Font,
|
||||||
line: &str,
|
line: &str,
|
||||||
|
|
@ -321,7 +346,7 @@ impl ShapeWord {
|
||||||
word_range: Range<usize>,
|
word_range: Range<usize>,
|
||||||
level: unicode_bidi::Level,
|
level: unicode_bidi::Level,
|
||||||
blank: bool,
|
blank: bool,
|
||||||
skip_shaping: bool,
|
shaping: Shaping,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let word = &line[word_range.clone()];
|
let word = &line[word_range.clone()];
|
||||||
|
|
||||||
|
|
@ -341,24 +366,14 @@ impl ShapeWord {
|
||||||
let attrs_egc = attrs_list.get_span(start_egc);
|
let attrs_egc = attrs_list.get_span(start_egc);
|
||||||
if !attrs.compatible(&attrs_egc) {
|
if !attrs.compatible(&attrs_egc) {
|
||||||
//TODO: more efficient
|
//TODO: more efficient
|
||||||
if skip_shaping {
|
glyphs.append(&mut shaping.run(
|
||||||
glyphs.append(&mut shape_skip(
|
font_system,
|
||||||
font_system,
|
line,
|
||||||
line,
|
attrs_list,
|
||||||
attrs_list,
|
start_run,
|
||||||
start_run,
|
start_egc,
|
||||||
start_egc,
|
span_rtl,
|
||||||
));
|
));
|
||||||
} else {
|
|
||||||
glyphs.append(&mut shape_run(
|
|
||||||
font_system,
|
|
||||||
line,
|
|
||||||
attrs_list,
|
|
||||||
start_run,
|
|
||||||
start_egc,
|
|
||||||
span_rtl,
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
start_run = start_egc;
|
start_run = start_egc;
|
||||||
attrs = attrs_egc;
|
attrs = attrs_egc;
|
||||||
|
|
@ -366,24 +381,14 @@ impl ShapeWord {
|
||||||
}
|
}
|
||||||
if start_run < word_range.end {
|
if start_run < word_range.end {
|
||||||
//TODO: more efficient
|
//TODO: more efficient
|
||||||
if skip_shaping {
|
glyphs.append(&mut shaping.run(
|
||||||
glyphs.append(&mut shape_skip(
|
font_system,
|
||||||
font_system,
|
line,
|
||||||
line,
|
attrs_list,
|
||||||
attrs_list,
|
start_run,
|
||||||
start_run,
|
word_range.end,
|
||||||
word_range.end,
|
span_rtl,
|
||||||
));
|
));
|
||||||
} else {
|
|
||||||
glyphs.append(&mut shape_run(
|
|
||||||
font_system,
|
|
||||||
line,
|
|
||||||
attrs_list,
|
|
||||||
start_run,
|
|
||||||
word_range.end,
|
|
||||||
span_rtl,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut x_advance = 0.0;
|
let mut x_advance = 0.0;
|
||||||
|
|
@ -416,7 +421,7 @@ impl ShapeSpan {
|
||||||
span_range: Range<usize>,
|
span_range: Range<usize>,
|
||||||
line_rtl: bool,
|
line_rtl: bool,
|
||||||
level: unicode_bidi::Level,
|
level: unicode_bidi::Level,
|
||||||
skip_shaping: bool,
|
shaping: Shaping,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let span = &line[span_range.start..span_range.end];
|
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),
|
(span_range.start + start_word)..(span_range.start + start_lb),
|
||||||
level,
|
level,
|
||||||
false,
|
false,
|
||||||
skip_shaping,
|
shaping,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if start_lb < end_lb {
|
if start_lb < end_lb {
|
||||||
|
|
@ -461,7 +466,7 @@ impl ShapeSpan {
|
||||||
..(span_range.start + start_lb + i + c.len_utf8()),
|
..(span_range.start + start_lb + i + c.len_utf8()),
|
||||||
level,
|
level,
|
||||||
true,
|
true,
|
||||||
skip_shaping,
|
shaping,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +513,7 @@ impl ShapeLine {
|
||||||
font_system: &mut FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line: &str,
|
line: &str,
|
||||||
attrs_list: &AttrsList,
|
attrs_list: &AttrsList,
|
||||||
skip_shaping: bool,
|
shaping: Shaping,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut spans = Vec::new();
|
let mut spans = Vec::new();
|
||||||
|
|
||||||
|
|
@ -545,7 +550,7 @@ impl ShapeLine {
|
||||||
start..i,
|
start..i,
|
||||||
line_rtl,
|
line_rtl,
|
||||||
run_level,
|
run_level,
|
||||||
skip_shaping,
|
shaping,
|
||||||
));
|
));
|
||||||
start = i;
|
start = i;
|
||||||
run_level = new_level;
|
run_level = new_level;
|
||||||
|
|
@ -558,7 +563,7 @@ impl ShapeLine {
|
||||||
start..line_range.end,
|
start..line_range.end,
|
||||||
line_rtl,
|
line_rtl,
|
||||||
run_level,
|
run_level,
|
||||||
skip_shaping,
|
shaping,
|
||||||
));
|
));
|
||||||
line_rtl
|
line_rtl
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue