Remove Mutex from FontSystem
This commit is contained in:
parent
46e9ef0246
commit
384c5c1fdc
16 changed files with 109 additions and 96 deletions
|
|
@ -139,7 +139,10 @@ impl Application for Window {
|
||||||
.family(cosmic_text::Family::Monospace);
|
.family(cosmic_text::Family::Monospace);
|
||||||
|
|
||||||
let mut editor = SyntaxEditor::new(
|
let mut editor = SyntaxEditor::new(
|
||||||
Buffer::new(&FONT_SYSTEM.lock().unwrap(), FontSize::Body.to_metrics()),
|
Buffer::new(
|
||||||
|
&mut FONT_SYSTEM.lock().unwrap(),
|
||||||
|
FontSize::Body.to_metrics(),
|
||||||
|
),
|
||||||
&SYNTAX_SYSTEM,
|
&SYNTAX_SYSTEM,
|
||||||
"base16-eighties.dark",
|
"base16-eighties.dark",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ impl Text {
|
||||||
let mut line = BufferLine::new(string, AttrsList::new(Attrs::new()));
|
let mut line = BufferLine::new(string, AttrsList::new(Attrs::new()));
|
||||||
|
|
||||||
//TODO: do we have to immediately shape?
|
//TODO: do we have to immediately shape?
|
||||||
line.shape(&FONT_SYSTEM.lock().unwrap());
|
line.shape(&mut FONT_SYSTEM.lock().unwrap());
|
||||||
|
|
||||||
let text = Self {
|
let text = Self {
|
||||||
line,
|
line,
|
||||||
|
|
@ -186,7 +186,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
cache.with_pixels(
|
cache.with_pixels(
|
||||||
&FONT_SYSTEM.lock().unwrap(),
|
&mut FONT_SYSTEM.lock().unwrap(),
|
||||||
cache_key,
|
cache_key,
|
||||||
glyph_color,
|
glyph_color,
|
||||||
|pixel_x, pixel_y, color| {
|
|pixel_x, pixel_y, color| {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ fn main() {
|
||||||
let line_x = 8.0 * display_scale;
|
let line_x = 8.0 * display_scale;
|
||||||
|
|
||||||
let mut editor = SyntaxEditor::new(
|
let mut editor = SyntaxEditor::new(
|
||||||
Buffer::new(&font_system, font_sizes[font_size_i]),
|
Buffer::new(&mut font_system, font_sizes[font_size_i]),
|
||||||
&syntax_system,
|
&syntax_system,
|
||||||
"base16-eighties.dark",
|
"base16-eighties.dark",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ fn main() {
|
||||||
];
|
];
|
||||||
let font_size_default = 1; // Body
|
let font_size_default = 1; // Body
|
||||||
|
|
||||||
let mut buffer = Buffer::new(&font_system, font_sizes[font_size_default]);
|
let mut buffer = Buffer::new(&mut font_system, font_sizes[font_size_default]);
|
||||||
buffer
|
buffer
|
||||||
.borrow_with(&mut font_system)
|
.borrow_with(&mut font_system)
|
||||||
.set_size(window.width() as f32, window.height() as f32);
|
.set_size(window.width() as f32, window.height() as f32);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut editor = Editor::new(Buffer::new(
|
let mut editor = Editor::new(Buffer::new(
|
||||||
&font_system,
|
&mut font_system,
|
||||||
Metrics::new(32.0, 44.0).scale(display_scale),
|
Metrics::new(32.0, 44.0).scale(display_scale),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ fn main() {
|
||||||
let metrics = Metrics::new(14.0, 20.0);
|
let metrics = Metrics::new(14.0, 20.0);
|
||||||
|
|
||||||
// A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
|
// A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
|
||||||
let mut buffer = Buffer::new(&font_system, metrics);
|
let mut buffer = Buffer::new(&mut font_system, metrics);
|
||||||
|
|
||||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ impl Buffer {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Will panic if `metrics.line_height` is zero.
|
/// Will panic if `metrics.line_height` is zero.
|
||||||
pub fn new(font_system: &FontSystem, metrics: Metrics) -> Self {
|
pub fn new(font_system: &mut FontSystem, metrics: Metrics) -> Self {
|
||||||
assert_ne!(metrics.line_height, 0.0, "line height cannot be 0");
|
assert_ne!(metrics.line_height, 0.0, "line height cannot be 0");
|
||||||
|
|
||||||
let mut buffer = Self {
|
let mut buffer = Self {
|
||||||
|
|
@ -343,7 +343,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn relayout(&mut self, font_system: &FontSystem) {
|
pub(crate) fn relayout(&mut self, font_system: &mut FontSystem) {
|
||||||
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
||||||
let instant = std::time::Instant::now();
|
let instant = std::time::Instant::now();
|
||||||
|
|
||||||
|
|
@ -360,7 +360,7 @@ impl Buffer {
|
||||||
log::debug!("relayout: {:?}", instant.elapsed());
|
log::debug!("relayout: {:?}", instant.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn shape_until(&mut self, font_system: &FontSystem, lines: i32) -> i32 {
|
pub(crate) fn shape_until(&mut self, font_system: &mut FontSystem, lines: i32) -> i32 {
|
||||||
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
||||||
let instant = std::time::Instant::now();
|
let instant = std::time::Instant::now();
|
||||||
|
|
||||||
|
|
@ -387,7 +387,7 @@ impl Buffer {
|
||||||
total_layout
|
total_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn shape_until_cursor(&mut self, font_system: &FontSystem, cursor: Cursor) {
|
pub(crate) fn shape_until_cursor(&mut self, font_system: &mut FontSystem, cursor: Cursor) {
|
||||||
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
|
||||||
let instant = std::time::Instant::now();
|
let instant = std::time::Instant::now();
|
||||||
|
|
||||||
|
|
@ -427,7 +427,7 @@ impl Buffer {
|
||||||
self.shape_until_scroll(font_system);
|
self.shape_until_scroll(font_system);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn shape_until_scroll(&mut self, font_system: &FontSystem) {
|
pub(crate) fn shape_until_scroll(&mut self, font_system: &mut FontSystem) {
|
||||||
let lines = self.visible_lines();
|
let lines = self.visible_lines();
|
||||||
|
|
||||||
let scroll_end = self.scroll + lines;
|
let scroll_end = self.scroll + lines;
|
||||||
|
|
@ -468,7 +468,7 @@ impl Buffer {
|
||||||
|
|
||||||
pub(crate) fn line_shape(
|
pub(crate) fn line_shape(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line_i: usize,
|
line_i: usize,
|
||||||
) -> Option<&ShapeLine> {
|
) -> Option<&ShapeLine> {
|
||||||
let line = self.lines.get_mut(line_i)?;
|
let line = self.lines.get_mut(line_i)?;
|
||||||
|
|
@ -477,7 +477,7 @@ impl Buffer {
|
||||||
|
|
||||||
pub(crate) fn line_layout(
|
pub(crate) fn line_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line_i: usize,
|
line_i: usize,
|
||||||
) -> Option<&[LayoutLine]> {
|
) -> Option<&[LayoutLine]> {
|
||||||
let line = self.lines.get_mut(line_i)?;
|
let line = self.lines.get_mut(line_i)?;
|
||||||
|
|
@ -489,7 +489,7 @@ impl Buffer {
|
||||||
self.metrics
|
self.metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_metrics(&mut self, font_system: &FontSystem, metrics: Metrics) {
|
fn set_metrics(&mut self, font_system: &mut FontSystem, metrics: Metrics) {
|
||||||
if metrics != self.metrics {
|
if metrics != self.metrics {
|
||||||
assert_ne!(metrics.font_size, 0.0, "font size cannot be 0");
|
assert_ne!(metrics.font_size, 0.0, "font size cannot be 0");
|
||||||
self.metrics = metrics;
|
self.metrics = metrics;
|
||||||
|
|
@ -503,7 +503,7 @@ impl Buffer {
|
||||||
self.wrap
|
self.wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_wrap(&mut self, font_system: &FontSystem, wrap: Wrap) {
|
pub(crate) fn set_wrap(&mut self, font_system: &mut FontSystem, wrap: Wrap) {
|
||||||
if wrap != self.wrap {
|
if wrap != self.wrap {
|
||||||
self.wrap = wrap;
|
self.wrap = wrap;
|
||||||
self.relayout(font_system);
|
self.relayout(font_system);
|
||||||
|
|
@ -516,7 +516,7 @@ impl Buffer {
|
||||||
(self.width, self.height)
|
(self.width, self.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_size(&mut self, font_system: &FontSystem, width: f32, height: f32) {
|
pub(crate) fn set_size(&mut self, font_system: &mut FontSystem, width: f32, height: f32) {
|
||||||
let clamped_width = width.max(0.0);
|
let clamped_width = width.max(0.0);
|
||||||
let clamped_height = height.max(0.0);
|
let clamped_height = height.max(0.0);
|
||||||
|
|
||||||
|
|
@ -546,7 +546,7 @@ impl Buffer {
|
||||||
(self.height / self.metrics.line_height) as i32
|
(self.height / self.metrics.line_height) as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_text(&mut self, font_system: &FontSystem, text: &str, attrs: Attrs) {
|
pub(crate) fn set_text(&mut self, font_system: &mut FontSystem, text: &str, attrs: Attrs) {
|
||||||
self.lines.clear();
|
self.lines.clear();
|
||||||
for line in text.lines() {
|
for line in text.lines() {
|
||||||
self.lines
|
self.lines
|
||||||
|
|
@ -682,7 +682,7 @@ impl Buffer {
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
pub(crate) fn draw<F>(
|
pub(crate) fn draw<F>(
|
||||||
&self,
|
&self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache: &mut crate::SwashCache,
|
cache: &mut crate::SwashCache,
|
||||||
color: Color,
|
color: Color,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
|
|
@ -758,7 +758,7 @@ impl<'a> BorrowedWithFontSystem<'a, Buffer> {
|
||||||
|
|
||||||
/// Draw the buffer
|
/// Draw the buffer
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
pub fn draw<F>(&self, cache: &mut crate::SwashCache, color: Color, f: F)
|
pub fn draw<F>(&mut self, cache: &mut crate::SwashCache, color: Color, f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(i32, i32, u32, u32, Color),
|
F: FnMut(i32, i32, u32, u32, Color),
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ impl BufferLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shape line, will cache results
|
/// Shape line, will cache results
|
||||||
pub fn shape(&mut self, font_system: &FontSystem) -> &ShapeLine {
|
pub fn shape(&mut self, font_system: &mut FontSystem) -> &ShapeLine {
|
||||||
if self.shape_opt.is_none() {
|
if self.shape_opt.is_none() {
|
||||||
self.shape_opt = Some(ShapeLine::new(font_system, &self.text, &self.attrs_list));
|
self.shape_opt = Some(ShapeLine::new(font_system, &self.text, &self.attrs_list));
|
||||||
self.layout_opt = None;
|
self.layout_opt = None;
|
||||||
|
|
@ -183,7 +183,7 @@ impl BufferLine {
|
||||||
/// Layout line, will cache results
|
/// Layout line, will cache results
|
||||||
pub fn layout(
|
pub fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
font_size: f32,
|
font_size: f32,
|
||||||
width: f32,
|
width: f32,
|
||||||
wrap: Wrap,
|
wrap: Wrap,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_layout_cursor(&mut self, font_system: &FontSystem, cursor: LayoutCursor) {
|
pub(crate) fn set_layout_cursor(&mut self, font_system: &mut FontSystem, cursor: LayoutCursor) {
|
||||||
let layout = self
|
let layout = self
|
||||||
.buffer
|
.buffer
|
||||||
.line_layout(font_system, cursor.line)
|
.line_layout(font_system, cursor.line)
|
||||||
|
|
@ -94,7 +94,7 @@ impl Edit for Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_as_needed(&mut self, font_system: &FontSystem) {
|
fn shape_as_needed(&mut self, font_system: &mut FontSystem) {
|
||||||
if self.cursor_moved {
|
if self.cursor_moved {
|
||||||
self.buffer.shape_until_cursor(font_system, self.cursor);
|
self.buffer.shape_until_cursor(font_system, self.cursor);
|
||||||
self.cursor_moved = false;
|
self.cursor_moved = false;
|
||||||
|
|
@ -281,7 +281,7 @@ impl Edit for Editor {
|
||||||
self.cursor.index = self.buffer.lines[self.cursor.line].text().len() - after_len;
|
self.cursor.index = self.buffer.lines[self.cursor.line].text().len() - after_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(&mut self, font_system: &FontSystem, action: Action) {
|
fn action(&mut self, font_system: &mut FontSystem, action: Action) {
|
||||||
let old_cursor = self.cursor;
|
let old_cursor = self.cursor;
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
|
|
@ -677,7 +677,7 @@ impl Edit for Editor {
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
fn draw<F>(
|
fn draw<F>(
|
||||||
&self,
|
&self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache: &mut crate::SwashCache,
|
cache: &mut crate::SwashCache,
|
||||||
color: Color,
|
color: Color,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ pub trait Edit {
|
||||||
fn set_select_opt(&mut self, select_opt: Option<Cursor>);
|
fn set_select_opt(&mut self, select_opt: Option<Cursor>);
|
||||||
|
|
||||||
/// Shape lines until scroll, after adjusting scroll if the cursor moved
|
/// Shape lines until scroll, after adjusting scroll if the cursor moved
|
||||||
fn shape_as_needed(&mut self, font_system: &FontSystem);
|
fn shape_as_needed(&mut self, font_system: &mut FontSystem);
|
||||||
|
|
||||||
/// Copy selection
|
/// Copy selection
|
||||||
fn copy_selection(&mut self) -> Option<String>;
|
fn copy_selection(&mut self) -> Option<String>;
|
||||||
|
|
@ -122,12 +122,17 @@ pub trait Edit {
|
||||||
fn insert_string(&mut self, data: &str, attrs_list: Option<AttrsList>);
|
fn insert_string(&mut self, data: &str, attrs_list: Option<AttrsList>);
|
||||||
|
|
||||||
/// Perform an [Action] on the editor
|
/// Perform an [Action] on the editor
|
||||||
fn action(&mut self, font_system: &FontSystem, action: Action);
|
fn action(&mut self, font_system: &mut FontSystem, action: Action);
|
||||||
|
|
||||||
/// Draw the editor
|
/// Draw the editor
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
fn draw<F>(&self, font_system: &FontSystem, cache: &mut crate::SwashCache, color: Color, f: F)
|
fn draw<F>(
|
||||||
where
|
&self,
|
||||||
|
font_system: &mut FontSystem,
|
||||||
|
cache: &mut crate::SwashCache,
|
||||||
|
color: Color,
|
||||||
|
f: F,
|
||||||
|
) where
|
||||||
F: FnMut(i32, i32, u32, u32, Color);
|
F: FnMut(i32, i32, u32, u32, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +157,7 @@ impl<'a, T: Edit> BorrowedWithFontSystem<'a, T> {
|
||||||
|
|
||||||
/// Draw the editor
|
/// Draw the editor
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
pub fn draw<F>(&self, cache: &mut crate::SwashCache, color: Color, f: F)
|
pub fn draw<F>(&mut self, cache: &mut crate::SwashCache, color: Color, f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(i32, i32, u32, u32, Color),
|
F: FnMut(i32, i32, u32, u32, Color),
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ impl<'a> SyntaxEditor<'a> {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub(crate) fn load_text<P: AsRef<Path>>(
|
pub(crate) fn load_text<P: AsRef<Path>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
path: P,
|
path: P,
|
||||||
attrs: crate::Attrs,
|
attrs: crate::Attrs,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
|
@ -131,7 +131,7 @@ impl<'a> Edit for SyntaxEditor<'a> {
|
||||||
self.editor.set_select_opt(select_opt);
|
self.editor.set_select_opt(select_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_as_needed(&mut self, font_system: &FontSystem) {
|
fn shape_as_needed(&mut self, font_system: &mut FontSystem) {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
|
|
||||||
|
|
@ -236,7 +236,7 @@ impl<'a> Edit for SyntaxEditor<'a> {
|
||||||
self.editor.insert_string(data, attrs_list);
|
self.editor.insert_string(data, attrs_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(&mut self, font_system: &FontSystem, action: Action) {
|
fn action(&mut self, font_system: &mut FontSystem, action: Action) {
|
||||||
self.editor.action(font_system, action);
|
self.editor.action(font_system, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +244,7 @@ impl<'a> Edit for SyntaxEditor<'a> {
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
fn draw<F>(
|
fn draw<F>(
|
||||||
&self,
|
&self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache: &mut crate::SwashCache,
|
cache: &mut crate::SwashCache,
|
||||||
_color: Color,
|
_color: Color,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ impl<'a> ViEditor<'a> {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub(crate) fn load_text<P: AsRef<std::path::Path>>(
|
pub(crate) fn load_text<P: AsRef<std::path::Path>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
path: P,
|
path: P,
|
||||||
attrs: crate::Attrs,
|
attrs: crate::Attrs,
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
|
|
@ -71,7 +71,7 @@ impl<'a> Edit for ViEditor<'a> {
|
||||||
self.editor.set_select_opt(select_opt);
|
self.editor.set_select_opt(select_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_as_needed(&mut self, font_system: &FontSystem) {
|
fn shape_as_needed(&mut self, font_system: &mut FontSystem) {
|
||||||
self.editor.shape_as_needed(font_system);
|
self.editor.shape_as_needed(font_system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl<'a> Edit for ViEditor<'a> {
|
||||||
self.editor.insert_string(data, attrs_list);
|
self.editor.insert_string(data, attrs_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(&mut self, font_system: &FontSystem, action: Action) {
|
fn action(&mut self, font_system: &mut FontSystem, action: Action) {
|
||||||
let old_mode = self.mode;
|
let old_mode = self.mode;
|
||||||
|
|
||||||
match self.mode {
|
match self.mode {
|
||||||
|
|
@ -229,7 +229,7 @@ impl<'a> Edit for ViEditor<'a> {
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
fn draw<F>(
|
fn draw<F>(
|
||||||
&self,
|
&self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache: &mut crate::SwashCache,
|
cache: &mut crate::SwashCache,
|
||||||
color: Color,
|
color: Color,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
|
|
|
||||||
|
|
@ -44,24 +44,17 @@ impl FontSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_font(&self, id: fontdb::ID) -> Option<Arc<Font>> {
|
pub fn get_font(&self, id: fontdb::ID) -> Option<Arc<Font>> {
|
||||||
let face = self.db.face(id)?;
|
get_font(&self.db, id)
|
||||||
match Font::new(face) {
|
|
||||||
Some(font) => Some(Arc::new(font)),
|
|
||||||
None => {
|
|
||||||
log::warn!("failed to load font '{}'", face.post_script_name);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_font_matches(&self, attrs: Attrs) -> Arc<Vec<Arc<Font>>> {
|
pub fn get_font_matches(&mut self, attrs: Attrs) -> Arc<Vec<Arc<Font>>> {
|
||||||
let mut fonts = Vec::new();
|
let mut fonts = Vec::new();
|
||||||
for face in self.db.faces() {
|
for face in self.db.faces() {
|
||||||
if !attrs.matches(face) {
|
if !attrs.matches(face) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(font) = self.get_font(face.id) {
|
if let Some(font) = get_font(&self.db, face.id) {
|
||||||
fonts.push(font);
|
fonts.push(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,3 +62,14 @@ impl FontSystem {
|
||||||
Arc::new(fonts)
|
Arc::new(fonts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_font(db: &fontdb::Database, id: fontdb::ID) -> Option<Arc<Font>> {
|
||||||
|
let face = db.face(id)?;
|
||||||
|
match Font::new(face) {
|
||||||
|
Some(font) => Some(Arc::new(font)),
|
||||||
|
None => {
|
||||||
|
log::warn!("failed to load font '{}'", face.post_script_name);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use std::{
|
use std::{collections::HashMap, sync::Arc};
|
||||||
collections::HashMap,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{Attrs, AttrsOwned, Font};
|
use crate::{Attrs, AttrsOwned, Font};
|
||||||
|
|
||||||
|
|
@ -11,8 +8,8 @@ use crate::{Attrs, AttrsOwned, Font};
|
||||||
pub struct FontSystem {
|
pub struct FontSystem {
|
||||||
locale: String,
|
locale: String,
|
||||||
db: fontdb::Database,
|
db: fontdb::Database,
|
||||||
font_cache: Mutex<HashMap<fontdb::ID, Option<Arc<Font>>>>,
|
font_cache: HashMap<fontdb::ID, Option<Arc<Font>>>,
|
||||||
font_matches_cache: Mutex<HashMap<AttrsOwned, Arc<Vec<Arc<Font>>>>>,
|
font_matches_cache: HashMap<AttrsOwned, Arc<Vec<Arc<Font>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontSystem {
|
impl FontSystem {
|
||||||
|
|
@ -88,8 +85,8 @@ impl FontSystem {
|
||||||
Self {
|
Self {
|
||||||
locale,
|
locale,
|
||||||
db,
|
db,
|
||||||
font_cache: Mutex::new(HashMap::new()),
|
font_cache: HashMap::new(),
|
||||||
font_matches_cache: Mutex::new(HashMap::new()),
|
font_matches_cache: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,44 +102,28 @@ impl FontSystem {
|
||||||
(self.locale, self.db)
|
(self.locale, self.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_font(&self, id: fontdb::ID) -> Option<Arc<Font>> {
|
pub fn get_font(&mut self, id: fontdb::ID) -> Option<Arc<Font>> {
|
||||||
self.font_cache
|
get_font(&mut self.font_cache, &mut self.db, id)
|
||||||
.lock()
|
|
||||||
.expect("failed to lock font cache")
|
|
||||||
.entry(id)
|
|
||||||
.or_insert_with(|| {
|
|
||||||
let face = self.db.face(id)?;
|
|
||||||
match Font::new(face) {
|
|
||||||
Some(font) => Some(Arc::new(font)),
|
|
||||||
None => {
|
|
||||||
log::warn!("failed to load font '{}'", face.post_script_name);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_font_matches(&self, attrs: Attrs) -> Arc<Vec<Arc<Font>>> {
|
pub fn get_font_matches(&mut self, attrs: Attrs) -> Arc<Vec<Arc<Font>>> {
|
||||||
self.font_matches_cache
|
self.font_matches_cache
|
||||||
.lock()
|
|
||||||
.expect("failed to lock font matches cache")
|
|
||||||
//TODO: do not create AttrsOwned unless entry does not already exist
|
//TODO: do not create AttrsOwned unless entry does not already exist
|
||||||
.entry(AttrsOwned::new(attrs))
|
.entry(AttrsOwned::new(attrs))
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
|
|
||||||
let mut fonts = Vec::new();
|
let ids = self
|
||||||
for face in self.db.faces() {
|
.db
|
||||||
if !attrs.matches(face) {
|
.faces()
|
||||||
continue;
|
.filter(|face| attrs.matches(face))
|
||||||
}
|
.map(|face| face.id)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
if let Some(font) = self.get_font(face.id) {
|
let fonts = ids
|
||||||
fonts.push(font);
|
.into_iter()
|
||||||
}
|
.filter_map(|id| get_font(&mut self.font_cache, &mut self.db, id))
|
||||||
}
|
.collect();
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
{
|
{
|
||||||
|
|
@ -155,3 +136,23 @@ impl FontSystem {
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_font(
|
||||||
|
font_cache: &mut HashMap<fontdb::ID, Option<Arc<Font>>>,
|
||||||
|
db: &mut fontdb::Database,
|
||||||
|
id: fontdb::ID,
|
||||||
|
) -> Option<Arc<Font>> {
|
||||||
|
font_cache
|
||||||
|
.entry(id)
|
||||||
|
.or_insert_with(|| {
|
||||||
|
let face = db.face(id)?;
|
||||||
|
match Font::new(face) {
|
||||||
|
Some(font) => Some(Arc::new(font)),
|
||||||
|
None => {
|
||||||
|
log::warn!("failed to load font '{}'", face.post_script_name);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ fn shape_fallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_run(
|
fn shape_run(
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line: &str,
|
line: &str,
|
||||||
attrs_list: &AttrsList,
|
attrs_list: &AttrsList,
|
||||||
start_run: usize,
|
start_run: usize,
|
||||||
|
|
@ -273,7 +273,7 @@ pub struct ShapeWord {
|
||||||
|
|
||||||
impl ShapeWord {
|
impl ShapeWord {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line: &str,
|
line: &str,
|
||||||
attrs_list: &AttrsList,
|
attrs_list: &AttrsList,
|
||||||
word_range: Range<usize>,
|
word_range: Range<usize>,
|
||||||
|
|
@ -347,7 +347,7 @@ pub struct ShapeSpan {
|
||||||
|
|
||||||
impl ShapeSpan {
|
impl ShapeSpan {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
line: &str,
|
line: &str,
|
||||||
attrs_list: &AttrsList,
|
attrs_list: &AttrsList,
|
||||||
span_range: Range<usize>,
|
span_range: Range<usize>,
|
||||||
|
|
@ -431,7 +431,7 @@ impl ShapeLine {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Will panic if `line` contains more than one paragraph.
|
/// Will panic if `line` contains more than one paragraph.
|
||||||
pub fn new(font_system: &FontSystem, line: &str, attrs_list: &AttrsList) -> Self {
|
pub fn new(font_system: &mut FontSystem, line: &str, attrs_list: &AttrsList) -> Self {
|
||||||
let mut spans = Vec::new();
|
let mut spans = Vec::new();
|
||||||
|
|
||||||
let bidi = unicode_bidi::BidiInfo::new(line, None);
|
let bidi = unicode_bidi::BidiInfo::new(line, None);
|
||||||
|
|
|
||||||
12
src/swash.rs
12
src/swash.rs
|
|
@ -16,7 +16,7 @@ pub use swash::scale::image::{Content as SwashContent, Image as SwashImage};
|
||||||
pub use swash::zeno::{Command, Placement};
|
pub use swash::zeno::{Command, Placement};
|
||||||
|
|
||||||
fn swash_image(
|
fn swash_image(
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
context: &mut ScaleContext,
|
context: &mut ScaleContext,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
) -> Option<SwashImage> {
|
) -> Option<SwashImage> {
|
||||||
|
|
@ -57,7 +57,7 @@ fn swash_image(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swash_outline_commands(
|
fn swash_outline_commands(
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
context: &mut ScaleContext,
|
context: &mut ScaleContext,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
) -> Option<Vec<swash::zeno::Command>> {
|
) -> Option<Vec<swash::zeno::Command>> {
|
||||||
|
|
@ -109,7 +109,7 @@ impl SwashCache {
|
||||||
/// Create a swash Image from a cache key, without caching results
|
/// Create a swash Image from a cache key, without caching results
|
||||||
pub fn get_image_uncached(
|
pub fn get_image_uncached(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
) -> Option<SwashImage> {
|
) -> Option<SwashImage> {
|
||||||
swash_image(font_system, &mut self.context, cache_key)
|
swash_image(font_system, &mut self.context, cache_key)
|
||||||
|
|
@ -118,7 +118,7 @@ impl SwashCache {
|
||||||
/// Create a swash Image from a cache key, caching results
|
/// Create a swash Image from a cache key, caching results
|
||||||
pub fn get_image(
|
pub fn get_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
) -> &Option<SwashImage> {
|
) -> &Option<SwashImage> {
|
||||||
self.image_cache
|
self.image_cache
|
||||||
|
|
@ -128,7 +128,7 @@ impl SwashCache {
|
||||||
|
|
||||||
pub fn get_outline_commands(
|
pub fn get_outline_commands(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
) -> Option<&[swash::zeno::Command]> {
|
) -> Option<&[swash::zeno::Command]> {
|
||||||
self.outline_command_cache
|
self.outline_command_cache
|
||||||
|
|
@ -140,7 +140,7 @@ impl SwashCache {
|
||||||
/// Enumerate pixels in an Image, use `with_image` for better performance
|
/// Enumerate pixels in an Image, use `with_image` for better performance
|
||||||
pub fn with_pixels<F: FnMut(i32, i32, Color)>(
|
pub fn with_pixels<F: FnMut(i32, i32, Color)>(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &FontSystem,
|
font_system: &mut FontSystem,
|
||||||
cache_key: CacheKey,
|
cache_key: CacheKey,
|
||||||
base: Color,
|
base: Color,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue