fix(arch, table): what the 1.6.0 README renders showed

- The exterior dimension chains follow the plot scale. DIMSCALE is the
  plan's scale while they are drawn and is put back afterwards; a 1:50
  chain's 2.5 text had been 2.5 drawing units, 0.05 mm on the sheet.
- A headless TABLE merges its title row, as AutoCAD's TABLE does; a long
  title no longer wraps inside the first column over the header row.
- A headless TABLE's cell margin scales with the lettering. A flat 1.0 was
  0.02 mm on a 1:50 schedule; tables at the default 2.5 text are unchanged.
- drawing_new writes the Standard text style in arial.ttf, as AutoCAD
  2026's acadiso.dwt ships it: txt has no superscript two, so 'm²' read
  'm?' live and rendered as a box headlessly. The five bundled templates
  are rebuilt and build_templates --check reproduces them.

Each fix has a test that fails on the old code.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-25 00:17:10 +03:00
co-authored by Claude Opus 5.5
parent 554daff8d0
commit 7e7fe11a71
13 changed files with 182 additions and 370 deletions
+4 -1
View File
@@ -11,6 +11,9 @@ class TableLayout:
column_widths: list[float]
row_height: float
text_height: float
#: The first row is a title, merged across every column as AutoCAD's
#: TABLE draws it.
title_row: bool = False
@property
def row_count(self) -> int:
@@ -71,7 +74,7 @@ def prepare_table_layout(
if any(width <= 0 for width in widths):
raise RuntimeError("entity_create_table: column widths must be positive")
return TableLayout(data, widths, float(row_height), float(text_height))
return TableLayout(data, widths, float(row_height), float(text_height), title_row=bool(title))
def validate_mleader(points: list[list[float]], text: str) -> list[tuple[float, float]]:
+39 -26
View File
@@ -375,42 +375,55 @@ async def add_stair(backend, stair: dict, *, lang: str = "en", scale=50) -> dict
async def draw_chains(
backend, walls, openings, *, sides=("bottom", "left"), scale=50, first_offset=None, step=None
) -> dict:
"""The exterior chains as real linear DIMENSIONs on the dimension layer."""
"""The exterior chains as real linear DIMENSIONs on the dimension layer.
Their text, arrows and gaps follow the plot scale like every other plan
annotation: DIMSCALE is ``scale`` while the chains are drawn, so each chain
dimension carries it, and the drawing's own DIMSCALE is put back afterwards.
Drawn at the style's DIMSCALE 1, a 1:50 chain's 2.5 text was 2.5 drawing
units - 0.05 mm on the sheet, which is no text at all.
"""
intents = exterior_chains(
walls, openings, sides=sides, first_offset=first_offset, step=step, scale=scale
)
layer = ARCH_ROLE_LAYER["dim"]
await ensure_arch_layers(backend, [layer])
factor = float(scale)
previous = await backend.system_get_variable("DIMSCALE")
previous = 1.0 if previous is None else float(previous)
handles: list[str] = []
rows: list[dict] = []
for intent in intents:
horizontal = abs(intent.p2[1] - intent.p1[1]) <= abs(intent.p2[0] - intent.p1[0])
info = await backend.dimension_linear(
intent.p1[0],
intent.p1[1],
intent.p2[0],
intent.p2[1],
intent.text_at[0],
intent.text_at[1],
0.0 if horizontal else 90.0,
layer,
)
handles.append(info.handle)
rows.append(
{
"row": intent.feature,
"from": list(intent.p1),
"to": list(intent.p2),
"value": math.dist(intent.p1, intent.p2),
}
)
if abs(previous - factor) > 1e-9:
await backend.system_set_variable("DIMSCALE", factor)
try:
for intent in intents:
horizontal = abs(intent.p2[1] - intent.p1[1]) <= abs(intent.p2[0] - intent.p1[0])
info = await backend.dimension_linear(
intent.p1[0],
intent.p1[1],
intent.p2[0],
intent.p2[1],
intent.text_at[0],
intent.text_at[1],
0.0 if horizontal else 90.0,
layer,
)
handles.append(info.handle)
rows.append(
{
"row": intent.feature,
"from": list(intent.p1),
"to": list(intent.p2),
"value": math.dist(intent.p1, intent.p2),
}
)
finally:
if abs(previous - factor) > 1e-9:
await backend.system_set_variable("DIMSCALE", previous)
return {
"count": len(handles),
"handles": handles,
"dimensions": rows,
"text_height": (
"set by the current dimension style; at 1:{0:g} set DIMSCALE={0:g} with "
"dimstyle_modify so the text plots at its paper height".format(float(scale))
),
"dimscale": factor,
"backend": backend.name,
}