Skip to content

Text wrapping duplicates content when a multi-word Text/Cell needs to wrap (regression vs b386ee8) #80

Description

@Cadons

Regression found against commit b386ee8 (PR #79, "weight common attribute silently no-ops outside Layout orientation=\"horizontal\""), which introduced a new dedicated text-wrapping module (docraft_loom_text_wrapper.cc/.h). Found while re-validating five previously-fixed issues against the current main for an unrelated test-document suite — this one is new, not one of those five.

Summary

When a <Text> (bare, or inside a <Cell>) has two or more space-separated words and its natural (unwrapped) width exceeds its box width, the wrap-boundary word can be printed complete on one line and then repeated — reprocessed as if it were unplaced — on the following line(s), instead of being cleanly split once. The result is corrupted, misleading duplicate text in the rendered PDF, not just a layout/cosmetic issue.

A single word alone (no other word on that Text) wraps correctly via character-level breaking, no duplication. The bug requires ≥2 words.

Minimal reproducer

<Document>
  <Body margin_left="40" margin_top="20">
    <Text font_size="9" width="56">A. Balasubramanian</Text>
    <Blank height="10"/>
    <Text font_size="9" width="56">Balasubramanian</Text>
    <Blank height="10"/>
    <Text font_size="9" width="56">The quick brown fox jumps</Text>
    <Blank height="10"/>
    <Text font_size="9" width="200">A. Balasubramanian</Text>
    <Blank height="10"/>
    <Text font_size="9" width="30">Balasubramanian</Text>
  </Body>
</Document>
docraft_tool dup.craft dup.pdf
pdftotext -layout dup.pdf -

Output (pdftotext -layout, matches the visual PDF — not an extraction artefact, confirmed by rendering to PNG at 150 dpi):

A. Balasubramanian        <- case 1: two words, width=56 (too narrow)
Balasubrama                    ink shows the FULL first word AND a
nian                            second, partial copy of it

Balasubramanian            <- case 2: one word alone, width=56 (control)
                                clean single wrap, no duplication -- correct

The quick brown             <- case 3: five short words, width=56, no
brown fox jumps                 single word individually exceeds width
jumps                           "brown" and "jumps" both duplicated

A. Balasubramanian          <- case 4: two words, width=200 (fits) -- correct

Balasubramanian              <- case 5: one word alone, width=30 (forces
Balasu                          3-way char split) -- clean, no duplication,
brama                           confirms single-word char-splitting itself
nian                             is fine

Cases 2 and 5 (single word, any width) are correct. Cases 1 and 3 (≥2 words, wrap required) both duplicate. Case 3 is the more concerning variant, since it shows this is not limited to the long-unbreakable-word / character-splitting fallback path — it also corrupts normal multi-word wrapping where no individual word is even close to the box width.

Also note in case 1/3 the first line does not appear to respect width at all ("A. Balasubramanian" and "The quick brown" both print wider than the declared box) — the constraint seems to only kick in on the second pass, which then re-includes content already placed by the first.

Real-world trigger

Found via a landscape <Table> column (<Cell width="…">) holding a Firstinitial. Surname value ("R. Balasubramanian") one row-owner field among six on a reconciliation report. Every other owner name in the same dataset was short enough to fit its column without wrapping and rendered fine — only the one row whose content genuinely needed to wrap corrupted. This will affect any data-driven table (names, addresses, free-text descriptions) where cell content length varies and only some rows are long enough to require a wrap.

Impact

Rated above the five just-fixed issues on the "silent corruption" axis: earlier issues either failed loudly (good) or dropped/warned about missing content. This one actively fabricates incorrect text in the output PDF with exit code 0 and no diagnostic — a document can render "successfully" while showing garbled duplicated names/words, which is worse for a compliance or financial document than an honest failure.

Environment

  • docraft_tool, built from main at b386ee8 (macOS, AppleClang 21, Release, -DBUILD_TESTS=ON, 426/426 existing unit tests pass)
  • Confirmed both as a bare <Text width="…"> and inside a <Table><Cell width="…">

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions