Skip to content

Add TableEntity DXF round-trip (cells, alignment, merges, flow direction)#1085

Open
ilCosmico wants to merge 3 commits into
DomCR:masterfrom
ilCosmico:dxf-table-entity-write
Open

Add TableEntity DXF round-trip (cells, alignment, merges, flow direction)#1085
ilCosmico wants to merge 3 commits into
DomCR:masterfrom
ilCosmico:dxf-table-entity-write

Conversation

@ilCosmico

@ilCosmico ilCosmico commented May 20, 2026

Copy link
Copy Markdown
Contributor

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

@ilCosmico ilCosmico changed the title Add minimal TableEntity write support in DxfWriter Add TableEntity DXF round-trip (cells, alignment, merges, flow direction) May 22, 2026
@ilCosmico ilCosmico force-pushed the dxf-table-entity-write branch from ca91691 to 84cd0ff Compare May 22, 2026 15:10
@ilCosmico

Copy link
Copy Markdown
Contributor Author

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.

@ilCosmico ilCosmico force-pushed the dxf-table-entity-write branch from 84cd0ff to 67eb93f Compare June 15, 2026 11:58
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.
@ilCosmico ilCosmico force-pushed the dxf-table-entity-write branch from 67eb93f to 6ff541a Compare June 17, 2026 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DxfTable in Dxf and Dwg writers

1 participant