Skip to content

Commit a0752c7

Browse files
authored
Move char_style_indices out of the per-item ShapeOptions (#741)
LLM Contributions: Review. The style indices are text-wide, whereas the options are per-item since #727. Fixes the TODO from #727 (comment).
1 parent f109c7b commit a0752c7

4 files changed

Lines changed: 46 additions & 37 deletions

File tree

parley/src/shape/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ pub(crate) fn shape_text<'a, B: Brush>(
173173
font_size: item_style.font_size,
174174
features: &style_features[item_style_index as usize],
175175
variations: rcx.variations(item_style.font_variations).unwrap_or(&[]),
176-
char_style_indices,
177176
},
178177
})
179178
})
@@ -184,6 +183,7 @@ pub(crate) fn shape_text<'a, B: Brush>(
184183
scx.shape_text(
185184
text,
186185
analysis,
186+
char_style_indices,
187187
items,
188188
font_selector,
189189
&mut layout.data.shaped_text,

parley_engine/src/shape/atom.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,10 +858,16 @@ mod tests {
858858
language: None,
859859
features: &[],
860860
variations: &[],
861-
char_style_indices: &char_style_indices,
862861
},
863862
}];
864-
shaper.shape_text(text, &analysis, items, SingleFont(font), &mut shaped);
863+
shaper.shape_text(
864+
text,
865+
&analysis,
866+
&char_style_indices,
867+
items,
868+
SingleFont(font),
869+
&mut shaped,
870+
);
865871
shaped
866872
}
867873

parley_engine/src/shape/shaped_text.rs

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ impl ShapedText {
236236
item: &Segment,
237237
options: &ShapeOptions<'_>,
238238
char_info: &[CharInfo],
239+
char_style_indices: &[u16],
239240
font: &FontInstance,
240241
glyph_buffer: &harfrust::GlyphBuffer,
241242
normalized_coords: &[harfrust::NormalizedCoord],
@@ -318,7 +319,7 @@ impl ShapedText {
318319
for (((byte_offset, ch), info), style_index) in text[range.byte_range.clone()]
319320
.char_indices()
320321
.zip(&char_info[range.char_range.clone()])
321-
.zip(&options.char_style_indices[range.char_range.clone()])
322+
.zip(&char_style_indices[range.char_range.clone()])
322323
{
323324
self.characters.push(Character {
324325
text_byte_start: (range.byte_range.start + byte_offset) as u32,
@@ -340,7 +341,6 @@ impl ShapedText {
340341
scale_factor,
341342
glyph_infos.iter(),
342343
glyph_positions.iter(),
343-
&options.char_style_indices[range.char_range.clone()],
344344
&self.characters,
345345
characters_start,
346346
);
@@ -351,7 +351,6 @@ impl ShapedText {
351351
scale_factor,
352352
glyph_infos.iter().rev(),
353353
glyph_positions.iter().rev(),
354-
&options.char_style_indices[range.char_range.clone()],
355354
&self.characters,
356355
characters_start,
357356
);
@@ -429,7 +428,6 @@ pub struct ShapedRun {
429428
/// * `glyph_infos` - `HarfRust` glyph information in logical order (i.e., reversed for RTL runs).
430429
/// * `glyph_positions` - `HarfRust` glyph positioning data in logical order (i.e., reversed for RTL
431430
/// runs).
432-
/// * `char_style_indices` - The run's slice of per-character style indices, indexed by cluster ID.
433431
/// * `characters` must contain the shaped characters whose clusters we're now processing, starting at
434432
/// index `characters_start`.
435433
/// * `characters_start` - See `characters`.
@@ -439,7 +437,6 @@ fn process_shaped_clusters<'a>(
439437
scale_factor: f32,
440438
glyph_infos: impl Iterator<Item = &'a harfrust::GlyphInfo>,
441439
glyph_positions: impl Iterator<Item = &'a harfrust::GlyphPosition>,
442-
char_style_indices: &[u16],
443440
characters: &[Character],
444441
characters_start: usize,
445442
) {
@@ -457,7 +454,6 @@ fn process_shaped_clusters<'a>(
457454
fn flush(
458455
cluster: &mut Cluster,
459456
char_end: usize,
460-
style_index: u16,
461457
characters: &[Character],
462458
shaped_clusters: &mut Vec<ShapedCluster>,
463459
) {
@@ -479,7 +475,7 @@ fn process_shaped_clusters<'a>(
479475

480476
shaped_clusters.push(ShapedCluster {
481477
chars_range: (cluster.characters_start as u32, char_end as u32),
482-
style_index,
478+
style_index: first_character.style_index,
483479
flags: ShapedClusterFlags::new(glyph_len)
484480
.with_grapheme_start(first_character.grapheme_start)
485481
// TODO: fill with actual shaping data (`parley` currently just ignores this)
@@ -502,14 +498,7 @@ fn process_shaped_clusters<'a>(
502498
for (glyph_info, glyph_pos) in glyph_infos.zip(glyph_positions) {
503499
if glyph_info.cluster != cluster.id {
504500
let char_end = characters_start + glyph_info.cluster as usize;
505-
let style_index = char_style_indices[cluster.id as usize];
506-
flush(
507-
&mut cluster,
508-
char_end,
509-
style_index,
510-
characters,
511-
shaped_clusters,
512-
);
501+
flush(&mut cluster, char_end, characters, shaped_clusters);
513502

514503
cluster = Cluster {
515504
id: glyph_info.cluster,
@@ -542,14 +531,7 @@ fn process_shaped_clusters<'a>(
542531
}
543532

544533
// Flush the final cluster.
545-
let style_index = char_style_indices[cluster.id as usize];
546-
flush(
547-
&mut cluster,
548-
characters.len(),
549-
style_index,
550-
characters,
551-
shaped_clusters,
552-
);
534+
flush(&mut cluster, characters.len(), characters, shaped_clusters);
553535
}
554536

555537
#[cfg(test)]
@@ -621,10 +603,16 @@ mod tests {
621603
language: None,
622604
features: &[],
623605
variations: &[],
624-
char_style_indices: &char_style_indices,
625606
},
626607
}];
627-
shaper.shape_text(text, &analysis, items, SingleFont(font), &mut shaped);
608+
shaper.shape_text(
609+
text,
610+
&analysis,
611+
&char_style_indices,
612+
items,
613+
SingleFont(font),
614+
&mut shaped,
615+
);
628616
shaped
629617
}
630618

@@ -732,7 +720,6 @@ mod tests {
732720
language: None,
733721
features: &[],
734722
variations: &[],
735-
char_style_indices: &char_style_indices,
736723
},
737724
},
738725
Item {
@@ -742,11 +729,17 @@ mod tests {
742729
language: None,
743730
features: &[],
744731
variations: &[],
745-
char_style_indices: &char_style_indices,
746732
},
747733
},
748734
];
749-
shaper.shape_text(text, &analysis, items, SingleFont(font), &mut shaped);
735+
shaper.shape_text(
736+
text,
737+
&analysis,
738+
&char_style_indices,
739+
items,
740+
SingleFont(font),
741+
&mut shaped,
742+
);
750743

751744
let grapheme_starts: Vec<bool> =
752745
shaped.characters.iter().map(|c| c.grapheme_start).collect();

parley_engine/src/shape/shaper.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ pub struct ShapeOptions<'a> {
3434
pub features: &'a [FontFeature],
3535
/// The font variations that are constant over an item.
3636
pub variations: &'a [FontVariation],
37-
/// The per-character style indices.
38-
// TODO: rename to something like `user_data` (s.t. we don't assume it's a style per se).
39-
// TODO: probably move this out of `ShapeOptions`, and supply it as a parameter on
40-
// `Shaper::shape_text`.
41-
pub char_style_indices: &'a [u16],
4237
}
4338

4439
/// The font instance to shape an item with.
@@ -92,6 +87,10 @@ impl Shaper {
9287
/// split on properties like shaping-relevant style changes (e.g., font size) or properties like
9388
/// language.
9489
///
90+
/// `char_style_indices` holds per-character style indices; these are copied onto
91+
/// [`Character`][super::Character`] and [`ShapedCluster`][super::ShapedCluster]. A shaped
92+
/// cluster's style index is that of its logically first constituent character.
93+
///
9594
/// Characters that don't have a particular script have their script resolved based on
9695
/// surrounding context (see [`Segment::script`]).
9796
///
@@ -106,6 +105,8 @@ impl Shaper {
106105
&mut self,
107106
text: &str,
108107
analysis: &Analysis,
108+
// TODO: rename to something like `user_data` (s.t. we don't assume it's a style per se).
109+
char_style_indices: &[u16],
109110
items: impl IntoIterator<Item = Item<'options>>,
110111
mut select_font: impl FontSelector,
111112
shaped_text: &mut ShapedText,
@@ -114,6 +115,12 @@ impl Shaper {
114115
shaped_text.reserve(text.len());
115116

116117
let char_count = analysis.char_info().len();
118+
debug_assert_eq!(
119+
char_style_indices.len(),
120+
char_count,
121+
"The number of character style indices must be equal to the character count"
122+
);
123+
117124
let mut previous_item_end = 0;
118125
let mut itemizer = analysis.itemize(text);
119126

@@ -142,6 +149,7 @@ impl Shaper {
142149
&item.options,
143150
&mut select_font,
144151
analysis.char_info(),
152+
char_style_indices,
145153
shaped_text,
146154
)
147155
.is_err()
@@ -182,6 +190,7 @@ fn shape_segment(
182190
options: &ShapeOptions<'_>,
183191
select_font: &mut impl FontSelector,
184192
char_info: &[CharInfo],
193+
char_style_indices: &[u16],
185194
shaped_text: &mut ShapedText,
186195
) -> Result<(), ()> {
187196
select_font.begin_segment(item, options);
@@ -193,7 +202,7 @@ fn shape_segment(
193202

194203
// Only process current item
195204
let item_char_info = &char_info[char_range.start..char_range.end];
196-
let item_char_style_indices = &options.char_style_indices[char_range.start..char_range.end];
205+
let item_char_style_indices = &char_style_indices[char_range.start..char_range.end];
197206

198207
if item_text.is_empty() {
199208
return Ok(()); // No clusters
@@ -378,6 +387,7 @@ fn shape_segment(
378387
item,
379388
options,
380389
char_info,
390+
char_style_indices,
381391
&font,
382392
&glyph_buffer,
383393
harf_shaper.coords(),

0 commit comments

Comments
 (0)