Skip to content

Fix: measure inline boxes inside inline roots and send SoftWrap property (#175) - #177

Merged
b-re-w merged 3 commits into
developfrom
feat/button-inline-text
Nov 7, 2026
Merged

b-re-w merged 3 commits into
developfrom
feat/button-inline-text

Conversation

@b-re-w

@b-re-w b-re-w commented Nov 7, 2026

Copy link
Copy Markdown
Member

Closes #175

Root Cause

  1. When an inline-outside element (such as <button style="display: inline-flex">) is a direct child of a block container, blitz-dom wraps inline-outside children in an AnonymousBlock marked IS_INLINE_ROOT.
  2. In MeasuredTree::route, prepare_inline sees that inline boxes exist (!layout.inline_boxes().is_empty()) and returns None, directing the node to Route::Blitz.
  3. Route::Blitz delegated to <BaseDocument as LayoutPartialTree>::compute_child_layout, which uses BaseDocument's internal layout to recursively size inline boxes, bypassing MeasuredTree. Because MeasuredTree was never visited for the button or its text, self.texts contained no measured text entry for the button's label.
  4. During painting (paint/build.rs), the missing text fell back to self.parley_runs(). Parley measured the Hangul characters with its font metrics.
  5. In paint/bridge.rs, PropertyKind::SoftWrap was not sent for unconstrained text runs. In compose-rust (TextResolution.kt), softWrap defaulted to true. When Compose rendered BasicText constrained by Modifier.width(run.rect.width), its Skia font metrics slightly exceeded Parley's advance width. Because softWrap was true, Compose soft-wrapped the Korean syllable to line 2 (Korean allows breaks between syllables under normal word breaking). Because maxLines = 1, line 2 was clipped, but the advance width was reserved, leaving 다 연.
  6. Wrapping in <div style="display: flex"> placed the button as a flex item instead of inside an anonymous block, routing it through Route::Flex and measuring its text run directly with the renderer measurer.

Fix

  • Added pre_measure_inline_boxes to MeasuredTree so that inline boxes inside inline roots are laid out by MeasuredTree before blitz-dom lays out the line, ensuring descendant text runs are measured by RendererMeasurer and recorded in self.texts.
  • In paint/bridge.rs, explicitly send PropertyKind::SoftWrap as text.soft_wrap for text runs.
  • Added regression tests in tests/fr34_html_text.rs and tests/fr34_html_bridge.rs.

Not compiled.

…rty (#175)

When an inline-outside element like a button is placed directly in a block
container, blitz-dom wraps it in an AnonymousBlock marked as an inline root.
Previously, MeasuredTree routed inline roots with inline boxes to Route::Blitz,
which bypassed MeasuredTree and prevented the button's text from being measured
by the renderer measurer. Furthermore, paint/bridge omitted PropertyKind::SoftWrap
for unconstrained text runs, causing compose-rust to default softWrap to true
and soft-wrap Korean syllables when font metrics slightly exceeded Parley's
advance.

This pre-measures inline boxes in MeasuredTree so that descendant text runs
participate in the layout measurer, and ensures PropertyKind::SoftWrap is
explicitly set on Text plan nodes.

Not compiled.
@b-re-w
b-re-w merged commit 55dc89e into develop Nov 7, 2026
4 checks passed
@b-re-w
b-re-w deleted the feat/button-inline-text branch November 7, 2026 01:56
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