fix(docx): float an anchored drawing, and draw a table's own borders - #812
Merged
Conversation
A `wp:anchor` was reported as `as_char` with no position and no graphic style, so it landed at its anchor's character position: the reporter's letterhead logo sat between two lines instead of below them. It now floats at its `wp:positionH`/`wp:positionV` offset, with the wrap and the side it states. Table borders were read from `w:tcPr/w:tcBorders` alone, so a table stating its rules once — on `w:tblPr/w:tblBorders`, a `w:tblStyle`'s included — rendered borderless. The table's borders now reach its cells, each edge drawn by the cell that leads it. New `TableStyle::border`, `::border_inside_horizontal` and `::border_inside_vertical`, mirrored in the JNI, Apple and Python bindings. `w:sz` is in eighths of a point, not half-points, so every border was four times too thick, and `w:val="none"` now says "no border" rather than saying nothing. A cell in a text document starts its content at the top, as word and odf do. Closes #803. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UDi21mwuKRGvGiFcGwETtS
andiwand
force-pushed
the
fix/docx-float-drawing-and-table-borders
branch
from
September 3, 2026 18:25
8b167ab to
ee6b054
Compare
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.
🤖 Generated with Claude Code
Closes #803.
What was wrong
Two defects a user reported from a German letterhead + invoice, both docx-only. The html renderer already implements the whole anchor/wrap matrix and
odffeeds it properly; it is the docx adapter that starved it.A
wp:anchordrawing rendered inline.frame_anchor_typereturnedAnchorType::as_charunconditionally,frame_x/frame_yreturnednullopt, andframe_stylereturned{}— so a floating logo was laid out at its anchor's character position, landing between two lines instead of below them.A table's own borders were dropped.
resolve_table_cell_style_readw:tcPr/w:tcBordersonly. Nothing readw:tblPr/w:tblBorders, so a table stating its rules once — directly or through aw:tblStyle— rendered borderless. Andw:szwas read as half-points where [ECMA-376] 17.3.4 says eighths, so every border that did draw was four times too thick.The change
wp:anchorreports its real anchor type, itswp:positionH/wp:positionVoffset (read_emus_text), and aGraphicStylecarrying its wrap and its side. A page-relative offset is dropped rather than measured against the wrong box.table_cell_borderresolves each cell's edges: its ownw:tcBordersover the neighbour's over the table's, and only the edges the cell leads, so a rule between two cells is one line. NewTableStyle::border,::border_inside_horizontal,::border_inside_vertical, mirrored in the JNI, Apple and Python bindings.read_border_nodereadsw:szin eighths of a point, andw:val="none"/"nil"now says no border rather than saying nothing.td{vertical-align:top}indocument.css— word and odf start a cell's content at the top where the browser default centres it; a sheet still says its own.margin-right:calc(100% - 0 - width), which pinned it to the left.Verified
New fixture
docx/float-drawing+table-borders.docx— awp:anchorwrapped top-and-bottom at an offset, a table whose borders live on aw:tblStyle, and a cell whosew:tcBordersoverride them. 272 lines of unit tests over the border resolution.Full suite 1417 passed / 6 pre-existing skips. Reference output regenerated: 14 public and 7 private files, every one a table gaining the borders it states, plus
image-anchor.docx, where two stacked images now sit side by side at their own offsets — which is where LibreOffice puts them too. The three odt files lose the redundantmargin-right; nothing there moves by more than a pixel. Changed TUs re-checked under-Werror.