cache the monospace fallbacks buffer in FontSystem

This commit is contained in:
koe 2024-09-01 23:22:27 -05:00 committed by Jeremy Soller
parent 069d3404bf
commit 9d132f8ebd
2 changed files with 19 additions and 8 deletions

View file

@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use alloc::collections::BTreeSet;
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::vec::Vec; use alloc::vec::Vec;
use fontdb::Family; use fontdb::Family;
@ -35,7 +34,7 @@ use log::warn as missing_warn;
// Default font gets None for both `weight_offset` and `script_non_matches`, and thus, it is // Default font gets None for both `weight_offset` and `script_non_matches`, and thus, it is
// always the first to be popped from the set. // always the first to be popped from the set.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct MonospaceFallbackInfo { pub(crate) struct MonospaceFallbackInfo {
font_weight_diff: Option<u16>, font_weight_diff: Option<u16>,
codepoint_non_matches: Option<usize>, codepoint_non_matches: Option<usize>,
font_weight: u16, font_weight: u16,
@ -46,7 +45,6 @@ pub struct FontFallbackIter<'a> {
font_system: &'a mut FontSystem, font_system: &'a mut FontSystem,
font_match_keys: &'a [FontMatchKey], font_match_keys: &'a [FontMatchKey],
default_families: &'a [&'a Family<'a>], default_families: &'a [&'a Family<'a>],
monospace_fallbacks: BTreeSet<MonospaceFallbackInfo>,
default_i: usize, default_i: usize,
scripts: &'a [Script], scripts: &'a [Script],
word: &'a str, word: &'a str,
@ -64,11 +62,11 @@ impl<'a> FontFallbackIter<'a> {
scripts: &'a [Script], scripts: &'a [Script],
word: &'a str, word: &'a str,
) -> Self { ) -> Self {
font_system.monospace_fallbacks_buffer.clear();
Self { Self {
font_system, font_system,
font_match_keys, font_match_keys,
default_families, default_families,
monospace_fallbacks: BTreeSet::new(),
default_i: 0, default_i: 0,
scripts, scripts,
word, word,
@ -148,7 +146,7 @@ impl<'a> FontFallbackIter<'a> {
impl<'a> Iterator for FontFallbackIter<'a> { impl<'a> Iterator for FontFallbackIter<'a> {
type Item = Arc<Font>; type Item = Arc<Font>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if let Some(fallback_info) = self.monospace_fallbacks.pop_first() { if let Some(fallback_info) = self.font_system.monospace_fallbacks_buffer.pop_first() {
if let Some(font) = self.font_system.get_font(fallback_info.id) { if let Some(font) = self.font_system.get_font(fallback_info.id) {
return Some(font); return Some(font);
} }
@ -207,7 +205,10 @@ impl<'a> Iterator for FontFallbackIter<'a> {
return Some(font); return Some(font);
} }
} else { } else {
assert!(self.monospace_fallbacks.insert(fallback_info)); assert!(self
.font_system
.monospace_fallbacks_buffer
.insert(fallback_info));
} }
} }
} }
@ -245,13 +246,16 @@ impl<'a> Iterator for FontFallbackIter<'a> {
font_weight: m_key.font_weight, font_weight: m_key.font_weight,
id: m_key.id, id: m_key.id,
}; };
assert!(self.monospace_fallbacks.insert(fallback_info)); assert!(self
.font_system
.monospace_fallbacks_buffer
.insert(fallback_info));
} }
} }
} }
} }
// If default family is Monospace fallback to first monospaced font // If default family is Monospace fallback to first monospaced font
if let Some(fallback_info) = self.monospace_fallbacks.pop_first() { if let Some(fallback_info) = self.font_system.monospace_fallbacks_buffer.pop_first() {
if let Some(font) = self.font_system.get_font(fallback_info.id) { if let Some(font) = self.font_system.get_font(fallback_info.id) {
return Some(font); return Some(font);
} }

View file

@ -1,4 +1,5 @@
use crate::{Attrs, Font, FontMatchAttrs, HashMap, ShapeBuffer, ShapePlanCache}; use crate::{Attrs, Font, FontMatchAttrs, HashMap, ShapeBuffer, ShapePlanCache};
use alloc::collections::BTreeSet;
use alloc::string::String; use alloc::string::String;
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -9,6 +10,8 @@ use core::ops::{Deref, DerefMut};
pub use fontdb; pub use fontdb;
pub use rustybuzz; pub use rustybuzz;
use super::fallback::MonospaceFallbackInfo;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct FontMatchKey { pub struct FontMatchKey {
pub(crate) font_weight_diff: u16, pub(crate) font_weight_diff: u16,
@ -106,6 +109,9 @@ pub struct FontSystem {
/// Scratch buffer for shaping and laying out. /// Scratch buffer for shaping and laying out.
pub(crate) shape_buffer: ShapeBuffer, pub(crate) shape_buffer: ShapeBuffer,
/// Buffer for use in FontFallbackIter.
pub(crate) monospace_fallbacks_buffer: BTreeSet<MonospaceFallbackInfo>,
/// Cache for shaped runs /// Cache for shaped runs
#[cfg(feature = "shape-run-cache")] #[cfg(feature = "shape-run-cache")]
pub shape_run_cache: crate::ShapeRunCache, pub shape_run_cache: crate::ShapeRunCache,
@ -172,6 +178,7 @@ impl FontSystem {
font_matches_cache: Default::default(), font_matches_cache: Default::default(),
font_codepoint_support_info_cache: Default::default(), font_codepoint_support_info_cache: Default::default(),
shape_plan_cache: ShapePlanCache::default(), shape_plan_cache: ShapePlanCache::default(),
monospace_fallbacks_buffer: BTreeSet::default(),
#[cfg(feature = "shape-run-cache")] #[cfg(feature = "shape-run-cache")]
shape_run_cache: crate::ShapeRunCache::default(), shape_run_cache: crate::ShapeRunCache::default(),
shape_buffer: ShapeBuffer::default(), shape_buffer: ShapeBuffer::default(),