diff --git a/examples/editor-libcosmic/src/main.rs b/examples/editor-libcosmic/src/main.rs index 522b111..5f47d23 100644 --- a/examples/editor-libcosmic/src/main.rs +++ b/examples/editor-libcosmic/src/main.rs @@ -23,7 +23,6 @@ use cosmic_text::{ }; use std::{ env, - fmt, fs, sync::{Arc, Mutex}, }; @@ -135,8 +134,7 @@ impl Application for Window { } fn title(&self) -> String { - let buffer = self.buffer.lock().unwrap(); - format!("COSMIC Text - iced - {}", buffer.font_matches().locale) + format!("COSMIC Text - iced - {}", FONT_SYSTEM.locale) } fn update(&mut self, message: Message) -> iced::Command { diff --git a/examples/editor-libcosmic/src/text_box.rs b/examples/editor-libcosmic/src/text_box.rs index 037e9e5..f0d4789 100644 --- a/examples/editor-libcosmic/src/text_box.rs +++ b/examples/editor-libcosmic/src/text_box.rs @@ -12,7 +12,7 @@ use cosmic::iced_native::{ widget::{self, Widget}, }; use cosmic_text::{ - FontLineIndex, + TextLineIndex, TextAction, TextBuffer, }; @@ -136,7 +136,7 @@ where let line_x = layout.bounds().x as i32; let mut line_y = layout.bounds().y as i32 + font_size; let mut start_line_opt = None; - let mut end_line = FontLineIndex::new(0); + let mut end_line = TextLineIndex::new(0); for (line_i, line) in buffer .layout_lines() .iter() diff --git a/examples/editor-orbclient/src/main.rs b/examples/editor-orbclient/src/main.rs index 1038471..72fd3ce 100644 --- a/examples/editor-orbclient/src/main.rs +++ b/examples/editor-orbclient/src/main.rs @@ -1,6 +1,6 @@ -use cosmic_text::{FontLineIndex, FontSystem, TextAction, TextBuffer, TextCursor, TextMetrics}; +use cosmic_text::{FontSystem, TextAction, TextBuffer, TextCursor, TextLineIndex, TextMetrics}; use orbclient::{Color, EventOption, Renderer, Window, WindowFlag}; -use std::{cmp, env, fs, time::Instant}; +use std::{env, fs, time::Instant}; fn main() { env_logger::init(); @@ -156,7 +156,7 @@ fn main() { let mut line_y = line_height; let mut start_line_opt = None; - let mut end_line = FontLineIndex::new(0); + let mut end_line = TextLineIndex::new(0); for (line_i, line) in buffer .layout_lines() .iter() diff --git a/src/buffer.rs b/src/buffer.rs index 959f0d5..68b6047 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -4,8 +4,9 @@ use std::{ time::Instant, }; -use crate::{FontLayoutLine, FontLineIndex, FontMatches, FontShapeLine}; +use crate::{FontLayoutLine, FontMatches, FontShapeLine}; +/// An action to perform on a [TextBuffer] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TextAction { Left, @@ -21,6 +22,7 @@ pub enum TextAction { Scroll(i32), } +/// Current cursor location #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct TextCursor { pub line: usize, @@ -33,9 +35,26 @@ impl TextCursor { } } +/// Index of a text line +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] +pub struct TextLineIndex(usize); + +impl TextLineIndex { + pub fn new(index: usize) -> Self { + Self(index) + } + + pub fn get(&self) -> usize { + self.0 + } +} + +/// Metrics of text #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct TextMetrics { + /// Font size in pixels pub font_size: i32, + /// Line height in pixels pub line_height: i32, } @@ -58,6 +77,7 @@ impl fmt::Display for TextMetrics { } } +/// A buffer of text that is shaped and laid out pub struct TextBuffer<'a> { font_matches: &'a FontMatches<'a>, text_lines: Vec, @@ -95,7 +115,7 @@ impl<'a> TextBuffer<'a> { } } - ///TODO: do not allow access + /// Pre-shape lines in the buffer, up to `lines` pub fn shape_until(&mut self, lines: i32) { let instant = Instant::now(); @@ -103,7 +123,7 @@ impl<'a> TextBuffer<'a> { while self.shape_lines.len() < self.text_lines.len() && (self.layout_lines.len() as i32) < lines { - let line_i = FontLineIndex::new(self.shape_lines.len()); + let line_i = TextLineIndex::new(self.shape_lines.len()); self.reshape_line(line_i); reshaped += 1; } @@ -129,7 +149,7 @@ impl<'a> TextBuffer<'a> { ); } - fn reshape_line(&mut self, line_i: FontLineIndex) { + fn reshape_line(&mut self, line_i: TextLineIndex) { let instant = Instant::now(); let shape_line = self @@ -167,7 +187,7 @@ impl<'a> TextBuffer<'a> { log::debug!("relayout: {:?}", duration); } - fn relayout_line(&mut self, line_i: FontLineIndex) { + fn relayout_line(&mut self, line_i: TextLineIndex) { let instant = Instant::now(); let mut insert_opt = None; @@ -200,10 +220,6 @@ impl<'a> TextBuffer<'a> { log::debug!("relayout line {}: {:?}", line_i.get(), duration); } - pub fn font_matches(&self) -> &FontMatches { - &self.font_matches - } - /// Get the current [TextMetrics] pub fn metrics(&self) -> TextMetrics { self.metrics diff --git a/src/font/font.rs b/src/font/font.rs new file mode 100644 index 0000000..f7f22ff --- /dev/null +++ b/src/font/font.rs @@ -0,0 +1,27 @@ +use std::{collections::HashMap, sync::Mutex}; + +use super::{CacheKey, CacheItem}; + +pub struct Font<'a> { + pub info: &'a fontdb::FaceInfo, + pub data: &'a [u8], + pub index: u32, + pub rustybuzz: rustybuzz::Face<'a>, + pub swash: swash::FontRef<'a>, + pub scale_context: Mutex, + pub cache: Mutex>, +} + +impl<'a> Font<'a> { + pub fn new(info: &'a fontdb::FaceInfo, data: &'a [u8], index: u32) -> Option { + Some(Self { + info, + data, + index, + rustybuzz: rustybuzz::Face::from_slice(data, index)?, + swash: swash::FontRef::from_index(data, index as usize)?, + scale_context: Mutex::new(swash::scale::ScaleContext::new()), + cache: Mutex::new(HashMap::new()), + }) + } +} diff --git a/src/font/layout.rs b/src/font/layout.rs index 86c4225..076e2fe 100644 --- a/src/font/layout.rs +++ b/src/font/layout.rs @@ -1,4 +1,5 @@ -use super::{CacheKey, Font, FontLineIndex}; +use crate::TextLineIndex; +use super::{CacheKey, Font}; pub struct FontLayoutGlyph<'a> { pub start: usize, @@ -10,7 +11,7 @@ pub struct FontLayoutGlyph<'a> { } pub struct FontLayoutLine<'a> { - pub line_i: FontLineIndex, + pub line_i: TextLineIndex, pub glyphs: Vec>, } diff --git a/src/font/matches.rs b/src/font/matches.rs index 5c4455b..259c241 100644 --- a/src/font/matches.rs +++ b/src/font/matches.rs @@ -1,8 +1,10 @@ use unicode_script::{Script, UnicodeScript}; -use super::{Font, FontLineIndex, FontShapeGlyph, FontShapeLine, FontShapeSpan, FontShapeWord}; +use crate::TextLineIndex; +use super::{Font, FontShapeGlyph, FontShapeLine, FontShapeSpan, FontShapeWord}; use super::fallback::{FontFallbackIter}; +/// Fonts that match a pattern pub struct FontMatches<'a> { pub locale: &'a str, pub fonts: Vec>, @@ -285,7 +287,7 @@ impl<'a> FontMatches<'a> { } } - pub fn shape_line(&self, line_i: FontLineIndex, line: &str) -> FontShapeLine { + pub fn shape_line(&self, line_i: TextLineIndex, line: &str) -> FontShapeLine { let mut spans = Vec::new(); let bidi = unicode_bidi::BidiInfo::new(line, None); diff --git a/src/font/mod.rs b/src/font/mod.rs index 2f7f459..f7c2b5b 100644 --- a/src/font/mod.rs +++ b/src/font/mod.rs @@ -1,60 +1,19 @@ -use std::{collections::HashMap, sync::Mutex}; +pub(crate) mod fallback; -pub mod fallback; - -pub use self::cache::*; +pub(crate) use self::cache::*; mod cache; -pub use self::layout::*; +pub(crate) use self::font::*; +mod font; + +pub(crate) use self::layout::*; mod layout; pub use self::matches::*; mod matches; -pub use self::shape::*; +pub(crate) use self::shape::*; mod shape; pub use self::system::*; mod system; - -#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct FontCacheKey { - glyph_id: u16, -} - -#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub struct FontLineIndex(usize); - -impl FontLineIndex { - pub fn new(index: usize) -> Self { - Self(index) - } - - pub fn get(&self) -> usize { - self.0 - } -} - -pub struct Font<'a> { - pub info: &'a fontdb::FaceInfo, - pub data: &'a [u8], - pub index: u32, - pub rustybuzz: rustybuzz::Face<'a>, - pub swash: swash::FontRef<'a>, - pub scale_context: Mutex, - pub cache: Mutex>, -} - -impl<'a> Font<'a> { - pub fn new(info: &'a fontdb::FaceInfo, data: &'a [u8], index: u32) -> Option { - Some(Self { - info, - data, - index, - rustybuzz: rustybuzz::Face::from_slice(data, index)?, - swash: swash::FontRef::from_index(data, index as usize)?, - scale_context: Mutex::new(swash::scale::ScaleContext::new()), - cache: Mutex::new(HashMap::new()), - }) - } -} diff --git a/src/font/shape.rs b/src/font/shape.rs index 67afd32..48ac024 100644 --- a/src/font/shape.rs +++ b/src/font/shape.rs @@ -1,4 +1,5 @@ -use super::{CacheKey, Font, FontLayoutGlyph, FontLayoutLine, FontLineIndex}; +use crate::TextLineIndex; +use super::{CacheKey, Font, FontLayoutGlyph, FontLayoutLine}; pub struct FontShapeGlyph<'a> { pub start: usize, @@ -40,7 +41,7 @@ pub struct FontShapeSpan<'a> { } pub struct FontShapeLine<'a> { - pub line_i: FontLineIndex, + pub line_i: TextLineIndex, pub rtl: bool, pub spans: Vec>, } diff --git a/src/font/system.rs b/src/font/system.rs index d008cfd..5ccae48 100644 --- a/src/font/system.rs +++ b/src/font/system.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use super::{Font, FontMatches}; +/// Access system fonts pub struct FontSystem { pub locale: String, db: fontdb::Database,