Skip to content

feat(layout): expose positioned visual cluster iteration - #2

Open
ldm0 wants to merge 1 commit into
fix/inline-object-bidi-rebasedfrom
perf/positioned-visual-clusters
Open

ldm0 wants to merge 1 commit into
fix/inline-object-bidi-rebasedfrom
perf/positioned-visual-clusters

Conversation

@ldm0

@ldm0 ldm0 commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Moli currently has to reproduce Parley's visual item positioning to avoid calling the linear-time Cluster::visual_offset() for every cluster. Add Line::positioned_visual_clusters(), yielding (Cluster, f32) in visual left-to-right order with no position cache or heap allocation, so consumers can obtain all positions in one pass.

Offsets include LineMetrics::offset and exclude inline_min_coord, matching visual_offset() bit for bit. Preceding runs use run.advance() while clusters within a run use cluster.advance(), preserving spacing, justification and floating-point summation order. The iterator reads Parley's current visual item stream directly, including inline boxes and host item reordering, and supports cloning and iterator adaptors.

Validation:

  • cargo fmt --all
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo nextest run --no-fail-fast: 502 passed, 1 skipped.
  • RUSTDOCFLAGS='--cfg docsrs -D warnings' cargo +nightly doc --workspace --all-features --no-deps --document-private-items
  • cargo check -p parley --no-default-features --features libm
  • Four regression tests covering mixed bidi text, ligatures, combining characters, positive/negative letter spacing, word spacing, consecutive and zero-width inline boxes, indent, all six alignments, repeated line breaking/alignment, nonzero line origins, visual box reordering, clone/nth/skip/last, empty/box-only lines and an 8,192-cluster single run. Positions are checked against the independent visual_offset() implementation, using exact float bits.

Added release benchmarks comparing the two library access patterns on already-built layouts. Final revision a18cfc3ba6638d44ff0d0c9ce7b0b3396b42e8cf, Intel Core i9-13900K, rustc 1.94.0. Three separate process runs, 100 samples per case; the table reports the median of the three process means as rounded by Tango:

Text Clusters Per-cluster visual_offset() Positioned iterator
LTR single run 128 146.6 µs 2.3 µs
LTR single run 512 2.3 ms 8.8 µs
LTR single run 2,048 36.1 ms 35.8 µs
Mixed LTR/RTL 128 20.0 µs 2.8 µs
Mixed LTR/RTL 512 174.7 µs 11.1 µs
Mixed LTR/RTL 2,048 2.2 ms 44.6 µs

Reproduce with cargo +1.94.0 bench -p parley_bench --bench main -- solo --filter 'Cluster Positions -*' --samples 100 --seed 20261016.

These measurements compare Parley's public API access patterns. Moli already has a linear accumulator after lexmount/moli#1434; the integration consolidates ownership of that existing algorithm.

The base is fix/inline-object-bidi-rebased at d0f5452487b872562102fde2c133d445272bcccc, the exact revision currently used by Moli, to avoid pulling unrelated fork changes into the integration.

Moli consumer integration: lexmount/moli#1599.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant