Skip to content

Commit e8ea3b8

Browse files
committed
Better encapsulate LayoutContext
Signed-off-by: Nico Burns <[email protected]>
1 parent 080a4fd commit e8ea3b8

File tree

2 files changed

+103
-78
lines changed

2 files changed

+103
-78
lines changed

parley/src/builder.rs

Lines changed: 13 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ impl<B: Brush> RangedBuilder<'_, B> {
2828
pub fn push_default<'a>(&mut self, property: impl Into<StyleProperty<'a, B>>) {
2929
let resolved = self
3030
.lcx
31-
.rcx
3231
.resolve_property(self.fcx, &property.into(), self.scale);
3332
self.lcx.ranged_style_builder.push_default(resolved);
3433
}
@@ -40,7 +39,6 @@ impl<B: Brush> RangedBuilder<'_, B> {
4039
) {
4140
let resolved = self
4241
.lcx
43-
.rcx
4442
.resolve_property(self.fcx, &property.into(), self.scale);
4543
self.lcx.ranged_style_builder.push(resolved, range);
4644
}
@@ -54,14 +52,8 @@ impl<B: Brush> RangedBuilder<'_, B> {
5452
self.lcx.ranged_style_builder.finish(&mut self.lcx.styles);
5553

5654
// Call generic layout builder method
57-
build_into_layout(
58-
layout,
59-
self.scale,
60-
self.quantize,
61-
text.as_ref(),
62-
self.lcx,
63-
self.fcx,
64-
);
55+
self.lcx
56+
.build_into_layout(layout, self.scale, self.quantize, text.as_ref(), self.fcx);
6557
}
6658

6759
pub fn build(self, text: impl AsRef<str>) -> Layout<B> {
@@ -84,7 +76,6 @@ impl<B: Brush> TreeBuilder<'_, B> {
8476
pub fn push_style_span(&mut self, style: TextStyle<'_, B>) {
8577
let resolved = self
8678
.lcx
87-
.rcx
8879
.resolve_entire_style_set(self.fcx, &style, self.scale);
8980
self.lcx.tree_style_builder.push_style_span(resolved);
9081
}
@@ -96,11 +87,15 @@ impl<B: Brush> TreeBuilder<'_, B> {
9687
's: 'iter,
9788
B: 'iter,
9889
{
99-
self.lcx.tree_style_builder.push_style_modification_span(
100-
properties
101-
.into_iter()
102-
.map(|p| self.lcx.rcx.resolve_property(self.fcx, p, self.scale)),
103-
);
90+
// FIXME: eliminate allocation if/when the "style builders" are extracted
91+
// from the LayoutContext
92+
let resolved_properties: Vec<_> = properties
93+
.into_iter()
94+
.map(|p| self.lcx.resolve_property(self.fcx, p, self.scale))
95+
.collect();
96+
self.lcx
97+
.tree_style_builder
98+
.push_style_modification_span(resolved_properties.into_iter());
10499
}
105100

106101
pub fn pop_style_span(&mut self) {
@@ -134,7 +129,8 @@ impl<B: Brush> TreeBuilder<'_, B> {
134129
let text = self.lcx.tree_style_builder.finish(&mut self.lcx.styles);
135130

136131
// Call generic layout builder method
137-
build_into_layout(layout, self.scale, self.quantize, &text, self.lcx, self.fcx);
132+
self.lcx
133+
.build_into_layout(layout, self.scale, self.quantize, &text, self.fcx);
138134

139135
text
140136
}
@@ -146,60 +142,3 @@ impl<B: Brush> TreeBuilder<'_, B> {
146142
(layout, text)
147143
}
148144
}
149-
150-
fn build_into_layout<B: Brush>(
151-
layout: &mut Layout<B>,
152-
scale: f32,
153-
quantize: bool,
154-
text: &str,
155-
lcx: &mut LayoutContext<B>,
156-
fcx: &mut FontContext,
157-
) {
158-
lcx.analyze_text(text);
159-
160-
layout.data.clear();
161-
layout.data.scale = scale;
162-
layout.data.quantize = quantize;
163-
layout.data.has_bidi = !lcx.bidi.levels().is_empty();
164-
layout.data.base_level = lcx.bidi.base_level();
165-
layout.data.text_len = text.len();
166-
167-
let mut char_index = 0;
168-
for (i, style) in lcx.styles.iter().enumerate() {
169-
for _ in text[style.range.clone()].chars() {
170-
lcx.info[char_index].1 = i as u16;
171-
char_index += 1;
172-
}
173-
}
174-
175-
// Copy the visual styles into the layout
176-
layout
177-
.data
178-
.styles
179-
.extend(lcx.styles.iter().map(|s| s.style.as_layout_style()));
180-
181-
// Sort the inline boxes as subsequent code assumes that they are in text index order.
182-
// Note: It's important that this is a stable sort to allow users to control the order of contiguous inline boxes
183-
lcx.inline_boxes.sort_by_key(|b| b.index);
184-
185-
{
186-
let query = fcx.collection.query(&mut fcx.source_cache);
187-
super::shape::shape_text(
188-
&lcx.rcx,
189-
query,
190-
&lcx.styles,
191-
&lcx.inline_boxes,
192-
&lcx.info,
193-
lcx.bidi.levels(),
194-
&mut lcx.scx,
195-
text,
196-
layout,
197-
);
198-
}
199-
200-
// Move inline boxes into the layout
201-
layout.data.inline_boxes.clear();
202-
core::mem::swap(&mut layout.data.inline_boxes, &mut lcx.inline_boxes);
203-
204-
layout.data.finish();
205-
}

