fix(task-11): live text styles write TrueType by typeface, refuse missing fonts and arrowhead blocks before any write, un-narrow the dimension walker
Four review findings against the COM styles block, all measured on AutoCAD 2026
(scratch documents from Documents.Add, closed without saving):
1. textstyle_create: `TextStyle.fontFile = "arial.ttf"` raises 'Filer error' for
every bare TrueType name (bundled presets included) after TextStyles.Add has
run, leaving a stub with an empty font that a retry meets as "already exists";
a full path is accepted but the STYLE record then carries the machine path.
`SetFont("Arial", bold, italic, 0, 0)` — the STYLE dialog's own route — stores
the clean `arial.ttf`. The font is now located before Add (`_com_locate_font`:
support path, then the Windows font folders), a TrueType is written by the
family/subfamily read from its `name` table (`_truetype_face`), an SHX by the
name given, an unlocatable file is refused with nothing written, and a write
ActiveX still refuses after Add deletes the entry it added.
2. _ensure_com_textstyle goes through the same helper, so DIMTXSTY / text_style
ARIAL and ISOCPEUR are created on the first call with a real font instead of
failing once and then silently binding a fontless style.
3. dimstyle_create / dimstyle_modify check a user DIMBLK/DIMBLK1/DIMBLK2 against
doc.Blocks before any write (`_com_require_arrowhead_blocks`, the headless
`_require_arrowhead_blocks` twin, same message and table-spelling rewrite);
a write that fails after DimStyles.Add restores the previous ActiveDimStyle
(discarding the unsaved overrides) and deletes the half-made style and any
preset text style the call created.
4. _com_dimensions_using un-narrows each `Layouts.Item(i).Block.Item(p)` —
declared IAcadEntity*, so `.StyleName` raised AttributeError under a makepy
cache and the blanket except reported `[]` — and swallows nothing.
The fake in tests/test_styles.py now models the measured ActiveX rules (bare
TrueType fontFile refused, SetFont by installed typeface, SetVariable refusing an
unknown arrowhead, IAcadEntity narrowing on block items, Delete) so the old code
cannot pass; nine tests cover the four findings. SECTION 18 docstrings state the
live engine's refusal rule for fonts and the pre-write arrowhead check.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
a60f801205
commit
03a5067d83
@@ -6883,8 +6883,13 @@ async def dimstyle_create(
|
||||
DIMCLRD/E/T, DIMSAH, DIMBLK1/2, DIMCEN); a value outside its range
|
||||
(DIMDEC 0-8, sizes > 0, DIMTAD 0-4, DIMDSEP one character, lineweights an
|
||||
AutoCAD code); a name that already exists (use `dimstyle_modify`); a
|
||||
DIMTXSTY that is neither an existing text style nor a bundled preset
|
||||
(ISOCP, ISOCPEUR, ARIAL, ROMANS — those are created, `textstyle_created`).
|
||||
user DIMBLK/DIMBLK1/DIMBLK2 naming a block the drawing does not define
|
||||
(built-in arrowheads need none); a DIMTXSTY that is neither an existing
|
||||
text style nor a bundled preset (ISOCP, ISOCPEUR, ARIAL, ROMANS — those
|
||||
are created on both engines, `textstyle_created`; live, a preset whose
|
||||
font file the seat lacks is refused the same way, nothing written). On
|
||||
the live engine a write ActiveX still refuses after the style is added
|
||||
is rolled back — previous style current, the half-made entry deleted.
|
||||
With `set_current` the next dimension carries the style on both engines.
|
||||
"""
|
||||
from engineering.standards.dimstyles import resolve_dimstyle
|
||||
@@ -6915,10 +6920,11 @@ async def dimstyle_modify(
|
||||
says they still show the old style until redrawn (AutoCAD re-renders on
|
||||
the next regen). Refuses a missing style, an empty `overrides`, a key
|
||||
outside the whitelist, a value outside its range, a DIMTXSTY that does
|
||||
not exist — all before any write. On the live engine, editing a
|
||||
non-current style makes it current for the duration of the call and the
|
||||
previous style is restored (its unsaved overrides are discarded, which is
|
||||
AutoCAD's own DIMSTYLE rule).
|
||||
not exist, a user arrowhead block the drawing does not define — all
|
||||
before any write. On the live engine, editing a non-current style makes
|
||||
it current for the duration of the call and the previous style is
|
||||
restored — also when a write fails midway (its unsaved overrides are
|
||||
discarded, which is AutoCAD's own DIMSTYLE rule).
|
||||
"""
|
||||
await ctx.info(f"Modifying dimension style {name!r}")
|
||||
return await _backend(ctx).dimstyle_modify(name, overrides)
|
||||
@@ -6982,12 +6988,17 @@ async def textstyle_create(
|
||||
) -> dict:
|
||||
"""Create a text style.
|
||||
|
||||
A font that is neither a bundled preset nor on the engine's font path is
|
||||
*written* and reported `font_resolved: false` (AutoCAD substitutes at
|
||||
open; the headless renderer falls back) — never refused, because a DXF
|
||||
stores only the name. Refuses, before any write: a name that exists, an
|
||||
empty font, `width_factor <= 0`, `height < 0`, an oblique angle outside
|
||||
±85°.
|
||||
Headlessly a font nobody can find is *written* and reported
|
||||
`font_resolved: false` (AutoCAD substitutes at open; the headless
|
||||
renderer falls back), because a DXF stores only the name. The live
|
||||
engine cannot do that: ActiveX refuses a font AutoCAD cannot open, so a
|
||||
file that is neither on its support path nor in the Windows Fonts folder
|
||||
is refused there before any write (the message names the folders and the
|
||||
presets); a TrueType font is written by its typeface (`SetFont`, what the
|
||||
STYLE dialog does — the record carries `arial.ttf`, never a machine
|
||||
path), an SHX by the file name. Refuses, before any write on both
|
||||
engines: a name that exists, an empty font, `width_factor <= 0`,
|
||||
`height < 0`, an oblique angle outside ±85°.
|
||||
"""
|
||||
await ctx.info(f"Text style {name!r} with font {font!r}")
|
||||
return await _backend(ctx).textstyle_create(
|
||||
@@ -7055,7 +7066,8 @@ async def mleaderstyle_create(
|
||||
unknown preset; an override key outside the four; `arrow_size` /
|
||||
`text_height <= 0`, `landing_gap < 0`; a name that exists; a `text_style`
|
||||
that is neither present nor a bundled preset (ISOCP, ISOCPEUR, ARIAL,
|
||||
ROMANS — those are created, `textstyle_created`).
|
||||
ROMANS — those are created on both engines, `textstyle_created`; live, a
|
||||
preset whose font file the seat lacks is refused, nothing written).
|
||||
"""
|
||||
from engineering.standards.mleaderstyles import resolve_mleaderstyle
|
||||
|
||||
|
||||
Reference in New Issue
Block a user