33
44pub use parley;
55
6+ use std:: cell:: RefCell ;
7+
68use crate :: {
79 graphics:: FontRequest ,
810 items:: TextStrokeStyle ,
@@ -20,8 +22,9 @@ fn font_context() -> parley::FontContext {
2022 }
2123}
2224
23- static LAYOUT_CONTEXT : std:: sync:: LazyLock < parley:: LayoutContext < Brush > > =
24- std:: sync:: LazyLock :: new ( || Default :: default ( ) ) ;
25+ std:: thread_local! {
26+ static LAYOUT_CONTEXT : RefCell <parley:: LayoutContext <Brush >> = Default :: default ( ) ;
27+ }
2528
2629#[ derive( Debug , Default , PartialEq , Clone , Copy ) ]
2730pub struct Brush {
@@ -58,60 +61,63 @@ impl Default for LayoutOptions {
5861}
5962
6063pub fn layout ( text : & str , scale_factor : f32 , options : LayoutOptions ) -> Layout {
61- let mut font_context = font_context ( ) ;
62- let mut layout_context = LAYOUT_CONTEXT . clone ( ) ;
63-
64- let mut builder = layout_context. ranged_builder ( & mut font_context, text, scale_factor, true ) ;
65- if let Some ( ref font_request) = options. font_request {
66- if let Some ( family) = & font_request. family {
67- builder. push_default ( parley:: StyleProperty :: FontStack (
68- parley:: style:: FontStack :: Single ( parley:: style:: FontFamily :: Named (
69- family. as_str ( ) . into ( ) ,
70- ) ) ,
71- ) ) ;
72- }
73- if let Some ( weight) = font_request. weight {
74- builder. push_default ( parley:: StyleProperty :: FontWeight (
75- parley:: style:: FontWeight :: new ( weight as f32 ) ,
76- ) ) ;
77- }
78- if let Some ( letter_spacing) = font_request. letter_spacing {
79- builder. push_default ( parley:: StyleProperty :: LetterSpacing ( letter_spacing. get ( ) ) ) ;
80- }
81- builder. push_default ( parley:: StyleProperty :: FontStyle ( if font_request. italic {
82- parley:: style:: FontStyle :: Italic
83- } else {
84- parley:: style:: FontStyle :: Normal
85- } ) ) ;
86- }
64+ let max_physical_width = options. max_physical_width . map ( |max_width| max_width. get ( ) ) ;
8765 let pixel_size = options
8866 . font_request
67+ . as_ref ( )
8968 . and_then ( |font_request| font_request. pixel_size )
9069 . unwrap_or ( DEFAULT_FONT_SIZE ) ;
91- builder. push_default ( parley:: StyleProperty :: FontSize ( pixel_size. get ( ) ) ) ;
92- builder. push_default ( parley:: StyleProperty :: WordBreak ( match options. text_wrap {
93- TextWrap :: NoWrap => parley:: style:: WordBreakStrength :: KeepAll ,
94- TextWrap :: WordWrap => parley:: style:: WordBreakStrength :: Normal ,
95- TextWrap :: CharWrap => parley:: style:: WordBreakStrength :: BreakAll ,
96- } ) ) ;
97- if options. text_overflow == TextOverflow :: Elide {
98- todo ! ( ) ;
99- }
10070
101- builder. push_default ( parley:: StyleProperty :: Brush ( Brush {
102- stroke : options. stroke ,
103- ..Default :: default ( )
104- } ) ) ;
105- if let Some ( selection) = options. selection {
106- builder. push (
107- parley:: StyleProperty :: Brush ( Brush { stroke : options. stroke , is_selected : true } ) ,
108- selection,
109- ) ;
110- }
71+ let mut layout = LAYOUT_CONTEXT . with_borrow_mut ( move |layout_context| {
72+ let mut font_context = font_context ( ) ;
73+ let mut builder =
74+ layout_context. ranged_builder ( & mut font_context, text, scale_factor, true ) ;
75+ if let Some ( ref font_request) = options. font_request {
76+ if let Some ( family) = & font_request. family {
77+ builder. push_default ( parley:: StyleProperty :: FontStack (
78+ parley:: style:: FontStack :: Single ( parley:: style:: FontFamily :: Named (
79+ family. as_str ( ) . into ( ) ,
80+ ) ) ,
81+ ) ) ;
82+ }
83+ if let Some ( weight) = font_request. weight {
84+ builder. push_default ( parley:: StyleProperty :: FontWeight (
85+ parley:: style:: FontWeight :: new ( weight as f32 ) ,
86+ ) ) ;
87+ }
88+ if let Some ( letter_spacing) = font_request. letter_spacing {
89+ builder. push_default ( parley:: StyleProperty :: LetterSpacing ( letter_spacing. get ( ) ) ) ;
90+ }
91+ builder. push_default ( parley:: StyleProperty :: FontStyle ( if font_request. italic {
92+ parley:: style:: FontStyle :: Italic
93+ } else {
94+ parley:: style:: FontStyle :: Normal
95+ } ) ) ;
96+ }
97+ builder. push_default ( parley:: StyleProperty :: FontSize ( pixel_size. get ( ) ) ) ;
98+ builder. push_default ( parley:: StyleProperty :: WordBreak ( match options. text_wrap {
99+ TextWrap :: NoWrap => parley:: style:: WordBreakStrength :: KeepAll ,
100+ TextWrap :: WordWrap => parley:: style:: WordBreakStrength :: Normal ,
101+ TextWrap :: CharWrap => parley:: style:: WordBreakStrength :: BreakAll ,
102+ } ) ) ;
103+ if options. text_overflow == TextOverflow :: Elide {
104+ todo ! ( ) ;
105+ }
111106
112- let max_physical_width = options. max_physical_width . map ( |max_width| max_width. get ( ) ) ;
107+ builder. push_default ( parley:: StyleProperty :: Brush ( Brush {
108+ stroke : options. stroke ,
109+ ..Default :: default ( )
110+ } ) ) ;
111+ if let Some ( selection) = options. selection {
112+ builder. push (
113+ parley:: StyleProperty :: Brush ( Brush { stroke : options. stroke , is_selected : true } ) ,
114+ selection,
115+ ) ;
116+ }
117+
118+ builder. build ( text)
119+ } ) ;
113120
114- let mut layout: parley:: Layout < Brush > = builder. build ( text) ;
115121 layout. break_all_lines ( max_physical_width) ;
116122 layout. align (
117123 max_physical_width,
0 commit comments