parley/src/context.rs

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,28 @@ use super::style::{Brush, TextStyle};
1616
use swash::shape::ShapeContext;
1717
use swash::text::cluster::CharInfo;
1818

19+
use crate::Layout;
20+
use crate::StyleProperty;
1921
use crate::builder::TreeBuilder;
2022
use crate::inline_box::InlineBox;
23+
use crate::resolve::ResolvedProperty;
2124

2225
/// Shared scratch space used when constructing text layouts.
2326
///
2427
/// This type is designed to be a global resource with only one per-application (or per-thread).
2528
pub struct LayoutContext<B: Brush = [u8; 4]> {
26-
pub(crate) bidi: bidi::BidiResolver,
27-
pub(crate) rcx: ResolveContext,
2829
pub(crate) styles: Vec<RangedStyle<B>>,
2930
pub(crate) inline_boxes: Vec<InlineBox>,
3031

3132
// Reusable style builders (to amortise allocations)
3233
pub(crate) ranged_style_builder: RangedStyleBuilder<B>,
3334
pub(crate) tree_style_builder: TreeStyleBuilder<B>,
3435

35-
pub(crate) info: Vec<(CharInfo, u16)>,
36-
pub(crate) scx: ShapeContext,
36+
// Internal contexts
37+
bidi: bidi::BidiResolver,
38+
rcx: ResolveContext,
39+
scx: ShapeContext,
40+
info: Vec<(CharInfo, u16)>,
3741
}
3842

3943
impl<B: Brush> LayoutContext<B> {
@@ -179,6 +183,88 @@ impl<B: Brush> LayoutContext<B> {
179183
}
180184
}
181185

186+
pub(crate) fn resolve_property(
187+
&mut self,
188+
fcx: &mut FontContext,
189+
property: &StyleProperty<'_, B>,
190+
scale: f32,
191+
) -> ResolvedProperty<B> {
192+
self.rcx.resolve_property(fcx, property, scale)
193+
}
194+
195+
pub(crate) fn resolve_entire_style_set(
196+
&mut self,
197+
fcx: &mut FontContext,
198+
raw_style: &TextStyle<'_, B>,
199+
scale: f32,
200+
) -> ResolvedStyle<B> {
201+
self.rcx.resolve_entire_style_set(fcx, raw_style, scale)
202+
}
203+
204+
pub(crate) fn shape_into_layout(
205+
&mut self,
206+
fcx: &mut FontContext,
207+
text: &str,
208+
layout: &mut Layout<B>,
209+
) {
210+
let query = fcx.collection.query(&mut fcx.source_cache);
211+
super::shape::shape_text(
212+
&self.rcx,
213+
query,
214+
&self.styles,
215+
&self.inline_boxes,
216+
&self.info,
217+
self.bidi.levels(),
218+
&mut self.scx,
219+
text,
220+
layout,
221+
);
222+
}
223+
224+
pub(crate) fn build_into_layout(
225+
&mut self,
226+
layout: &mut Layout<B>,
227+
scale: f32,
228+
quantize: bool,
229+
text: &str,
230+
fcx: &mut FontContext,
231+
) {
232+
self.analyze_text(text);
233+
234+
layout.data.clear();
235+
layout.data.scale = scale;
236+
layout.data.quantize = quantize;
237+
layout.data.has_bidi = !self.bidi.levels().is_empty();
238+
layout.data.base_level = self.bidi.base_level();
239+
layout.data.text_len = text.len();
240+
241+
let mut char_index = 0;
242+
for (i, style) in self.styles.iter().enumerate() {
243+
for _ in text[style.range.clone()].chars() {
244+
self.info[char_index].1 = i as u16;
245+
char_index += 1;
246+
}
247+
}
248+
249+
// Copy the visual styles into the layout
250+
layout
251+
.data
252+
.styles
253+
.extend(self.styles.iter().map(|s| s.style.as_layout_style()));
254+
255+
// Sort the inline boxes as subsequent code assumes that they are in text index order.
256+
// Note: It's important that this is a stable sort to allow users to control the order of contiguous inline boxes
257+
self.inline_boxes.sort_by_key(|b| b.index);
258+
259+
self.shape_into_layout(fcx, text, layout);
260+
261+
// Move inline boxes into the layout
262+
layout.data.inline_boxes.clear();
263+
core::mem::swap(&mut layout.data.inline_boxes, &mut self.inline_boxes);
264+
265+
layout.data.finish();
266+
}
267+
182268
fn begin(&mut self) {
183269
self.rcx.clear();
184270
self.styles.clear();

0 commit comments

Comments
 (0)