Add TableEntity DXF round-trip (cells, alignment, merges, flow direction)#1085
Add TableEntity DXF round-trip (cells, alignment, merges, flow direction)#1085ilCosmico wants to merge 3 commits into
Conversation
ca91691 to
84cd0ff
Compare
|
Hi @DomCR, I just saw your March comment on #995 about wanting to refactor CadTable before tackling the writers. This PR sits on top of the existing TableEntity API and does not touch CadTable internals, just the DXF reader and writer code paths, so it should not get in the way of that refactor. We had a downstream need for the round trip sooner, which is why I went ahead. If your refactor lands first and the shape changes, I can rebase, or close this PR if you would rather start fresh. Whatever works best for you. |
84cd0ff to
67eb93f
Compare
DxfWriter previously skipped TableEntity with a "not implemented" notification, so saving a CadDocument containing an ACAD_TABLE produced a DXF with an empty modelspace. Emit the AcDbBlockReference (Insert) subclass first so the viewer can instantiate the anonymous BlockRecord that holds the table's rendered geometry, then the AcDbTable subclass with the table-level data (version, horizontal direction, value flag, row/column counts and sizes, style and block references) and a minimal per-cell payload (type, edge/merge flags, autofit, border counts, optional text content and rotation). Advanced cell features (block-cell payloads, multi-run formatted content, custom data, borders, format runs, merged ranges) are not yet round-tripped and will emit a Warning notification so consumers know some data is lost.
When the writer emits both a populated AcDbBlockReference (pointing at the anonymous BlockRecord that holds the exploded table geometry) and a fully populated AcDbTable subclass with rows, columns and per-cell content, AutoCAD renders the table twice: once from the BlockReference and once from the AcDbTable cells, with the two renderings offset because AutoCAD's AcDbTable renderer does not pick up the Insert's transform. Emit only the AcDbTable header (version, horizontal direction, value flag, style and block handles) with row and column counts set to 0. AutoCAD then has no cell data to render from and falls back to drawing the BlockReference, which gives a single correctly positioned table. Cell metadata is not round-tripped through DXF in this minimal pass; a follow-up can add it together with the proxy graphic preview that AutoCAD-produced files emit (DXF group codes 160/310) so the AcDbTable renderer is shadowed by the proxy graphic instead of being suppressed.
The DXF writer for TableEntity was emitting cell rows and cell contents but dropping the per-cell alignment (group code 170) and the cell flag bits that mark which overrides are active (group code 91). A strict reader fell back to the table style defaults, so the original alignment set on each cell was lost on round-trip. Emit the cell flag with the baseline state value AutoCAD-produced files use (262192) and OR in 0x01 plus a 170 record when the cell carries an explicit alignment override. On the reader side, capture group 170 onto the cell StyleOverride so callers see the alignment through the regular API. The DXF cell stream also encodes merged cells per-cell only: the top-left anchor carries the column and row span in BorderWidth/BorderHeight (175/176) and the remaining cells carry MergedValue=1 (173). The table-level MergedCellRanges collection that consumers actually iterate was never populated. Rebuild it in CadTableEntityTemplate.build() by scanning the grid after all cells are parsed, so DXF and DWG paths expose the same shape.
67eb93f to
6ff541a
Compare
|
Hi @DomCR, coming back to this now that the CadTable refactor has landed. The PR still merges cleanly on top of the new API, and it covers the TableEntity DXF write path that is currently a not-implemented notify on master. I saw you have already started on the writers with the TableStyle DXF support, so I did not want to just push ahead and step on that. If it helps, I am glad to lend a hand finishing the table writers starting from this PR, rebasing or reshaping it to match your refactor, and taking the DWG side too if you want it. Totally your call on scope and how to split things. And if you would rather keep this part yourself, no problem at all, just let me know and I will step back. Either way, thanks for the refactor, it made this much cleaner to build on. |
|
Hi @ilCosmico, Before implementing the support for the tables in dxf I want to solve the problem with the I still need to refactor the dxf reader to fix the mess that the Having said that, if this implementation works with existing files and it rewrites a dxf file with a table, I can create a transfer branch and check it once I refactor the Let me know what you prefer to do. |
|
Hi @DomCR, that plan works for me. The transfer branch is fine, and I will rebase or adapt the PR after the TableContent refactor lands, whatever shape it takes. On your question: yes, the implementation round-trips existing files. A dxf with a table reads and rewrites with cells, per-cell alignment, merge ranges and flow direction preserved, and we validated it downstream with our product tests against files from real drawings. One known limitation, noted here for transparency: the writer does not emit the proxy graphic preview blob, so viewers regenerate the table from the data instead of the cached preview. Content and layout are correct, only the hover preview behaves differently, as in the screenshot below (the rotated overlay is the regenerated preview during hover).
Take your time with the refactor, and thanks for keeping this on the table 😅 |

Until now the DXF writer only emitted the block reference for a TableEntity. This change writes the AcDbTable subclass too, with rows, columns, per-cell data, margins, flow direction, alignment (group 170 plus the matching cell flag at group 91), and merge ranges (per-cell via BorderWidth/BorderHeight and MergedValue).
On the reader side, per-cell alignment is now captured and the table-level MergedCellRanges is rebuilt by scanning the grid, so a DXF table comes back with the same merge layout as one read from DWG.
Known limitation: with no proxy graphic preview attached, AutoCAD and DWG TrueView draw the table twice (once from the anonymous block, once from the cell stream). Readers that consume the cell stream directly show a single, correct table.
Closes #995