Skip to content

Commit bc66148

Browse files
authored
Reset the overlay context for each draw request and use global font cache (#3231)
1 parent 84e4481 commit bc66148

File tree

2 files changed

+20
-22
lines changed

2 files changed

+20
-22
lines changed

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ pub struct OverlaysMessageHandler {
1515
canvas: Option<web_sys::HtmlCanvasElement>,
1616
#[cfg(target_family = "wasm")]
1717
context: Option<web_sys::CanvasRenderingContext2d>,
18-
#[cfg(all(not(target_family = "wasm"), not(test)))]
19-
context: Option<super::utility_types::OverlayContext>,
2018
}
2119

2220
#[message_handler_data]
@@ -82,11 +80,7 @@ impl MessageHandler<OverlaysMessage, OverlaysMessageContext<'_>> for OverlaysMes
8280

8381
let size = ipp.viewport_bounds.size();
8482

85-
if self.context.is_none() {
86-
self.context = Some(OverlayContext::new(size, device_pixel_ratio, visibility_settings));
87-
}
88-
89-
let overlay_context = self.context.as_mut().unwrap();
83+
let overlay_context = OverlayContext::new(size, device_pixel_ratio, visibility_settings);
9084

9185
if visibility_settings.all() {
9286
responses.add(DocumentMessage::GridOverlays { context: overlay_context.clone() });
@@ -95,7 +89,7 @@ impl MessageHandler<OverlaysMessage, OverlaysMessageContext<'_>> for OverlaysMes
9589
responses.add(provider(overlay_context.clone()));
9690
}
9791
}
98-
responses.add(FrontendMessage::RenderOverlays { context: overlay_context.clone() });
92+
responses.add(FrontendMessage::RenderOverlays { context: overlay_context });
9993
}
10094
#[cfg(all(not(target_family = "wasm"), test))]
10195
OverlaysMessage::Draw => {

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,22 @@ use graphene_std::vector::{PointId, SegmentId, Vector};
2020
use kurbo::{self, BezPath, ParamCurve};
2121
use kurbo::{Affine, PathSeg};
2222
use std::collections::HashMap;
23-
use std::sync::{Arc, Mutex, MutexGuard};
23+
use std::sync::{Arc, LazyLock, Mutex, MutexGuard};
2424
use vello::Scene;
2525
use vello::peniko;
2626

27+
// Global lazy initialized font cache and text context
28+
static GLOBAL_FONT_CACHE: LazyLock<FontCache> = LazyLock::new(|| {
29+
let mut font_cache = FontCache::default();
30+
// Initialize with the hardcoded font used by overlay text
31+
const FONT_DATA: &[u8] = include_bytes!("source-sans-pro-regular.ttf");
32+
let font = Font::new("Source Sans Pro".to_string(), "Regular".to_string());
33+
font_cache.insert(font, String::new(), FONT_DATA.to_vec());
34+
font_cache
35+
});
36+
37+
static GLOBAL_TEXT_CONTEXT: LazyLock<Mutex<TextContext>> = LazyLock::new(|| Mutex::new(TextContext::default()));
38+
2739
pub type OverlayProvider = fn(OverlayContext) -> Message;
2840

2941
pub fn empty_provider() -> OverlayProvider {
@@ -412,8 +424,6 @@ pub(super) struct OverlayContextInternal {
412424
size: DVec2,
413425
device_pixel_ratio: f64,
414426
visibility_settings: OverlaysVisibilitySettings,
415-
font_cache: FontCache,
416-
thread_text: TextContext,
417427
}
418428

419429
impl Default for OverlayContextInternal {
@@ -424,19 +434,11 @@ impl Default for OverlayContextInternal {
424434

425435
impl OverlayContextInternal {
426436
pub(super) fn new(size: DVec2, device_pixel_ratio: f64, visibility_settings: OverlaysVisibilitySettings) -> Self {
427-
let mut font_cache = FontCache::default();
428-
// Initialize with the hardcoded font used by overlay text
429-
const FONT_DATA: &[u8] = include_bytes!("source-sans-pro-regular.ttf");
430-
let font = Font::new("Source Sans Pro".to_string(), "Regular".to_string());
431-
font_cache.insert(font, String::new(), FONT_DATA.to_vec());
432-
433437
Self {
434438
scene: Scene::new(),
435439
size,
436440
device_pixel_ratio,
437441
visibility_settings,
438-
font_cache,
439-
thread_text: TextContext::default(),
440442
}
441443
}
442444

@@ -1031,7 +1033,8 @@ impl OverlayContextInternal {
10311033
// TODO: Grab this from the node_modules folder (either with `include_bytes!` or ideally at runtime) instead of checking the font file into the repo.
10321034
// TODO: And maybe use the WOFF2 version (if it's supported) for its smaller, compressed file size.
10331035
let font = Font::new("Source Sans Pro".to_string(), "Regular".to_string());
1034-
let bounds = self.thread_text.bounding_box(text, &font, &self.font_cache, typesetting, false);
1036+
let mut text_context = GLOBAL_TEXT_CONTEXT.lock().expect("Failed to lock global text context");
1037+
let bounds = text_context.bounding_box(text, &font, &GLOBAL_FONT_CACHE, typesetting, false);
10351038
bounds.x
10361039
}
10371040

@@ -1056,14 +1059,15 @@ impl OverlayContextInternal {
10561059
let font = Font::new("Source Sans Pro".to_string(), "Regular".to_string());
10571060

10581061
// Get text dimensions directly from layout
1059-
let text_size = self.thread_text.bounding_box(text, &font, &self.font_cache, typesetting, false);
1062+
let mut text_context = GLOBAL_TEXT_CONTEXT.lock().expect("Failed to lock global text context");
1063+
let text_size = text_context.bounding_box(text, &font, &GLOBAL_FONT_CACHE, typesetting, false);
10601064
let text_width = text_size.x;
10611065
let text_height = text_size.y;
10621066
// Create a rect from the size (assuming text starts at origin)
10631067
let text_bounds = kurbo::Rect::new(0.0, 0.0, text_width, text_height);
10641068

10651069
// Convert text to vector paths for rendering
1066-
let text_table = self.thread_text.to_path(text, &font, &self.font_cache, typesetting, false);
1070+
let text_table = text_context.to_path(text, &font, &GLOBAL_FONT_CACHE, typesetting, false);
10671071

10681072
// Calculate position based on pivot
10691073
let mut position = DVec2::ZERO;

0 commit comments

Comments
 (0)