Conversation
resolve_table_column_widths gave every flexible column a share of the FULL available_width even when another column had an explicit width, instead of deducting that explicit width first. The resolved columns' total could then exceed available_width, silently pushing the table past the page/body margin. Flexible columns now divide only what's left after explicit-width columns are deducted, and only the flexible columns are rescaled to close any gap left by their natural-width floors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
visit(DocraftLoomRectangle*) painted children with no clip at all, unlike the equivalent visit(DocraftLoomCanvas*). A child whose computed size exceeded the rectangle's own frame (e.g. a Text node whose own explicit wrap_width overrides the width relayed by its parent rectangle) painted past the rectangle's edges instead of being contained by it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
visit(Rectangle*) and visit(Canvas*) each hand-rolled the same save_state()/clip_rectangle()/paint children/restore_state() sequence (flagged as duplication by SonarQube). Extracted into a shared helper, mirroring how draw_container_background() already factors out the background paint sequence shared by container node visitors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
This was referenced Aug 16, 2026
Cadons
deleted the
80-text-wrapping-duplicates-content-when-a-multi-word-textcell-needs-to-wrap-regression-vs-b386ee8
branch
August 31, 2026 21:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Three regressions found and fixed while re-validating this branch against
main(b386ee8).fix(text-wrapper)— duplicated boundary word when wrapping multi-word textDocraftLoomTextWrapper::wrap_paragraphbuilt the wrap candidate withcurrent_line.append(" ").append(word).std::string::appendmutates theobject in place and returns a reference to itself, so this silently
overwrote
current_lineas a side effect of buildingcandidate— notjust
candidate. When the candidate didn't fit and the code fell back tolines.push_back(current_line),current_linehad already beenoverwritten to include the overflowing word, so that word was pushed on
the current line and reprocessed onto the next one. Any
<Text>(bareor inside a table
<Cell>) with 2+ words whose full width exceeded itsbox duplicated the boundary word in the rendered PDF — a silent content
corruption, not just a layout glitch.
Fixed by building
candidatewithout mutatingcurrent_line(
current_line + " " + word).fix(loom-table)— table columns overflowing available widthresolve_table_column_widthsgave every flexible column a share of thefull
available_widtheven when another column in the same table hadan explicit
width, instead of deducting that explicit width first. E.g.with
available_width = 200and one column pinned to150, the other(flexible, weight 1) column used to get
200/2 = 100instead of the50actually left over — total
250 > 200, silently overflowing thepage/body margin.
Flexible columns now only divide what's left after explicit-width columns
are deducted, and only those flexible columns are rescaled to close any
gap left by natural-width floors.
fix(loom-rectangle)— text/content overflowing rectangle boundsvisit(DocraftLoomRectangle*)in the rendering processor painted childrenwith no clip at all, unlike the equivalent
visit(DocraftLoomCanvas*). Achild whose computed size exceeded the rectangle's own frame (e.g. a
<Text>whose own explicitwidthoverrides the width relayed by itsparent
<Rectangle>) painted past the rectangle's border instead ofbeing contained by it.
Now clipped the same way Canvas already is.
Verification
All three verified end-to-end via
docraft_tool+ rendered PDF (visualbefore/after comparison for the wrapping duplication and the rectangle
clip), plus new/updated regression tests:
DocraftLoomTextWrapperTest.*(new — the wrapper had no dedicated unittests before this)
DocraftLoomTableTest.ExplicitWidthIsRespectedAndRemainderRedistributed(updated — it previously asserted the buggy dilution as expected
behavior)
DocraftLoomRectangleTest.RenderingClipsChildrenToRectangleBoundsBracketedBySaveRestore(new — Rectangle's rendering pass had no test coverage before this)
Full suite: 430/430 passing.