Skip to content

fix(layout-engine): render underlined tabs as one continuous line#3627

Merged
caio-pizzol merged 5 commits into
mainfrom
caio-pizzol/sd3330-underlined-tabs-followup
Jun 3, 2026
Merged

fix(layout-engine): render underlined tabs as one continuous line#3627
caio-pizzol merged 5 commits into
mainfrom
caio-pizzol/sd3330-underlined-tabs-followup

Conversation

@caio-pizzol
Copy link
Copy Markdown
Contributor

@caio-pizzol caio-pizzol commented Jun 3, 2026

Follow-up to #3611.

Draws one shared underline across text, spaces, and underlined tabs so the inline case and the tab-stop case stay continuous. Also expands the tab paint cache key and tightens tab-only line metrics to use the tab font.

Before:
image

After:
image

…lay (SD-3330)

Underlined tabs drew a border-bottom while adjacent text used native
text-decoration, meeting at slightly different y and leaving a seam. One
line-level overlay now owns the underline for both the inline and
segment-positioned branches; native painters are suppressed where it covers
the run. Scoped to single/double/dotted/dashed (words/wave/heavy and theme
colors stay on the existing path). Tab paint-version now keys on
fontSize/fontFamily/color/font epoch so a style change repaints.

Covered by painter unit tests (inline + segment-positioned merged geometry),
version-signature tests, overlay-scope guards, and a behavior test that types
text+tabs, selects all, underlines, and asserts one continuous overlay.
…SD-3330)

A tab-only paragraph has no text run, so the line fell back to synthetic
0.8/0.2 ascent/descent. Derive metrics from the tab's own font so a tab-only
underlined line gets the same measured ascent/descent (underline offset, line
height) as the equivalent text line. Effective only in a real browser; jsdom
has no real font metrics, so validate via the layout/visual suites in CI.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d237d77db5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/layout-engine/painters/dom/src/runs/render-line.ts Outdated
@caio-pizzol caio-pizzol requested review from harbournick and tupizz June 3, 2026 21:19
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

RTL paragraphs skip segment positioning and fall to inline flow so the browser
places the bidi tabs, but the underline overlay built LTR left-offsets from the
line start and suppressed the native underlines - painting on the wrong side.
Gate the overlay on !isRtl so RTL keeps native text-decoration + tab borders; a
mirrored RTL overlay is larger work and unnecessary here. Adds a painter
regression test (RTL underlined-tab line -> no overlay, natives intact).
…nes (SD-3330)

The inline-flow overlay builds left-origin offsets, so it mispainted - and
suppressed the natively-correct underlines - on center/right-aligned,
hanging/negative-indent, and atomic-run lines. Gate it to left/start-aligned
LTR lines with a matching indent origin, built only from text/tab/line-break
runs; the segment-positioned branch stays exempt (it captures spans at the same
x it positions runs at). Add the tab's bold/italic to the version key (tab-only
metrics depend on them via getFontInfoFromRun) and pin the overlay-top unit
assertions to underlineOffsetFromLineTop. Tests: center/right alignment,
hanging indent, and a boolean-underline field annotation.
… off (SD-3330)

Sharpen the atomic-run regression: beyond checking no overlay is produced, assert
the field annotation's own underline is not suppressed (textDecorationLine not
forced to 'none'), via the aria-label selector.
@caio-pizzol caio-pizzol merged commit 85802da into main Jun 3, 2026
68 checks passed
@caio-pizzol caio-pizzol deleted the caio-pizzol/sd3330-underlined-tabs-followup branch June 3, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants