Skip to content

Commit 18cba38

Browse files
committed
Fix default font fallback causing wrong caching and rename to TextContext
1 parent ee014e1 commit 18cba38

File tree

6 files changed

+33
-25
lines changed

6 files changed

+33
-25
lines changed

editor/src/messages/portfolio/document/overlays/overlays_message_handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::utility_types::{OverlayContext, OverlayProvider, OverlaysVisibilitySettings};
1+
use super::utility_types::{OverlayProvider, OverlaysVisibilitySettings};
22
use crate::messages::prelude::*;
33

44
#[derive(ExtractField)]
@@ -15,8 +15,8 @@ pub struct OverlaysMessageHandler {
1515
canvas: Option<web_sys::HtmlCanvasElement>,
1616
#[cfg(target_family = "wasm")]
1717
context: Option<web_sys::CanvasRenderingContext2d>,
18-
#[cfg(not(target_family = "wasm"))]
19-
context: Option<OverlayContext>,
18+
#[cfg(all(not(target_family = "wasm"), not(test)))]
19+
context: Option<super::utility_types::OverlayContext>,
2020
}
2121

2222
#[message_handler_data]

editor/src/messages/portfolio/document/overlays/utility_types_vello.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use graphene_std::Color;
1212
use graphene_std::math::quad::Quad;
1313
use graphene_std::subpath::{self, Subpath};
1414
use graphene_std::table::Table;
15-
use graphene_std::text::ThreadText;
15+
use graphene_std::text::TextContext;
1616
use graphene_std::text::{Font, FontCache, TextAlign, TypesettingConfig};
1717
use graphene_std::vector::click_target::ClickTargetType;
1818
use graphene_std::vector::misc::point_to_dvec2;
@@ -413,7 +413,13 @@ pub(super) struct OverlayContextInternal {
413413
device_pixel_ratio: f64,
414414
visibility_settings: OverlaysVisibilitySettings,
415415
font_cache: FontCache,
416-
thread_text: ThreadText,
416+
thread_text: TextContext,
417+
}
418+
419+
impl Default for OverlayContextInternal {
420+
fn default() -> Self {
421+
Self::new(DVec2::new(100., 100.), 1., OverlaysVisibilitySettings::default())
422+
}
417423
}
418424

419425
impl OverlayContextInternal {
@@ -430,7 +436,7 @@ impl OverlayContextInternal {
430436
device_pixel_ratio,
431437
visibility_settings,
432438
font_cache,
433-
thread_text: ThreadText::default(),
439+
thread_text: TextContext::default(),
434440
}
435441
}
436442

node-graph/gcore/src/text.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
mod font_cache;
22
mod path_builder;
3-
mod thread_text;
3+
mod text_context;
44
mod to_path;
55

66
use dyn_any::DynAny;
77
pub use font_cache::*;
8-
pub use thread_text::ThreadText;
8+
pub use text_context::TextContext;
99
pub use to_path::*;
1010

1111
/// Alignment of lines of type within a text block.

node-graph/gcore/src/text/font_cache.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ impl FontCache {
5252
}
5353

5454
/// Try to get the bytes for a font
55-
pub fn get(&self, font: &Font) -> Option<&Vec<u8>> {
56-
self.resolve_font(font).and_then(|font| self.font_file_data.get(font))
55+
pub fn get<'a>(&'a self, font: &'a Font) -> Option<(&'a Vec<u8>, &'a Font)> {
56+
self.resolve_font(font).and_then(|font| self.font_file_data.get(font).map(|data| (data, font)))
5757
}
5858

5959
/// Get font data as a Blob for use with parley/skrifa
60-
pub fn get_blob(&self, font: &Font) -> Option<Blob<u8>> {
61-
self.get(font).map(|data| Blob::new(Arc::new(data.clone())))
60+
pub fn get_blob<'a>(&'a self, font: &'a Font) -> Option<(Blob<u8>, &'a Font)> {
61+
self.get(font).map(|(data, font)| (Blob::new(Arc::new(data.clone())), font))
6262
}
6363

6464
/// Check if the font is already loaded

node-graph/gcore/src/text/thread_text.rs renamed to node-graph/gcore/src/text/text_context.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@ use std::collections::HashMap;
1010
use super::path_builder::PathBuilder;
1111

