Summary
The layoutInlineItems function in the rich-note demo can produce lines whose accumulated width exceeds maxWidth by ~4px. This happens when chips and text fragments fill a line almost exactly, leaving near-zero remainingWidth for the next text item.
Reproduction
Run the rich-note demo at a width of ~320px. Line 7 ("Keep layoutNextLine() public, tag this P1 , ") computes to 324.2px against a 320px budget.
Root Cause
When remainingWidth is near zero after placing a chip:
- The text-case check
reservedWidth >= remainingWidth passes (reservedWidth=0, remaining=ε)
layoutNextLine(prepared, cursor, Math.max(1, remainingWidth)) inflates the budget to 1px
layoutNextLine returns at least the first grapheme (e.g. , at ~4px) even though only ε was available
- The accumulated
lineWidth exceeds safeWidth by the width of that grapheme
Observed on
Lynx port of pretext, where lynx.getTextInfo() measurements may differ slightly from rendering, making tight fits more likely. The algorithm issue exists in the upstream rich-note.ts as well — it just rarely triggers in browsers due to closer measurement/rendering agreement.
What we tried
- Adding an overflow guard after
layoutNextLine returns in the slow path — guard never fires, suggesting the overflow comes from a different code path than expected
- Tightening the
reservedWidth >= remainingWidth check with a 1px minimum — also didn't resolve it
- Ruling out
fontWeight mismatch (getTextInfo doesn't accept fontWeight) — tested with all weights at 400, issue persists
Possible fix direction
The overflow may involve interaction between the fast path (full text fits) and accumulated floating-point imprecision across multiple fragments with INLINE_BOUNDARY_GAP. Needs deeper tracing of the exact arithmetic on the overflowing line.
Summary
The
layoutInlineItemsfunction in the rich-note demo can produce lines whose accumulated width exceedsmaxWidthby ~4px. This happens when chips and text fragments fill a line almost exactly, leaving near-zeroremainingWidthfor the next text item.Reproduction
Run the rich-note demo at a width of ~320px. Line 7 ("Keep layoutNextLine() public, tag this P1 , ") computes to 324.2px against a 320px budget.
Root Cause
When
remainingWidthis near zero after placing a chip:reservedWidth >= remainingWidthpasses (reservedWidth=0, remaining=ε)layoutNextLine(prepared, cursor, Math.max(1, remainingWidth))inflates the budget to 1pxlayoutNextLinereturns at least the first grapheme (e.g.,at ~4px) even though only ε was availablelineWidthexceedssafeWidthby the width of that graphemeObserved on
Lynx port of pretext, where
lynx.getTextInfo()measurements may differ slightly from rendering, making tight fits more likely. The algorithm issue exists in the upstreamrich-note.tsas well — it just rarely triggers in browsers due to closer measurement/rendering agreement.What we tried
layoutNextLinereturns in the slow path — guard never fires, suggesting the overflow comes from a different code path than expectedreservedWidth >= remainingWidthcheck with a 1px minimum — also didn't resolve itfontWeightmismatch (getTextInfo doesn't accept fontWeight) — tested with all weights at 400, issue persistsPossible fix direction
The overflow may involve interaction between the fast path (full text fits) and accumulated floating-point imprecision across multiple fragments with
INLINE_BOUNDARY_GAP. Needs deeper tracing of the exact arithmetic on the overflowing line.