Skip to content

Commit bc6b6be

Browse files
committed
Improve docs, reintroduce ligature suppression after rebase (in a slightly unfortunate form)
1 parent 84cb03d commit bc6b6be

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

parley/src/shape/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! Text shaping implementation using `harfrust`for shaping
55
//! and `icu` for text analysis.
66
7+
use alloc::vec::Vec;
78
use parley_engine::shape::{CharCluster, Coverage};
89
use parley_engine::{Analysis, AnalysisDataSources, FontInstance, ShapeOptions, Shaper};
910
use smallvec::SmallVec;
@@ -73,6 +74,29 @@ pub(crate) fn shape_text<'a, B: Brush>(
7374

7475
let mut inline_box_iter = inline_boxes.iter().peekable();
7576

77+
// Merge font features with letter-spacing ligature suppression.
78+
//
79+
// TODO: This allocation is slightly unfortunate (though solvable). It's required currently,
80+
// because the iterator providing `ShapeOptions` has to provide a borrowed `&'a [FontFeature]`,
81+
// which cannot be tied to the lifetime of the call to `Iterator::next`. What we'd need is a
82+
// lending iterator (i.e., we probably just need to let `parley_engine` take some trait
83+
// providing the items).
84+
let style_features: &'_ Vec<SmallVec<[FontFeature; 8]>> = &styles
85+
.iter()
86+
.map(|style| {
87+
let style_features = rcx.features(style.font_features).unwrap_or(&[]);
88+
if !nearly_zero(style.letter_spacing) {
89+
// Later values override earlier values.
90+
OPTIONAL_LIGATURES_OFF
91+
.into_iter()
92+
.chain(style_features.iter().copied())
93+
.collect()
94+
} else {
95+
style_features.iter().copied().collect()
96+
}
97+
})
98+
.collect();
99+
76100
// Split when shaping-relevant style properties change and at inline boxes.
77101
let items = {
78102
// TODO: we currently walk characters here, but we could instead just walk boundaries of
@@ -147,7 +171,7 @@ pub(crate) fn shape_text<'a, B: Brush>(
147171
options: ShapeOptions {
148172
language: item_style.locale,
149173
font_size: item_style.font_size,
150-
features: rcx.features(item_style.font_features).unwrap_or(&[]),
174+
features: &style_features[item_style_index as usize],
151175
variations: rcx.variations(item_style.font_variations).unwrap_or(&[]),
152176
char_style_indices,
153177
},

parley_engine/src/itemize.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ pub struct Segment {
4242

4343
/// A span of text shaped with specific [`ShapeOptions`].
4444
///
45-
/// While shaping text, items are divided into [`Segment`]s.
45+
/// An [`Item`] represents a sequence of constant [`ShapeOptions`], but cannot always be passed to
46+
/// the shaper as a single unit. Within an item, the script or bidirectional text embedding level
47+
/// may change, which requires further splitting the item into segments of constant script and bidi
48+
/// level (see [`Segment`]).
4649
#[derive(Debug)]
4750
pub struct Item<'a> {
4851
/// The character offset in the source text which this item ends.

0 commit comments

Comments
 (0)