1212
thread_local! {
13-
static THREAD_TEXT: RefCell<ThreadText> = RefCell::new(ThreadText::default());
13+
static THREAD_TEXT: RefCell<TextContext> = RefCell::new(TextContext::default());
1414
}
1515

1616
/// Unified thread-local text processing context that combines font and layout management
1717
/// for efficient text rendering operations.
1818
#[derive(Default)]
19-
pub struct ThreadText {
19+
pub struct TextContext {
2020
font_context: FontContext,
2121
layout_context: LayoutContext<()>,
2222
/// Cached font metadata for performance optimization
2323
font_info_cache: HashMap<Font, (FamilyId, FontInfo)>,
2424
}
2525

26-
impl ThreadText {
27-
/// Access the thread-local ThreadText instance for text processing operations
28-
pub fn with<F, R>(f: F) -> R
26+
impl TextContext {
27+
/// Access the thread-local TextContext instance for text processing operations
28+
pub fn with_thread_local<F, R>(f: F) -> R
2929
where
30-
F: FnOnce(&mut ThreadText) -> R,
30+
F: FnOnce(&mut TextContext) -> R,
3131
{
3232
THREAD_TEXT.with_borrow_mut(f)
3333
}
3434

3535
/// Resolve a font and return its data as a Blob if available
36-
fn resolve_font_data(&self, font: &Font, font_cache: &FontCache) -> Option<Blob<u8>> {
36+
fn resolve_font_data<'a>(&self, font: &'a Font, font_cache: &'a FontCache) -> Option<(Blob<u8>, &'a Font)> {
3737
font_cache.get_blob(font)
3838
}
3939

@@ -62,8 +62,10 @@ impl ThreadText {
6262

6363
/// Create a text layout using the specified font and typesetting configuration
6464
fn layout_text(&mut self, text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig) -> Option<Layout<()>> {
65-
let font_data = self.resolve_font_data(font, font_cache)?;
66-
let (font_family, font_info) = self.get_font_info(font, &font_data)?;
65+
// Note that the actual_font may not be the desired font if that font is not yet loaded.
66+
// It is important not to cache the default font under the name of another font.
67+
let (font_data, actual_font) = self.resolve_font_data(font, font_cache)?;
68+
let (font_family, font_info) = self.get_font_info(actual_font, &font_data)?;
6769

6870
const DISPLAY_SCALE: f32 = 1.;
6971
let mut builder = self.layout_context.ranged_builder(&mut self.font_context, text, DISPLAY_SCALE, false);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::thread_text::ThreadText;
1+
use super::text_context::TextContext;
22
use super::{Font, FontCache, TypesettingConfig};
33
use crate::table::Table;
44
use crate::vector::Vector;
@@ -7,17 +7,17 @@ use parley::fontique::Blob;
77
use std::sync::Arc;
88

99
pub fn to_path(text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, per_glyph_instances: bool) -> Table<Vector> {
10-
ThreadText::with(|ctx| ctx.to_path(text, font, font_cache, typesetting, per_glyph_instances))
10+
TextContext::with_thread_local(|ctx| ctx.to_path(text, font, font_cache, typesetting, per_glyph_instances))
1111
}
1212

1313
pub fn bounding_box(text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig, for_clipping_test: bool) -> DVec2 {
14-
ThreadText::with(|ctx| ctx.bounding_box(text, font, font_cache, typesetting, for_clipping_test))
14+
TextContext::with_thread_local(|ctx| ctx.bounding_box(text, font, font_cache, typesetting, for_clipping_test))
1515
}
1616

1717
pub fn load_font(data: &[u8]) -> Blob<u8> {
1818
Blob::new(Arc::new(data.to_vec()))
1919
}
2020

2121
pub fn lines_clipping(text: &str, font: &Font, font_cache: &FontCache, typesetting: TypesettingConfig) -> bool {
22-
ThreadText::with(|ctx| ctx.lines_clipping(text, font, font_cache, typesetting))
22+
TextContext::with_thread_local(|ctx| ctx.lines_clipping(text, font, font_cache, typesetting))
2323
}

0 commit comments

Comments
 (0)