diff --git a/examples/rich-text/src/main.rs b/examples/rich-text/src/main.rs index cae3d63..0f02c82 100644 --- a/examples/rich-text/src/main.rs +++ b/examples/rich-text/src/main.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -use cosmic_text::{Color, Family, FontSystem, Style, SwashCache, +use cosmic_text::{Attrs, AttrsList, Color, Family, FontSystem, Style, SwashCache, TextAction, TextBuffer, TextBufferLine, TextMetrics, Weight}; use orbclient::{EventOption, Renderer, Window, WindowFlag}; use std::{process, thread, time::{Duration, Instant}}; @@ -31,7 +31,7 @@ fn main() { ) .unwrap(); - let attrs = cosmic_text::Attrs::new(); + let attrs = Attrs::new(); let mut buffer = TextBuffer::new( &font_system, attrs, @@ -47,75 +47,79 @@ fn main() { let mono_attrs = attrs.monospaced(true).family(Family::Monospace); let comic_attrs = attrs.family(Family::Name("Comic Neue")); - let mut line_i = 0; - for &(text, attrs) in &[ - ("B", attrs.weight(Weight::BOLD)), - ("old ", attrs), - ("I", attrs.style(Style::Italic)), - ("talic ", attrs), - ("f", attrs), - ("i ", attrs), - ("f", attrs.weight(Weight::BOLD)), - ("i ", attrs), - ("f", attrs.style(Style::Italic)), - ("i ", attrs), - ("\n", attrs), - ("Sans-Serif Normal ", attrs), - ("Sans-Serif Bold ", attrs.weight(Weight::BOLD)), - ("Sans-Serif Italic ", attrs.style(Style::Italic)), - ("Sans-Serif Bold Italic", attrs.weight(Weight::BOLD).style(Style::Italic)), - ("\n", attrs), - ("Serif Normal ", serif_attrs), - ("Serif Bold ", serif_attrs.weight(Weight::BOLD)), - ("Serif Italic ", serif_attrs.style(Style::Italic)), - ("Serif Bold Italic", serif_attrs.weight(Weight::BOLD).style(Style::Italic)), - ("\n", attrs), - ("Mono Normal ", mono_attrs), - ("Mono Bold ", mono_attrs.weight(Weight::BOLD)), - ("Mono Italic ", mono_attrs.style(Style::Italic)), - ("Mono Bold Italic", mono_attrs.weight(Weight::BOLD).style(Style::Italic)), - ("\n", attrs), - ("Comic Normal ", comic_attrs), - ("Comic Bold ", comic_attrs.weight(Weight::BOLD)), - ("Comic Italic ", comic_attrs.style(Style::Italic)), - ("Comic Bold Italic", comic_attrs.weight(Weight::BOLD).style(Style::Italic)), - ("\n", attrs), - ("R", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), - ("A", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), - ("I", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), - ("N", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), - ("B", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), - ("O", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), - ("W ", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), - ("Red ", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), - ("Orange ", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), - ("Yellow ", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), - ("Green ", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), - ("Blue ", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), - ("Indigo ", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), - ("Violet ", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), - ("U", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), - ("N", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), - ("I", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), - ("C", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), - ("O", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), - ("R", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), - ("N", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), - ] { - if text == "\n" { - line_i += 1; - while line_i >= buffer.lines.len() { - buffer.lines.push(TextBufferLine::new(String::new(), attrs)); - } - continue; - } + buffer.lines.clear(); - let line = &mut buffer.lines[line_i]; - let start = line.text.len(); - line.text.push_str(text); - let end = line.text.len(); - line.attrs_list.add_span(start, end, attrs); - line.reset(); + let lines: &[&[(&str, Attrs)]] = &[ + &[ + ("B", attrs.weight(Weight::BOLD)), + ("old ", attrs), + ("I", attrs.style(Style::Italic)), + ("talic ", attrs), + ("f", attrs), + ("i ", attrs), + ("f", attrs.weight(Weight::BOLD)), + ("i ", attrs), + ("f", attrs.style(Style::Italic)), + ("i ", attrs), + ], + &[ + ("Sans-Serif Normal ", attrs), + ("Sans-Serif Bold ", attrs.weight(Weight::BOLD)), + ("Sans-Serif Italic ", attrs.style(Style::Italic)), + ("Sans-Serif Bold Italic", attrs.weight(Weight::BOLD).style(Style::Italic)), + ], + &[ + ("Serif Normal ", serif_attrs), + ("Serif Bold ", serif_attrs.weight(Weight::BOLD)), + ("Serif Italic ", serif_attrs.style(Style::Italic)), + ("Serif Bold Italic", serif_attrs.weight(Weight::BOLD).style(Style::Italic)), + ], + &[ + ("Mono Normal ", mono_attrs), + ("Mono Bold ", mono_attrs.weight(Weight::BOLD)), + ("Mono Italic ", mono_attrs.style(Style::Italic)), + ("Mono Bold Italic", mono_attrs.weight(Weight::BOLD).style(Style::Italic)), + ], + &[ + ("Comic Normal ", comic_attrs), + ("Comic Bold ", comic_attrs.weight(Weight::BOLD)), + ("Comic Italic ", comic_attrs.style(Style::Italic)), + ("Comic Bold Italic", comic_attrs.weight(Weight::BOLD).style(Style::Italic)), + ], + &[ + ("R", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), + ("A", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), + ("I", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), + ("N", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), + ("B", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), + ("O", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), + ("W ", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), + ("Red ", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), + ("Orange ", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), + ("Yellow ", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), + ("Green ", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), + ("Blue ", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), + ("Indigo ", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), + ("Violet ", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), + ("U", attrs.color(Color::rgb(0x94, 0x00, 0xD3))), + ("N", attrs.color(Color::rgb(0x4B, 0x00, 0x82))), + ("I", attrs.color(Color::rgb(0x00, 0x00, 0xFF))), + ("C", attrs.color(Color::rgb(0x00, 0xFF, 0x00))), + ("O", attrs.color(Color::rgb(0xFF, 0xFF, 0x00))), + ("R", attrs.color(Color::rgb(0xFF, 0x7F, 0x00))), + ("N", attrs.color(Color::rgb(0xFF, 0x00, 0x00))), + ] + ]; + for &line in lines { + let mut line_text = String::new(); + let mut attrs_list = AttrsList::new(attrs); + for &(text, attrs) in line { + let start = line_text.len(); + line_text.push_str(text); + let end = line_text.len(); + attrs_list.add_span(start, end, attrs); + } + buffer.lines.push(TextBufferLine::new(line_text, attrs_list)); } let mut swash_cache = SwashCache::new(&font_system); diff --git a/examples/syntax/src/main.rs b/examples/syntax/src/main.rs index 9c8e95d..cf3684e 100644 --- a/examples/syntax/src/main.rs +++ b/examples/syntax/src/main.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -use cosmic_text::{Attrs, Color, Family, FontSystem, Style, SwashCache, +use cosmic_text::{Attrs, AttrsList, Color, Family, FontSystem, Style, SwashCache, TextAction, TextBuffer, TextBufferLine, TextMetrics, Weight}; use orbclient::{EventOption, Renderer, Window, WindowFlag}; use std::{env, fs, process, time::Instant}; @@ -59,6 +59,8 @@ fn main() { use syntect::highlighting::{ThemeSet, FontStyle, Style as SyntectStyle}; use syntect::util::LinesWithEndings; + let now = Instant::now(); + // Load these once at the start of your program let ps = SyntaxSet::load_defaults_newlines(); let ts = ThemeSet::load_defaults(); @@ -83,25 +85,25 @@ fn main() { } let syntax = ps.find_syntax_by_extension("rs").unwrap(); - let mut h = HighlightLines::new(syntax, &theme); - for (line_i, highlight_line) in LinesWithEndings::from(&text).enumerate() { // LinesWithEndings enables use of newlines mode - while line_i >= buffer.lines.len() { - buffer.lines.push(TextBufferLine::new(String::new(), attrs)); - } + buffer.lines.clear(); + + let mut h = HighlightLines::new(syntax, &theme); + for highlight_line in LinesWithEndings::from(&text) { // LinesWithEndings enables use of newlines mode let ranges: Vec<(SyntectStyle, &str)> = h.highlight_line(highlight_line, &ps).unwrap(); - let line = &mut buffer.lines[line_i]; + let mut line_text = String::new(); + let mut attrs_list = AttrsList::new(attrs); for (style, string) in ranges.iter() { let string_trim = match string.lines().next() { Some(some) => some, None => continue, }; - let start = line.text.len(); - line.text.push_str(string_trim); - let end = line.text.len(); - line.attrs_list.add_span( + let start = line_text.len(); + line_text.push_str(string_trim); + let end = line_text.len(); + attrs_list.add_span( start, end, attrs @@ -124,9 +126,13 @@ fn main() { }) //TODO: underline ); - line.reset(); } + + buffer.lines.push(TextBufferLine::new(line_text, attrs_list)); } + + let elapsed = now.elapsed(); + log::info!("Syntax highlighted in {:?}", elapsed); } let mut swash_cache = SwashCache::new(&font_system); diff --git a/src/buffer.rs b/src/buffer.rs index 77c8ecc..1c5f9c4 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -174,17 +174,17 @@ impl fmt::Display for TextMetrics { } pub struct TextBufferLine<'a> { - pub text: String, - pub attrs_list: AttrsList<'a>, + text: String, + attrs_list: AttrsList<'a>, shape_opt: Option, layout_opt: Option>, } impl<'a> TextBufferLine<'a> { - pub fn new(text: String, attrs: Attrs<'a>) -> Self { + pub fn new(text: String, attrs_list: AttrsList<'a>) -> Self { Self { text, - attrs_list: AttrsList::new(attrs), + attrs_list, shape_opt: None, layout_opt: None, } @@ -516,11 +516,11 @@ impl<'a> TextBuffer<'a> { pub fn set_text(&mut self, text: &str) { self.lines.clear(); for line in text.lines() { - self.lines.push(TextBufferLine::new(line.to_string(), self.attrs)); + self.lines.push(TextBufferLine::new(line.to_string(), AttrsList::new(self.attrs))); } // Make sure there is always one line if self.lines.is_empty() { - self.lines.push(TextBufferLine::new(String::new(), self.attrs)); + self.lines.push(TextBufferLine::new(String::new(), AttrsList::new(self.attrs))); } self.scroll = 0; @@ -676,7 +676,7 @@ impl<'a> TextBuffer<'a> { }; let next_line = self.cursor.line + 1; - self.lines.insert(next_line, TextBufferLine::new(new_line, self.attrs)); + self.lines.insert(next_line, TextBufferLine::new(new_line, AttrsList::new(self.attrs))); self.cursor.line = next_line; self.cursor.index = 0; diff --git a/syntax.sh b/syntax.sh index fe8621e..1ca2092 100755 --- a/syntax.sh +++ b/syntax.sh @@ -1 +1 @@ -RUST_LOG=cosmic_text=debug cargo run --release --package syntax -- "$@" +RUST_LOG=cosmic_text=debug,syntax=debug cargo run --release --package syntax -- "$@"