@@ -20,10 +20,22 @@ use graphene_std::vector::{PointId, SegmentId, Vector};
20
20
use kurbo:: { self , BezPath , ParamCurve } ;
21
21
use kurbo:: { Affine , PathSeg } ;
22
22
use std:: collections:: HashMap ;
23
- use std:: sync:: { Arc , Mutex , MutexGuard } ;
23
+ use std:: sync:: { Arc , LazyLock , Mutex , MutexGuard } ;
24
24
use vello:: Scene ;
25
25
use vello:: peniko;
26
26
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
+
27
39
pub type OverlayProvider = fn ( OverlayContext ) -> Message ;
28
40
29
41
pub fn empty_provider ( ) -> OverlayProvider {
@@ -412,8 +424,6 @@ pub(super) struct OverlayContextInternal {
412
424
size : DVec2 ,
413
425
device_pixel_ratio : f64 ,
414
426
visibility_settings : OverlaysVisibilitySettings ,
415
- font_cache : FontCache ,
416
- thread_text : TextContext ,
417
427
}
418
428
419
429
impl Default for OverlayContextInternal {
@@ -424,19 +434,11 @@ impl Default for OverlayContextInternal {
424
434
425
435
impl OverlayContextInternal {
426
436
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
-
433
437
Self {
434
438
scene : Scene :: new ( ) ,
435
439
size,
436
440
device_pixel_ratio,
437
441
visibility_settings,
438
- font_cache,
439
- thread_text : TextContext :: default ( ) ,
440
442
}
441
443
}
442
444
@@ -1031,7 +1033,8 @@ impl OverlayContextInternal {
1031
1033
// 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.
1032
1034
// TODO: And maybe use the WOFF2 version (if it's supported) for its smaller, compressed file size.
1033
1035
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 ) ;
1035
1038
bounds. x
1036
1039
}
1037
1040
@@ -1056,14 +1059,15 @@ impl OverlayContextInternal {
1056
1059
let font = Font :: new ( "Source Sans Pro" . to_string ( ) , "Regular" . to_string ( ) ) ;
1057
1060
1058
1061
// 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 ) ;
1060
1064
let text_width = text_size. x ;
1061
1065
let text_height = text_size. y ;
1062
1066
// Create a rect from the size (assuming text starts at origin)
1063
1067
let text_bounds = kurbo:: Rect :: new ( 0.0 , 0.0 , text_width, text_height) ;
1064
1068
1065
1069
// 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 ) ;
1067
1071
1068
1072
// Calculate position based on pivot
1069
1073
let mut position = DVec2 :: ZERO ;
0 commit comments