Skip to content

Commit 5fd6488

Browse files
committed
Use a thread local for layout context
1 parent e949231 commit 5fd6488

File tree

1 file changed

+55
-49
lines changed

1 file changed

+55
-49
lines changed

internal/core/textlayout/sharedparley.rs

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
pub use parley;
55

6+
use std::cell::RefCell;
7+
68
use 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)]
2730
pub struct Brush {
@@ -58,60 +61,63 @@ impl Default for LayoutOptions {
5861
}
5962

6063
pub 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

Comments
 (0)