Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize for single-line single-span single-word text #311

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rangemap = "1.4.0"
rustc-hash = { version = "1.1.0", default-features = false }
rustybuzz = { version = "0.14", default-features = false, features = ["libm"] }
self_cell = "1.0.1"
smallvec = { version = "1.13.2", optional = true }
smol_str = { version = "0.2.2", default-features = false }
swash = { version = "0.1.17", optional = true }
syntect = { version = "5.1.0", optional = true }
Expand All @@ -42,6 +43,7 @@ fontconfig = ["fontdb/fontconfig", "std"]
monospace_fallback = []
no_std = ["rustybuzz/libm", "hashbrown", "dep:libm"]
shape-run-cache = []
small-buffer-opt = ["smallvec"]
std = [
"fontdb/memmap",
"fontdb/std",
Expand Down
10 changes: 5 additions & 5 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use core::{cmp, fmt};
use unicode_segmentation::UnicodeSegmentation;

use crate::{
Affinity, Align, Attrs, AttrsList, BidiParagraphs, BorrowedWithFontSystem, BufferLine, Color,
Cursor, FontSystem, LayoutCursor, LayoutGlyph, LayoutLine, LineEnding, LineIter, Motion,
Scroll, ShapeLine, Shaping, Wrap,
Affinity, Align, Attrs, AttrsList, BidiParagraphs, BorrowedWithFontSystem, BufferLine,
BufferVec, Color, Cursor, FontSystem, LayoutCursor, LayoutGlyph, LayoutLine, LineEnding,
LineIter, Motion, Scroll, ShapeLine, Shaping, Wrap,
};

/// A line of visible text for rendering
Expand Down Expand Up @@ -203,7 +203,7 @@ impl fmt::Display for Metrics {
#[derive(Debug)]
pub struct Buffer {
/// [BufferLine]s (or paragraphs) of text in the buffer
pub lines: Vec<BufferLine>,
pub lines: BufferVec<BufferLine>,
metrics: Metrics,
width_opt: Option<f32>,
height_opt: Option<f32>,
Expand Down Expand Up @@ -246,7 +246,7 @@ impl Buffer {
pub fn new_empty(metrics: Metrics) -> Self {
assert_ne!(metrics.line_height, 0.0, "line height cannot be 0");
Self {
lines: Vec::new(),
lines: BufferVec::new(),
metrics,
width_opt: None,
height_opt: None,
Expand Down
9 changes: 5 additions & 4 deletions src/buffer_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use alloc::{string::String, vec::Vec};
use core::mem;

use crate::{
Align, Attrs, AttrsList, Cached, FontSystem, LayoutLine, LineEnding, ShapeLine, Shaping, Wrap,
Align, Attrs, AttrsList, BufferVec, Cached, FontSystem, LayoutLine, LineEnding, ShapeLine,
Shaping, Wrap,
};

/// A line (or paragraph) of text that is shaped and laid out
Expand All @@ -14,7 +15,7 @@ pub struct BufferLine {
attrs_list: AttrsList,
align: Option<Align>,
shape_opt: Cached<ShapeLine>,
layout_opt: Cached<Vec<LayoutLine>>,
layout_opt: Cached<BufferVec<LayoutLine>>,
shaping: Shaping,
metadata: Option<usize>,
}
Expand Down Expand Up @@ -242,7 +243,7 @@ impl BufferLine {
let mut layout = self
.layout_opt
.take_unused()
.unwrap_or_else(|| Vec::with_capacity(1));
.unwrap_or_else(|| BufferVec::with_capacity(1));
let shape = self.shape(font_system, tab_width);
shape.layout_to_buffer(
&mut font_system.shape_buffer,
Expand All @@ -259,7 +260,7 @@ impl BufferLine {
}

/// Get line layout cache
pub fn layout_opt(&self) -> Option<&Vec<LayoutLine>> {
pub fn layout_opt(&self) -> Option<&BufferVec<LayoutLine>> {
self.layout_opt.get()
}

Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,10 @@ type BuildHasher = core::hash::BuildHasherDefault<rustc_hash::FxHasher>;
type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasher>;
#[cfg(not(feature = "std"))]
type HashMap<K, V> = hashbrown::HashMap<K, V, BuildHasher>;

#[cfg(all(not(feature = "small-buffer-opt"), feature = "std"))]
type BufferVec<T> = Vec<T>;
#[cfg(all(not(feature = "small-buffer-opt"), not(feature = "std")))]
type BufferVec<T> = alloc::vec::Vec<T>;
#[cfg(feature = "small-buffer-opt")]
type BufferVec<T> = smallvec::SmallVec<[T; 1]>;
20 changes: 10 additions & 10 deletions src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use unicode_segmentation::UnicodeSegmentation;

use crate::fallback::FontFallbackIter;
use crate::{
math, Align, AttrsList, CacheKeyFlags, Color, Font, FontSystem, LayoutGlyph, LayoutLine,
Metrics, ShapePlanCache, Wrap,
math, Align, AttrsList, BufferVec, CacheKeyFlags, Color, Font, FontSystem, LayoutGlyph,
LayoutLine, Metrics, ShapePlanCache, Wrap,
};

/// The shaping strategy of some text.
Expand Down Expand Up @@ -661,7 +661,7 @@ impl ShapeWord {
#[derive(Clone, Debug)]
pub struct ShapeSpan {
pub level: unicode_bidi::Level,
pub words: Vec<ShapeWord>,
pub words: BufferVec<ShapeWord>,
}

impl ShapeSpan {
Expand All @@ -671,7 +671,7 @@ impl ShapeSpan {
pub(crate) fn empty() -> Self {
Self {
level: unicode_bidi::Level::ltr(),
words: Vec::default(),
words: BufferVec::default(),
}
}

Expand Down Expand Up @@ -726,7 +726,7 @@ impl ShapeSpan {
cached_words.clear();
if line_rtl != level.is_rtl() {
// Un-reverse previous words so the internal glyph counts match accurately when rewriting memory.
cached_words.append(&mut words);
cached_words.extend(words.drain(..));
} else {
cached_words.extend(words.drain(..).rev());
}
Expand Down Expand Up @@ -802,7 +802,7 @@ impl ShapeSpan {
#[derive(Clone, Debug)]
pub struct ShapeLine {
pub rtl: bool,
pub spans: Vec<ShapeSpan>,
pub spans: BufferVec<ShapeSpan>,
pub metrics_opt: Option<Metrics>,
}

Expand Down Expand Up @@ -831,7 +831,7 @@ impl ShapeLine {
pub(crate) fn empty() -> Self {
Self {
rtl: false,
spans: Vec::default(),
spans: BufferVec::default(),
metrics_opt: None,
}
}
Expand Down Expand Up @@ -1082,8 +1082,8 @@ impl ShapeLine {
wrap: Wrap,
align: Option<Align>,
match_mono_width: Option<f32>,
) -> Vec<LayoutLine> {
let mut lines = Vec::with_capacity(1);
) -> BufferVec<LayoutLine> {
let mut lines = BufferVec::with_capacity(1);
self.layout_to_buffer(
&mut ShapeBuffer::default(),
font_size,
Expand All @@ -1103,7 +1103,7 @@ impl ShapeLine {
width_opt: Option<f32>,
wrap: Wrap,
align: Option<Align>,
layout_lines: &mut Vec<LayoutLine>,
layout_lines: &mut BufferVec<LayoutLine>,
match_mono_width: Option<f32>,
) {
// For each visual line a list of (span index, and range of words in that span)
Expand Down
Loading