diff --git a/examples/editor-libcosmic/src/text_box.rs b/examples/editor-libcosmic/src/text_box.rs index a3c950c..7f65558 100644 --- a/examples/editor-libcosmic/src/text_box.rs +++ b/examples/editor-libcosmic/src/text_box.rs @@ -131,12 +131,10 @@ where fn layout(&self, _renderer: &Renderer, limits: &layout::Limits) -> layout::Node { let limits = limits.width(Length::Fill).height(Length::Fill); - //TODO: allow lazy shape let mut editor = self.editor.lock().unwrap(); editor .borrow_with(&mut FONT_SYSTEM.lock().unwrap()) - .buffer_mut() - .shape_until(i32::max_value()); + .shape_as_needed(true); let mut layout_lines = 0; for line in editor.buffer().lines.iter() { @@ -148,7 +146,6 @@ where let height = layout_lines as f32 * editor.buffer().metrics().line_height; let size = Size::new(limits.max().width, height); - log::info!("size {:?}", size); layout::Node::new(limits.resolve(size)) } @@ -228,7 +225,7 @@ where editor.buffer_mut().set_size(image_w as f32, image_h as f32); // Shape and layout - editor.shape_as_needed(); + editor.shape_as_needed(true); // Draw to pixel buffer let mut pixels = vec![0; image_w as usize * image_h as usize * 4]; diff --git a/examples/editor-orbclient/src/main.rs b/examples/editor-orbclient/src/main.rs index 309f4a5..53f9116 100644 --- a/examples/editor-orbclient/src/main.rs +++ b/examples/editor-orbclient/src/main.rs @@ -88,7 +88,7 @@ fn main() { let mut mouse_y = -1; let mut mouse_left = false; loop { - editor.shape_as_needed(); + editor.shape_as_needed(true); if editor.buffer().redraw() { let instant = Instant::now(); diff --git a/examples/editor-test/src/main.rs b/examples/editor-test/src/main.rs index c8fd28a..0d95ed2 100644 --- a/examples/editor-test/src/main.rs +++ b/examples/editor-test/src/main.rs @@ -16,7 +16,7 @@ fn redraw( let bg_color = orbclient::Color::rgb(0x34, 0x34, 0x34); let font_color = Color::rgb(0xFF, 0xFF, 0xFF); - editor.shape_as_needed(); + editor.shape_as_needed(true); if editor.buffer().redraw() { let instant = Instant::now(); diff --git a/examples/multiview/src/main.rs b/examples/multiview/src/main.rs index 9348bed..a4c3fb9 100644 --- a/examples/multiview/src/main.rs +++ b/examples/multiview/src/main.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -use cosmic_text::{Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Shaping, SwashCache}; +use cosmic_text::{ + Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Scroll, Shaping, SwashCache, +}; use std::{collections::HashMap, env, fs, num::NonZeroU32, rc::Rc, slice}; use tiny_skia::{Color, Paint, PixmapMut, Rect, Transform}; use winit::{ @@ -41,7 +43,7 @@ fn main() { window: Rc, context: softbuffer::Context>, surface: softbuffer::Surface, Rc>, - scroll: i32, + scroll: Scroll, } let mut windows = HashMap::new(); for _ in 0..2 { @@ -54,7 +56,7 @@ fn main() { window, context, surface, - scroll: 0, + scroll: Scroll::default(), }, ); } @@ -102,7 +104,8 @@ fn main() { // Set size, will relayout and shape until scroll if changed buffer.set_size(width as f32, height as f32); // Shape until scroll, ensures scroll is clamped - buffer.shape_until_scroll(); + //TODO: ability to prune with multiple views? + buffer.shape_until_scroll(true); // Update scroll after buffer clamps it *scroll = buffer.scroll(); @@ -145,16 +148,16 @@ fn main() { if state == ElementState::Pressed { match logical_key { Key::Named(NamedKey::ArrowDown) => { - *scroll += 1; + scroll.layout += 1; } Key::Named(NamedKey::ArrowUp) => { - *scroll -= 1; + scroll.layout -= 1; } Key::Named(NamedKey::PageDown) => { - *scroll += buffer.visible_lines(); + scroll.layout += buffer.visible_lines(); } Key::Named(NamedKey::PageUp) => { - *scroll -= buffer.visible_lines(); + scroll.layout -= buffer.visible_lines(); } _ => {} } diff --git a/examples/rich-text/src/main.rs b/examples/rich-text/src/main.rs index ec3501c..78d0774 100644 --- a/examples/rich-text/src/main.rs +++ b/examples/rich-text/src/main.rs @@ -131,7 +131,7 @@ fn main() { let bg_color = orbclient::Color::rgb(0x34, 0x34, 0x34); let font_color = Color::rgb(0xFF, 0xFF, 0xFF); - editor.shape_as_needed(); + editor.shape_as_needed(true); if editor.buffer().redraw() { let instant = Instant::now(); diff --git a/examples/terminal/src/main.rs b/examples/terminal/src/main.rs index 4b70d28..1da762d 100644 --- a/examples/terminal/src/main.rs +++ b/examples/terminal/src/main.rs @@ -39,7 +39,7 @@ fn main() { buffer.set_text(&text, attrs, Shaping::Advanced); // Perform shaping as desired - buffer.shape_until_scroll(); + buffer.shape_until_scroll(true); // Default text color (0xFF, 0xFF, 0xFF is white) const TEXT_COLOR: Color = Color::rgb(0xFF, 0xFF, 0xFF); diff --git a/src/buffer.rs b/src/buffer.rs index 5e25faa..84fa34e 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -7,8 +7,8 @@ use unicode_segmentation::UnicodeSegmentation; use crate::{ Affinity, Attrs, AttrsList, BidiParagraphs, BorrowedWithFontSystem, BufferLine, Color, Cursor, - FontSystem, LayoutCursor, LayoutGlyph, LayoutLine, Motion, ShapeBuffer, ShapeLine, Shaping, - Wrap, + FontSystem, LayoutCursor, LayoutGlyph, LayoutLine, Motion, Scroll, ShapeBuffer, ShapeLine, + Shaping, Wrap, }; /// A line of visible text for rendering @@ -101,6 +101,7 @@ impl<'b> LayoutRunIter<'b> { let total_layout_lines: usize = buffer .lines .iter() + .skip(buffer.scroll.line) .map(|line| { line.layout_opt() .as_ref() @@ -109,7 +110,7 @@ impl<'b> LayoutRunIter<'b> { }) .sum(); let top_cropped_layout_lines = - total_layout_lines.saturating_sub(buffer.scroll.try_into().unwrap_or_default()); + total_layout_lines.saturating_sub(buffer.scroll.layout.try_into().unwrap_or_default()); let maximum_lines = if buffer.metrics.line_height == 0.0 { 0 } else { @@ -124,7 +125,7 @@ impl<'b> LayoutRunIter<'b> { Self { buffer, - line_i: 0, + line_i: buffer.scroll.line, layout_i: 0, remaining_len: bottom_cropped_layout_lines, total_layout: 0, @@ -146,7 +147,7 @@ impl<'b> Iterator for LayoutRunIter<'b> { while let Some(layout_line) = layout.get(self.layout_i) { self.layout_i += 1; - let scrolled = self.total_layout < self.buffer.scroll; + let scrolled = self.total_layout < self.buffer.scroll.layout; self.total_layout += 1; if scrolled { continue; @@ -154,7 +155,7 @@ impl<'b> Iterator for LayoutRunIter<'b> { let line_top = self .total_layout - .saturating_sub(self.buffer.scroll) + .saturating_sub(self.buffer.scroll.layout) .saturating_sub(1) as f32 * self.buffer.metrics.line_height; let glyph_height = layout_line.max_ascent + layout_line.max_descent; @@ -227,7 +228,7 @@ pub struct Buffer { metrics: Metrics, width: f32, height: f32, - scroll: i32, + scroll: Scroll, /// True if a redraw is requires. Set to false after processing redraw: bool, wrap: Wrap, @@ -255,7 +256,7 @@ impl Buffer { metrics, width: 0.0, height: 0.0, - scroll: 0, + scroll: Scroll::default(), redraw: false, wrap: Wrap::Word, scratch: ShapeBuffer::default(), @@ -307,96 +308,119 @@ impl Buffer { log::debug!("relayout: {:?}", instant.elapsed()); } - /// Pre-shape lines in the buffer, up to `lines`, return actual number of layout lines - pub fn shape_until(&mut self, font_system: &mut FontSystem, lines: i32) -> i32 { - #[cfg(all(feature = "std", not(target_arch = "wasm32")))] - let instant = std::time::Instant::now(); - - let mut reshaped = 0; - let mut total_layout = 0; - for line in &mut self.lines { - if total_layout >= lines { - break; - } - - if line.shape_opt().is_none() { - reshaped += 1; - } - let layout = line.layout_in_buffer( - &mut self.scratch, - font_system, - self.metrics.font_size, - self.width, - self.wrap, - ); - total_layout += layout.len() as i32; - } - - if reshaped > 0 { - #[cfg(all(feature = "std", not(target_arch = "wasm32")))] - log::debug!("shape_until {}: {:?}", reshaped, instant.elapsed()); - self.redraw = true; - } - - total_layout - } - /// Shape lines until cursor, also scrolling to include cursor in view - pub fn shape_until_cursor(&mut self, font_system: &mut FontSystem, cursor: Cursor) { - #[cfg(all(feature = "std", not(target_arch = "wasm32")))] - let instant = std::time::Instant::now(); + pub fn shape_until_cursor( + &mut self, + font_system: &mut FontSystem, + cursor: Cursor, + prune: bool, + ) { + let old_scroll = self.scroll; - let mut reshaped = 0; - let mut layout_i = 0; - for (line_i, line) in self.lines.iter_mut().enumerate() { - if line_i > cursor.line { - break; - } + let layout_cursor = self + .layout_cursor(font_system, cursor) + .expect("shape_until_cursor invalid cursor"); - if line.shape_opt().is_none() { - reshaped += 1; - } - let layout = line.layout_in_buffer( - &mut self.scratch, - font_system, - self.metrics.font_size, - self.width, - self.wrap, - ); - if line_i == cursor.line { - if let Some(layout_cursor) = self.layout_cursor(font_system, cursor) { - layout_i += layout_cursor.layout as i32; + if self.scroll.line > layout_cursor.line + || (self.scroll.line == layout_cursor.line + && self.scroll.layout > layout_cursor.layout as i32) + { + // Adjust scroll backwards if cursor is before it + self.scroll.line = layout_cursor.line; + self.scroll.layout = layout_cursor.layout as i32; + } else { + // Adjust scroll forwards if cursor is after it + let visible_lines = self.visible_lines(); + let mut line_i = layout_cursor.line; + let mut total_layout = layout_cursor.layout as i32 + 1; + while line_i > self.scroll.line { + line_i -= 1; + let layout = self + .line_layout(font_system, line_i) + .expect("shape_until_cursor failed to scroll forwards"); + for layout_i in (0..layout.len()).rev() { + total_layout += 1; + if total_layout >= visible_lines { + self.scroll.line = line_i; + self.scroll.layout = layout_i as i32; + break; + } } - break; - } else { - layout_i += layout.len() as i32; } } - if reshaped > 0 { - #[cfg(all(feature = "std", not(target_arch = "wasm32")))] - log::debug!("shape_until_cursor {}: {:?}", reshaped, instant.elapsed()); + if old_scroll != self.scroll { self.redraw = true; } - let lines = self.visible_lines(); - if layout_i < self.scroll { - self.scroll = layout_i; - } else if layout_i >= self.scroll + lines { - self.scroll = layout_i - (lines - 1); - } - - self.shape_until_scroll(font_system); + self.shape_until_scroll(font_system, prune); } /// Shape lines until scroll - pub fn shape_until_scroll(&mut self, font_system: &mut FontSystem) { - let lines = self.visible_lines(); + pub fn shape_until_scroll(&mut self, font_system: &mut FontSystem, prune: bool) { + let old_scroll = self.scroll; - let scroll_end = self.scroll + lines; - let total_layout = self.shape_until(font_system, scroll_end); + loop { + // Adjust scroll.layout to be positive by moving scroll.line backwards + while self.scroll.layout < 0 { + if self.scroll.line > 0 { + self.scroll.line -= 1; + let layout = self + .line_layout(font_system, self.scroll.line) + .expect("shape_until_scroll invalid scroll.line"); + self.scroll.layout += layout.len() as i32; + } else { + self.scroll.layout = 0; + break; + } + } - self.scroll = cmp::max(0, cmp::min(total_layout - lines, self.scroll)); + let visible_lines = self.visible_lines(); + let scroll_start = self.scroll.layout; + let scroll_end = scroll_start + visible_lines; + + let mut total_layout = 0; + for line_i in 0..self.lines.len() { + if line_i < self.scroll.line { + if prune { + self.lines[line_i].reset_shaping(); + } + continue; + } + if total_layout >= scroll_end { + if prune { + self.lines[line_i].reset_shaping(); + continue; + } else { + break; + } + } + + let layout = self + .line_layout(font_system, line_i) + .expect("shape_until_scroll invalid line"); + for layout_i in 0..layout.len() { + if total_layout == scroll_start { + // Adjust scroll.line and scroll.layout + self.scroll.line = line_i; + self.scroll.layout = layout_i as i32; + } + total_layout += 1; + } + } + + if total_layout < scroll_end && self.scroll.line > 0 { + // Need to scroll up to stay inside of buffer + self.scroll.layout -= scroll_end - total_layout; + } else { + // Done adjusting scroll + break; + } + } + + if old_scroll != self.scroll { + self.redraw = true; + } } /// Convert a [`Cursor`] to a [`LayoutCursor`] @@ -481,7 +505,7 @@ impl Buffer { if wrap != self.wrap { self.wrap = wrap; self.relayout(font_system); - self.shape_until_scroll(font_system); + self.shape_until_scroll(font_system, false); } } @@ -516,17 +540,17 @@ impl Buffer { self.width = clamped_width; self.height = clamped_height; self.relayout(font_system); - self.shape_until_scroll(font_system); + self.shape_until_scroll(font_system, false); } } /// Get the current scroll location - pub fn scroll(&self) -> i32 { + pub fn scroll(&self) -> Scroll { self.scroll } /// Set the current scroll location - pub fn set_scroll(&mut self, scroll: i32) { + pub fn set_scroll(&mut self, scroll: Scroll) { if scroll != self.scroll { self.scroll = scroll; self.redraw = true; @@ -651,9 +675,9 @@ impl Buffer { } } - self.scroll = 0; + self.scroll = Scroll::default(); - self.shape_until_scroll(font_system); + self.shape_until_scroll(font_system, false); } /// True if a redraw is needed @@ -1098,19 +1122,15 @@ impl Buffer { } impl<'a> BorrowedWithFontSystem<'a, Buffer> { - /// Pre-shape lines in the buffer, up to `lines`, return actual number of layout lines - pub fn shape_until(&mut self, lines: i32) -> i32 { - self.inner.shape_until(self.font_system, lines) - } - /// Shape lines until cursor, also scrolling to include cursor in view - pub fn shape_until_cursor(&mut self, cursor: Cursor) { - self.inner.shape_until_cursor(self.font_system, cursor); + pub fn shape_until_cursor(&mut self, cursor: Cursor, prune: bool) { + self.inner + .shape_until_cursor(self.font_system, cursor, prune); } /// Shape lines until scroll - pub fn shape_until_scroll(&mut self) { - self.inner.shape_until_scroll(self.font_system); + pub fn shape_until_scroll(&mut self, prune: bool) { + self.inner.shape_until_scroll(self.font_system, prune); } /// Shape the provided line index and return the result diff --git a/src/buffer_line.rs b/src/buffer_line.rs index 7d8e031..64f706c 100644 --- a/src/buffer_line.rs +++ b/src/buffer_line.rs @@ -13,6 +13,7 @@ pub struct BufferLine { shape_opt: Option, layout_opt: Option>, shaping: Shaping, + metadata: Option, } impl BufferLine { @@ -27,6 +28,7 @@ impl BufferLine { shape_opt: None, layout_opt: None, shaping, + metadata: None, } } @@ -69,7 +71,7 @@ impl BufferLine { pub fn set_attrs_list(&mut self, attrs_list: AttrsList) -> bool { if attrs_list != self.attrs_list { self.attrs_list = attrs_list; - self.reset(); + self.reset_shaping(); true } else { false @@ -129,23 +131,23 @@ impl BufferLine { new } - /// Reset shaping and layout information - //TODO: make this private + /// Reset shaping, layout, and metadata caches pub fn reset(&mut self) { - self.shape_opt = None; - self.layout_opt = None; + self.metadata = None; + self.reset_shaping(); } - /// Reset only layout information + /// Reset shaping and layout caches + pub fn reset_shaping(&mut self) { + self.shape_opt = None; + self.reset_layout(); + } + + /// Reset only layout cache pub fn reset_layout(&mut self) { self.layout_opt = None; } - /// Check if shaping and layout information is cleared - pub fn is_reset(&self) -> bool { - self.shape_opt.is_none() - } - /// Shape line, will cache results pub fn shape(&mut self, font_system: &mut FontSystem) -> &ShapeLine { self.shape_in_buffer(&mut ShapeBuffer::default(), font_system) @@ -215,4 +217,15 @@ impl BufferLine { pub fn layout_opt(&self) -> &Option> { &self.layout_opt } + + /// Get line metadata. This will be None if [`BufferLine::set_metadata`] has not been called + /// after the last reset of shaping and layout caches + pub fn metadata(&self) -> Option { + self.metadata + } + + /// Set line metadata. This is stored until the next line reset + pub fn set_metadata(&mut self, metadata: usize) { + self.metadata = Some(metadata); + } } diff --git a/src/cursor.rs b/src/cursor.rs index 4ea5e93..84e80e3 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -3,7 +3,7 @@ use crate::Color; /// Current cursor location #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd)] pub struct Cursor { - /// Text line the cursor is on + /// Index of [`BufferLine`] in [`Buffer::lines`] pub line: usize, /// First-byte-index of glyph at cursor (will insert behind this glyph) pub index: usize, @@ -81,8 +81,11 @@ impl Affinity { /// The position of a cursor within a [`Buffer`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct LayoutCursor { + /// Index of [`BufferLine`] in [`Buffer::lines`] pub line: usize, + /// Index of [`LayoutLine`] in [`BufferLine::layout`] pub layout: usize, + /// Index of [`LayoutGlyph`] in [`LayoutLine::glyphs`] pub glyph: usize, } @@ -145,3 +148,14 @@ pub enum Motion { /// Move cursor to specific line GotoLine(usize), } + +/// Scroll position in [`Buffer`] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct Scroll { + /// Index of [`BufferLine`] in [`Buffer::lines`]. This will be adjusted as needed if layout is + /// out of bounds + pub line: usize, + /// Index of [`LayoutLine`] in [`BufferLine::layout`]. This will be adjusted as needed + /// if it is negative or exceeds the number of layout lines + pub layout: i32, +} diff --git a/src/edit/editor.rs b/src/edit/editor.rs index 622899d..fb670d4 100644 --- a/src/edit/editor.rs +++ b/src/edit/editor.rs @@ -94,12 +94,13 @@ impl Edit for Editor { } } - fn shape_as_needed(&mut self, font_system: &mut FontSystem) { + fn shape_as_needed(&mut self, font_system: &mut FontSystem, prune: bool) { if self.cursor_moved { - self.buffer.shape_until_cursor(font_system, self.cursor); + self.buffer + .shape_until_cursor(font_system, self.cursor, prune); self.cursor_moved = false; } else { - self.buffer.shape_until_scroll(font_system); + self.buffer.shape_until_scroll(font_system, prune); } } @@ -627,7 +628,7 @@ impl Edit for Editor { } Action::Scroll { lines } => { let mut scroll = self.buffer.scroll(); - scroll += lines; + scroll.layout += lines; self.buffer.set_scroll(scroll); } } diff --git a/src/edit/mod.rs b/src/edit/mod.rs index 8c8c0c8..fc938b3 100644 --- a/src/edit/mod.rs +++ b/src/edit/mod.rs @@ -231,7 +231,7 @@ pub trait Edit { fn set_tab_width(&mut self, tab_width: u16); /// Shape lines until scroll, after adjusting scroll if the cursor moved - fn shape_as_needed(&mut self, font_system: &mut FontSystem); + fn shape_as_needed(&mut self, font_system: &mut FontSystem, prune: bool); /// Delete text starting at start Cursor and ending at end Cursor fn delete_range(&mut self, start: Cursor, end: Cursor); @@ -288,8 +288,8 @@ impl<'a, T: Edit> BorrowedWithFontSystem<'a, T> { } /// Shape lines until scroll, after adjusting scroll if the cursor moved - pub fn shape_as_needed(&mut self) { - self.inner.shape_as_needed(self.font_system); + pub fn shape_as_needed(&mut self, prune: bool) { + self.inner.shape_as_needed(self.font_system, prune); } /// Perform an [Action] on the editor diff --git a/src/edit/syntect.rs b/src/edit/syntect.rs index 00da3bf..750f561 100644 --- a/src/edit/syntect.rs +++ b/src/edit/syntect.rs @@ -206,14 +206,15 @@ impl<'a> Edit for SyntaxEditor<'a> { self.editor.set_tab_width(tab_width); } - fn shape_as_needed(&mut self, font_system: &mut FontSystem) { + fn shape_as_needed(&mut self, font_system: &mut FontSystem, prune: bool) { #[cfg(feature = "std")] let now = std::time::Instant::now(); let cursor = self.cursor(); let buffer = self.editor.buffer_mut(); - let lines = buffer.visible_lines(); - let scroll_end = buffer.scroll() + lines; + let visible_lines = buffer.visible_lines(); + let scroll = buffer.scroll(); + let scroll_end = scroll.layout + visible_lines; let mut total_layout = 0; let mut highlighted = 0; for line_i in 0..buffer.lines.len() { @@ -223,15 +224,17 @@ impl<'a> Edit for SyntaxEditor<'a> { } let line = &mut buffer.lines[line_i]; - if !line.is_reset() && line_i < self.syntax_cache.len() { + if line.metadata().is_some() && line_i < self.syntax_cache.len() { //TODO: duplicated code! - // Perform shaping and layout of this line in order to count if we have reached scroll - match buffer.line_layout(font_system, line_i) { - Some(layout_lines) => { - total_layout += layout_lines.len() as i32; - } - None => { - //TODO: should this be possible? + if line_i >= scroll.line && total_layout < scroll_end { + // Perform shaping and layout of this line in order to count if we have reached scroll + match buffer.line_layout(font_system, line_i) { + Some(layout_lines) => { + total_layout += layout_lines.len() as i32; + } + None => { + //TODO: should this be possible? + } } } continue; @@ -285,12 +288,14 @@ impl<'a> Edit for SyntaxEditor<'a> { line.set_attrs_list(attrs_list); // Perform shaping and layout of this line in order to count if we have reached scroll - match buffer.line_layout(font_system, line_i) { - Some(layout_lines) => { - total_layout += layout_lines.len() as i32; - } - None => { - //TODO: should this be possible? + if line_i >= scroll.line && total_layout < scroll_end { + match buffer.line_layout(font_system, line_i) { + Some(layout_lines) => { + total_layout += layout_lines.len() as i32; + } + None => { + //TODO: should this be possible? + } } } @@ -303,6 +308,7 @@ impl<'a> Edit for SyntaxEditor<'a> { } } } else { + buffer.lines[line_i].set_metadata(self.syntax_cache.len()); self.syntax_cache.push(cache_item); } } @@ -317,7 +323,7 @@ impl<'a> Edit for SyntaxEditor<'a> { ); } - self.editor.shape_as_needed(font_system); + self.editor.shape_as_needed(font_system, prune); } fn delete_range(&mut self, start: Cursor, end: Cursor) { diff --git a/src/edit/vi.rs b/src/edit/vi.rs index b95fe10..868651b 100644 --- a/src/edit/vi.rs +++ b/src/edit/vi.rs @@ -291,8 +291,8 @@ impl<'a> Edit for ViEditor<'a> { self.editor.set_tab_width(tab_width); } - fn shape_as_needed(&mut self, font_system: &mut FontSystem) { - self.editor.shape_as_needed(font_system); + fn shape_as_needed(&mut self, font_system: &mut FontSystem, prune: bool) { + self.editor.shape_as_needed(font_system, prune); } fn delete_range(&mut self, start: Cursor, end: Cursor) { @@ -443,8 +443,8 @@ impl<'a> Edit for ViEditor<'a> { editor.insert_at(cursor, "\n", None); editor.insert_at(cursor, data, None); - // Hack to allow immediate up/down - editor.shape_as_needed(font_system); + //TODO: Hack to allow immediate up/down + editor.shape_as_needed(font_system, false); // Move to inserted line, preserving cursor x position if after { diff --git a/src/font/system.rs b/src/font/system.rs index eaefe2b..19e8304 100644 --- a/src/font/system.rs +++ b/src/font/system.rs @@ -177,7 +177,7 @@ impl FontSystem { } #[cfg(not(target_arch = "wasm32"))] - log::info!( + log::debug!( "Parsed {} font faces in {}ms.", db.len(), now.elapsed().as_millis() diff --git a/src/lib.rs b/src/lib.rs index 7d5a120..b15eb1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,7 @@ //! buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced); //! //! // Perform shaping as desired -//! buffer.shape_until_scroll(); +//! buffer.shape_until_scroll(true); //! //! // Inspect the output runs //! for run in buffer.layout_runs() { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 9e250f8..20617d6 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -93,7 +93,7 @@ impl DrawTestCfg { (self.canvas_height - margins * 2) as f32, ); buffer.set_text(&self.text, self.font.as_attrs(), Shaping::Advanced); - buffer.shape_until_scroll(); + buffer.shape_until_scroll(true); // Black let text_color = Color::rgb(0x00, 0x00, 0x00);