* Dynamic blocks: a distance's grip shows only at an end an action follows
A linear parameter's grip at an end no action is attached to moves nothing,
and AutoCAD doesn't show it on the reference: a stretch that follows only the
end's change (EndXDelta, EndYDelta) leaves the base without a grip, and the
other way round. A connection to the distance itself follows both ends, as
does a distance measured from its midpoint; a parameter no action is attached
to keeps the grips the block gives it. (A block saved with one grip has no
base grip at all, which was already honoured.)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Dynamic blocks: a visibility state that lists a parameter shows its grips
AutoCAD shows a parameter's grips in a visibility state that lists the
parameter, though the state doesn't list the grips themselves (a label block's
Label state lists Position1 and Distance2 but not their grips, and AutoCAD
shows the square and the arrow). A grip now shows when the state lists it or
its parameter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Paper-space units followed the drawing's MEASUREMENT only, so a layout
whose page setup is in millimetres (plot paper units 1), common in
drawings from AutoCAD with MEASUREMENT 0, was taken as inches: its PDF
drew everything 25.4 times too large, off the page.
PageSetup gains `paper_mm`, read from LAYOUT group 72 = 1; 72 = 0 still
leaves the units to MEASUREMENT, since earlier CADCraft versions wrote 0
for every layout. The layout's sheet, its PDF/raster plots, PREVIEW and
the pens of what its viewports show use the layout's units, and the
writer stores 72 = 1 for layouts in millimetres (it wrote 0 always).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
acadrust writes every paper-space entity with entity mode 1 ("paper
space"), including those of *Paper_Space0, *Paper_Space1… and relies on
each block's entity list; AutoCAD reads mode 1 as the *Paper_Space
block's, so what was drawn on a second layout (and its viewports, in
drawings from AutoCAD with several layouts) landed on the first one, and
the second stayed empty. The DWG bridge now writes those entities owned
by their block (entity mode 0 with the owner handle), as the public DWG
specification describes; the first layout's entities stay mode 1.
The io tests read CADCraft's DWG back with acadrust (a dev-dependency,
the same version as cadcraft-dwg's) to check the modes as written.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* DIMASSOC: no standard reference to a polyline's vertex or segment (#1049)
A dimension on a polyline vertex was written with an AcDbOsnapPointRef
naming the polyline but no subentity (groups 73 and 91 both 0); AutoCAD
then resolved it to the polyline's first segment when it regenerated
the dimension, and the value changed without warning (210 became 5).
Such points (LWPOLYLINE, 3D polyline, MLINE, also as the second object
of an intersection) are now left out of the DIMASSOC object, as the
report suggests: AutoCAD sees them as non-associative and the values
stay right. CADCraft keeps every link through its own xdata, and
references to single-curve objects (lines, arcs, circles, points) are
written as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* DIMASSOC: reference polyline vertices by segment, as AutoCAD does
Following the black-box observation of AutoCAD 2026 in the PR review: a
polyline vertex is referenced as an end of one of its segments,
subentity type 73 = 2 (edge) and the 1-based segment in 91 (segment k
runs from vertex k-1 to vertex k; a closed polyline's closing segment is
the last), with osnap 1 / parameter 1.0 for a segment's end and 13 / 0.0
for its start. Vertex 0 is written as the start of segment 1, vertex k
as the end of segment k, falling back to the other neighbour when that
one is an arc; a vertex between two arcs (where AutoCAD writes an angle
parameter, not yet tested) still gets no reference, nor do 3D polylines
and multilines.
Reading uses the segment and osnap for polylines: AutoCAD leaves the
reference point at 0,0, so the nearest-vertex fallback attached
AutoCAD's associative dimensions on polylines to the vertex nearest the
origin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* AutoCAD interop: justified text, DIMPOST, current dimension style, *D block colours
What AutoCAD takes from CADCraft's DWG/DXF as it is:
- Justified TEXT/ATTRIB/ATTDEF (#1050): group 10 is now where the
baseline starts, from the alignment point and the text's width, not
the alignment point itself; AutoCAD drew centred and right-aligned
text from DWG starting at its alignment point. A stored point close to
CADCraft's own (AutoCAD's, exact for its fonts) is kept.
- DIMPOST (#1053) is written even when empty: the DWG bridge defaulted a
missing one to "<>", and AutoCAD then dropped the "R" of radius
dimensions when it regenerated them.
- The current dimension style (#1051): the DXF header now carries its
DIM* variables (AutoCAD draws new and updated dimensions from them);
the DWG bridge points $DIMSTYLE at the style by name (its handle was
renumbered, so the writer fell back to Standard), and reading a DWG
gives the current dimension and text styles their names back.
- *D blocks (#1052): lines, arrows, extension lines and text take the
style's DIMCLRD/DIMCLRE/DIMCLRT instead of ByBlock.
#1054 (group 42 of a rotated linear dimension) was already fixed on
main by #855; acad_interop.rs keeps it covered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Test: angular dimensions store their angle in radians (group 42)
Three-point (60°, 174°) and two-line (120°) angular dimensions, read back
from the DWG as DXF. Already right on main since #855; this guards it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Justified text made here: Left Middle and Left Bottom write their baseline start too
text_insert kept a stored insertion point that was within 0.1 x an
estimated width + 0.5 x height of CADCraft's baseline start, taking it for
AutoCAD's own. The width was estimated from the alignment point's offset,
which for Left Middle is only h/2 (vertical), so a text made here, whose
stored point is the alignment point, passed and kept it: AutoCAD drew it
half a height high (Left Bottom: a third). Reported with a test by
@lee-cyrille-maskell.
A stored point equal to the alignment point is now always stale. Otherwise
the offset is split along and across the baseline: along it the same slack
as before (a tenth of the text's width plus half its height, as fonts and
their substitutes differ most in width), across it a fifth of the height.
Multiline attribute values keep the distance-only check, since their lines
are placed by the embedded MTEXT.
On 12 drawings made in AutoCAD (1,055 justified texts) the insertion points
written are the same as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A complete 1,326-entry Hungarian catalog: every key of the Ukrainian reference catalog and the
four menu headings (Méretezés, Rajzolás, Módosítás, Nézet). Written from the meaning of
CADCraft's English strings in general technical drawing vocabulary; no other product's
localization and no other catalog was used. The interface addresses the user informally;
command-line keywords, system variables and osnap tokens stay English.
- Preference::Hungarian (hu); hu-HU and hu_HU.UTF-8 select it. Counts take one form, as a
Hungarian numeral is followed by the singular (plural_ko, plural_forms: 1).
- hu in REPORTED; tests for locales, saved preference and plurals, menu headings, a live
switch, dialogs and the Hungarian letters (ő, ű) in the bundled fonts. No gaps are reported
for Hungarian.
- ATTRIBUTION, README, docs/localization.md, docs/localization-parity.md,
docs/control-protocol.md and the options doc comment.
Text, raster images, <use> copies, <style> sheets and rounded rectangle
corners aren't read yet. They were dropped without a word; the reader now
counts them and adds one read note (the channel DWG reading already uses),
which OPEN echoes and returns as a warning. Content that isn't drawn (in
<defs> or hidden) isn't counted.
craft-libs#169 is merged, so the fork pin is no longer needed. Pinned to
storytold/craft-libs 82a24b006eefa036b43c09a67fb9a3fbd17ffe63 (main after the merge) rather than the older 12281d07,
which predates resolve_absolute and the Windows colon refusal.
Found while testing crates/geom/src/curve.rs:435 (bulge_to_arc) together with crates/geom/src/lib.rs:45-48 (ccw_sweep)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Xref paths saved in a drawing (on open, on Reload, in the External
References list, XOPEN, nested xrefs) and table data-link paths re-read by
DATALINKUPDATE go through doc_path::resolve (craft-docpath): relative
paths resolve beside the drawing that stores them, and paths to other
computers, devices and URLs are not opened. Such an xref is Unresolved
with the reason, unless a file of its name is beside the host drawing.
Paths given to XATTACH, -XREF Path and DATALINK are used as given.
One load of xrefs reads at most 1 GB from referenced files in total.
A line that is not a JSON object with a string method, including an HTTP
request line, gets one error reply and the connection closes before
anything after it is read. Connections time out after 10 minutes idle or
30 seconds blocked on a write, and at most 64 requests wait for the app;
more are answered busy.
LAYER, LTYPE, STYLE and DIMSTYLE records were appended with no cap while
the VIEW, UCS and VPORT arms of the same loop guard at MAX_OBJECTS — so
a hostile DXF could grow the layer table (each record found by a linear
case-insensitive name scan) without bound. The same guard now applies to
all seven table kinds.
Behaviour is unchanged for every legal drawing: no drawing approaches a
million table records, so no regression test can reach the cap at unit
scale (the same reason the peer guards shipped without one). The
quadratic cost of the name lookups themselves is a separate, larger
change (resolving table names through a map while reading) deliberately
left to the maintainers.
* Zoom and pan regenerate in the background instead of freezing the window
A rebuild that only the view asks for (a new 2x zoom band, a pan out of the
built area) now runs on a worker thread while the canvas keeps drawing the
previous display list, scaled by the view uniform. The worker builds the list,
converts it to vertex data and creates the GPU buffers, so the frame that swaps
it in only swaps buffers. One build runs at a time; a result from an older
drawing revision is dropped. Edits, the first build and the web build (no
threads) still rebuild synchronously.
ZOOM no longer calls touch(): it changes the view, not the drawing, and the
bumped revision made every typed zoom a full blocking rebuild (wheel zoom
never did). REGEN, REGENALL and layout switches still touch.
ui.screenshot waits (up to 6 s) for a background rebuild so agents capture
the new view; ui.inspect perf reports "building".
On a hatched 12k-entity DWG (~340k primitives) the longest UI stall per zoom
went from 2-4.5 s to 26-64 ms.
Also: cargo fmt of a comment in engine/src/prompt.rs that was failing the fmt
gate on main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Cancel a background rebuild when the view moves on
A view that needs a different display list now cancels the build in flight
and starts one for itself, instead of waiting for the outdated build to land
and only then starting the next. A long scroll through many zoom bands builds
only for where it stops: the list lands about one build after the last step
(2.0-2.3 s on a hatched 12k-entity DWG) instead of up to two, and an outdated
build no longer keeps a core busy.
cadcraft_render::Options gains `cancel` (an Arc<AtomicBool>); a set flag stops
the build at the next entity (block contents included) and the hatch sweep at
its next pattern line, returning a partial list the caller discards. The
canvas's Job sets its flag when dropped, so replacing or dropping a job
cancels it; a cancelled worker sends nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cargo fmt: crates/doc/src/dynblock.rs (fails the fmt gate on main)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Show Thai file names and text in the interface with an installed Thai font
A drawing whose file name is Thai showed boxes in its file tab and in the
window title: the interface loaded one Latin system font (plus a CJK font for
the Chinese interface), and neither has Thai.
install_fonts now also adds an installed Thai font (Thonburi, Leelawadee UI,
Noto Sans Thai, Loma...) after the Latin one, in any interface language, since
file names and drawing text are Thai whatever the interface is in. No font is
bundled; without one installed nothing changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add Korean interface localization and Hangul font support
* Add Arabic (العربية) interface translation
A full ar.tsv catalog for the CAD interface — every menu label, tool,
palette, dialog and status message in the repo's three-column TSV
format, written from the plain meaning of the English with the
Arabic AutoCAD vocabulary its users know (أمر، إزاحة، تدوير، قص،
استدارة، طبقة…), with the six CLDR plural forms for the counts.
Registers ar in LANGUAGES with plural_arabic and the font chain
(Noto Sans Arabic first on Linux, Segoe UI/Tahoma on Windows, Geeza
Pro on macOS) so the UI families paint Arabic.
The shell itself still lays out left-to-right: egui 0.36 has no
global direction switch and no bidi, so mirroring is left for a
later pass; this PR is the catalog, the registry entry and the
fonts.
* i18n: start the Swedish (sv) interface catalog
Header only, not registered yet: the catalog is filled and the language registered in this
branch, translated from the meaning of CADCraft's English strings and reviewed by a native
Swedish speaker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: add Swedish (sv) interface translation
A complete 1,235-entry Swedish catalog: every key of the Spanish catalog, Run Script... and the
four menu headings (Visa, Rita, Måttsättning, Ändra). Written from the meaning of CADCraft's
English strings; no other product's localisation and no other catalog was used. AI-assisted; the
terminology and the running app were reviewed by a native speaker. Command-line keywords, system
variables and osnap tokens stay English.
- Preference::Swedish (sv); sv-SE, sv-FI and sv_SE.UTF-8 select it; one|other plurals (the
English rule).
- sv in REPORTED; tests for locales, saved preference and plurals, menu headings, a live switch,
dialogs and the Swedish letters in the bundled fonts. No gaps are reported for Swedish.
- ATTRIBUTION, README, docs/localization.md, docs/localization-parity.md,
docs/control-protocol.md, the options doc comment and a contributors/people.toml entry for
@holmbom.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Chanthawat Kiriyadee <enwuft@icloud.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: huk082 <89136256+huk082@users.noreply.github.com>
Co-authored-by: hasan-sdaif <306196098+hasan-sdaif@users.noreply.github.com>
Co-authored-by: Erik Holmbom <erik.holmbom@icloud.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Show Thai file names and text in the interface with an installed Thai font
A drawing whose file name is Thai showed boxes in its file tab and in the
window title: the interface loaded one Latin system font (plus a CJK font for
the Chinese interface), and neither has Thai.
install_fonts now also adds an installed Thai font (Thonburi, Leelawadee UI,
Noto Sans Thai, Loma...) after the Latin one, in any interface language, since
file names and drawing text are Thai whatever the interface is in. No font is
bundled; without one installed nothing changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add Korean interface localization and Hangul font support
* i18n: start the Swedish (sv) interface catalog
Header only, not registered yet: the catalog is filled and the language registered in this
branch, translated from the meaning of CADCraft's English strings and reviewed by a native
Swedish speaker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: add Swedish (sv) interface translation
A complete 1,235-entry Swedish catalog: every key of the Spanish catalog, Run Script... and the
four menu headings (Visa, Rita, Måttsättning, Ändra). Written from the meaning of CADCraft's
English strings; no other product's localisation and no other catalog was used. AI-assisted; the
terminology and the running app were reviewed by a native speaker. Command-line keywords, system
variables and osnap tokens stay English.
- Preference::Swedish (sv); sv-SE, sv-FI and sv_SE.UTF-8 select it; one|other plurals (the
English rule).
- sv in REPORTED; tests for locales, saved preference and plurals, menu headings, a live switch,
dialogs and the Swedish letters in the bundled fonts. No gaps are reported for Swedish.
- ATTRIBUTION, README, docs/localization.md, docs/localization-parity.md,
docs/control-protocol.md, the options doc comment and a contributors/people.toml entry for
@holmbom.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Chanthawat Kiriyadee <enwuft@icloud.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: huk082 <89136256+huk082@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Show Thai file names and text in the interface with an installed Thai font
A drawing whose file name is Thai showed boxes in its file tab and in the
window title: the interface loaded one Latin system font (plus a CJK font for
the Chinese interface), and neither has Thai.
install_fonts now also adds an installed Thai font (Thonburi, Leelawadee UI,
Noto Sans Thai, Loma...) after the Latin one, in any interface language, since
file names and drawing text are Thai whatever the interface is in. No font is
bundled; without one installed nothing changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add Korean interface localization and Hangul font support
---------
Co-authored-by: Chanthawat Kiriyadee <enwuft@icloud.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Double-clicking a viewport to enter MSPACE or sheet to enter PSPACE triggers a primary click on the first click that starts an idle selection window (pending_window). When the second click triggers dbl_primary, the handler executed an early return, leaving pending_window open and rendering an unwanted crossing/window rectangle across the screen. Reset pending_window and drag_window on double clicks and suppress primary click dispatch.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Draw object transparency on screen, in exports and in plots
Transparency was read and saved (entity group 440, layer xdata, ByLayer and
ByBlock) but never drawn. Display lists now carry each object's effective
transparency (its own, its layer's, or the block reference's), and:
- the canvas (GPU and CPU paths), ui.render and PNG/SVG exports blend it;
TRANSPARENCYDISPLAY turns it off on screen and is now on by default, as in
AutoCAD (initial value 1);
- plots draw it only when "Plot transparency" is on: a page setup option
(PAGESETUP `plotTransparency`, a checkbox in the Page Setup Manager and the
Plot dialog), overridable per plot, with PLOTTRANSPARENCYOVERRIDE (0 never,
1 the setting, 2 always). PDF gets /ExtGState alpha, PNG plots blend, SVG
uses opacity. Plots without it are byte-identical to before.
The public DXF Reference has no plot layout flag for plot transparency, so
the option is kept in the session and in JSON, not in DXF/DWG.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Transparency fixes: attributes, PDF overlaps, drag previews
- Attributes draw with their own transparency (their definition's, layer 0
meaning the reference's layer, ByBlock the reference's) instead of the
block reference's.
- PDF plots stroke overlapping transparent objects one by one, so they build
up where they cross as in PNG plots; opaque output is unchanged.
- Drag and rubber-band previews follow TRANSPARENCYDISPLAY.
- Effective transparency is worked out only when it is drawn, reusing the
layer the property lookup already found.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Transparency: one PDF stroke per transparent primitive; opaque rebuilt previews
- PDF plots never batch two transparent primitives into one path. Block and
viewport contents share their reference's handle, so the per-object flush
missed them; each primitive now blends on its own, as in PNG plots and on
screen. Opaque output is unchanged.
- Previews the session rebuilds with the current properties (rubber bands,
copies of objects) are drawn opaque again: they carry CLAYER's
transparency, not the objects'. The GPU drag of the objects themselves
keeps following TRANSPARENCYDISPLAY.
- Tests for attributes on a transparent reference layer, attributes without a
definition, and the drag cache across the TRANSPARENCYDISPLAY toggle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Selection like AutoCAD: colour highlight and the Options Selection tab
Selecting or hovering an object outlined each filled primitive (TrueType
glyphs, dimension and leader arrowheads, solid hatches, wide polylines)
by the rectangle around its triangles, and dashed everything else. A
selected dimension's text became a row of dashed boxes, one per glyph,
and its closed arrowheads small rectangles.
Selected objects are now redrawn in the selection colour: lines solid,
fills filled half see-through (so the lines and text on a highlighted
hatch stay visible), and the whole object reads as selected, text and
arrowheads included. A wipeout is always outlined, since filling it would
hide the drawing under it.
The Options dialog's Selection tab is laid out as AutoCAD's, with the
settings CADCraft can act on, each one AutoCAD's variable, kept in the
user profile:
- Selection modes: noun/verb selection (PICKFIRST), Shift to add
(PICKADD), Object grouping (PICKSTYLE bit 1, now saved in the profile).
- Selection effect color (selectionColor, an interface preference; null
is the theme's).
- Grips: Show grips (GRIPS) and the object selection limit for display of
grips (GRIPOBJLIMIT, 100; 0 no limit): grips are neither drawn nor
picked beyond it.
- Selection preview (SELECTIONPREVIEW): the object under the cursor is
highlighted when a command is active (2) and when none is (1).
- Visual Effect Settings: the selection area effect (SELECTIONAREA,
WINDOWAREACOLOR 150, CROSSINGAREACOLOR 100, SELECTIONAREAOPACITY 25)
and the Selection Preview Filter (PREVIEWFILTER 3: 1 objects on locked
layers, 2 xrefs, 4 tables, 8 multiline text, 16 hatches, 32 groups).
As in AutoCAD these are typed, not on the dialog: HIGHLIGHT (0 shows only
the grips of selected objects; not saved, so every session starts
highlighted), SELECTIONEFFECT (1 the selection colour, 0 dashed lines with
fills outlined along their real boundary) and PREVIEWEFFECT (the preview
dashed 0, thicker 1 or both 2).
Left for later, as CADCraft lacks what they control: lasso, grip tips and
menus, group grips, grips within blocks, associative hatch selection,
command and property preview, PICKDRAG, PICKAUTO and PROPOBJLIMIT.
DisplayList::fill_outlines returns the boundary of the region a filled
primitive covers as closed polylines (edges only one triangle has; the
slab filler's horizontal cuts, which need not line up between trapezoids,
are split at every x on their line and kept where an odd number cover
them), falling back to the bounding box over 600,000 vertices. The GPU
and CPU highlight paths and the drawing comparison overlay share the same
looks.
The new labels have Ukrainian rows (the required catalog); other
languages fall back to English.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: EP995LAB <293597958+EP995LAB@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Selecting or hovering an object outlined each filled primitive (TrueType
glyphs, dimension and leader arrowheads, solid hatches, wide polylines)
by the rectangle around its triangles, and dashed everything else. A
selected dimension's text became a row of dashed boxes, one per glyph,
and its closed arrowheads small rectangles.
Selected objects are now redrawn in the selection colour: lines solid,
fills filled half see-through (so the lines and text on a highlighted
hatch stay visible), and the whole object reads as selected, text and
arrowheads included. A wipeout is always outlined, since filling it would
hide the drawing under it.
The Options dialog's Selection tab is laid out as AutoCAD's, with the
settings CADCraft can act on, each one AutoCAD's variable, kept in the
user profile:
- Selection modes: noun/verb selection (PICKFIRST), Shift to add
(PICKADD), Object grouping (PICKSTYLE bit 1, now saved in the profile).
- Selection effect color (selectionColor, an interface preference; null
is the theme's).
- Grips: Show grips (GRIPS) and the object selection limit for display of
grips (GRIPOBJLIMIT, 100; 0 no limit): grips are neither drawn nor
picked beyond it.
- Selection preview (SELECTIONPREVIEW): the object under the cursor is
highlighted when a command is active (2) and when none is (1).
- Visual Effect Settings: the selection area effect (SELECTIONAREA,
WINDOWAREACOLOR 150, CROSSINGAREACOLOR 100, SELECTIONAREAOPACITY 25)
and the Selection Preview Filter (PREVIEWFILTER 3: 1 objects on locked
layers, 2 xrefs, 4 tables, 8 multiline text, 16 hatches, 32 groups).
As in AutoCAD these are typed, not on the dialog: HIGHLIGHT (0 shows only
the grips of selected objects; not saved, so every session starts
highlighted), SELECTIONEFFECT (1 the selection colour, 0 dashed lines with
fills outlined along their real boundary) and PREVIEWEFFECT (the preview
dashed 0, thicker 1 or both 2).
Left for later, as CADCraft lacks what they control: lasso, grip tips and
menus, group grips, grips within blocks, associative hatch selection,
command and property preview, PICKDRAG, PICKAUTO and PROPOBJLIMIT.
DisplayList::fill_outlines returns the boundary of the region a filled
primitive covers as closed polylines (edges only one triangle has; the
slab filler's horizontal cuts, which need not line up between trapezoids,
are split at every x on their line and kept where an odd number cover
them), falling back to the bounding box over 600,000 vertices. The GPU
and CPU highlight paths and the drawing comparison overlay share the same
looks.
The new labels have Ukrainian rows (the required catalog); other
languages fall back to English.
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The MTEXT text entry opens a text box on the canvas at the text's location and
width instead of a dialog: font, height, bold, italic, underline, overline,
colour, paragraph alignment, lists, tab and special characters, plus a ruler for
the paragraph's indents and tab stops. Text, per-character formats and paragraph
properties live in engine::mtext_edit (parse and write MTEXT codes, opaque codes
kept verbatim), tested headlessly.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Block Editor: BEDIT, BSAVE, BSAVEAS and BCLOSE for static blocks
BEDIT opens a block definition in the drawing's own tab with its base point
at the origin, and the block's objects are edited with the ordinary commands.
BSAVE writes them back into the definition, so every reference in the drawing
updates (one undo step in the drawing); BSAVEAS saves under a new name;
BCLOSE goes back to the drawing, asking whether to save unsaved changes.
- The drawing waits untouched while the editor is open (blockedit.rs): its
undo history, selection and views come back on BCLOSE. Objects left
unchanged are saved back exactly, so no coordinate drifts.
- Files save the drawing outside the editor; autosave keeps the editor's
unsaved changes in the block; the close/quit prompt's Save puts them into
the block first.
- Right-click a selected block reference: Block Editor. In the editor the
canvas is tinted, the base point is marked, and a bar offers Save Block,
Save Block As and Close Block Editor (also in the right-click menu). The
Block tool set's Block Editor button is now live. BLOCKEDITOR sysvar.
- Layout and paper-space commands are refused while the editor is open; a
block can't be saved to contain a reference to itself.
- Dynamic blocks: their data is kept; the editor says it can't edit their
parameters yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Edit Block Definition dialog; BEDIT can start a new block
BEDIT typed or started from a menu or the Tool Sets with no block reference
selected opens the Edit Block Definition dialog: the drawing's blocks sorted
by name, a preview and the description. OK opens the Block Editor on the
block named; a name no block has yet starts a new block, which BSAVE creates
(`bedit {name, create: true}`). A selected block reference still opens at
once, and JSON calls never open the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Edit Block Definition: centred window, list box; gaps.md F3
The dialog opens centred on the window, the blocks are a full-width list
in a list box of fixed height, and gaps.md F3 mentions the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: find dynamic block data on the block's BLOCK_RECORD
A dynamic block's ACAD_ENHANCEDBLOCK dictionary hangs off its BLOCK_RECORD
table entry, not the BLOCK entity, so the "parameters are kept" note never
showed for AutoCAD files. Regression test with the data laid out as an
AutoCAD DXF has it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: a dynamic block reference opens its dynamic block
A dynamic block reference with values of its own shows an anonymous block
(`*U12`), so the right-click Block Editor (and BEDIT on a picked or selected
reference) refused it and asked for a name. The anonymous block's record
names its dynamic block in AcDbBlockRepBTag xdata; BEDIT now opens that, as
AutoCAD does. Regression test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Block Editor on the current drawing; opening a drawing with authoring elements offers it
A dynamic block's own drawing (model space with authoring elements: its
block record's ACAD_ENHANCEDBLOCK) opened from the UI asks, as AutoCAD does,
"<file> contains authoring elements. Open in Block Editor?" Yes / No /
Cancel. Yes opens the Block Editor on <Current Drawing>: the drawing's own
objects, edited where they are; BSAVE keeps them, BCLOSE without saving puts
the drawing back. <Current Drawing> heads the Edit Block Definition list.
BSAVEAS is not available there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Block Editor: BEDIT, BSAVE, BSAVEAS and BCLOSE for static blocks
BEDIT opens a block definition in the drawing's own tab with its base point
at the origin, and the block's objects are edited with the ordinary commands.
BSAVE writes them back into the definition, so every reference in the drawing
updates (one undo step in the drawing); BSAVEAS saves under a new name;
BCLOSE goes back to the drawing, asking whether to save unsaved changes.
- The drawing waits untouched while the editor is open (blockedit.rs): its
undo history, selection and views come back on BCLOSE. Objects left
unchanged are saved back exactly, so no coordinate drifts.
- Files save the drawing outside the editor; autosave keeps the editor's
unsaved changes in the block; the close/quit prompt's Save puts them into
the block first.
- Right-click a selected block reference: Block Editor. In the editor the
canvas is tinted, the base point is marked, and a bar offers Save Block,
Save Block As and Close Block Editor (also in the right-click menu). The
Block tool set's Block Editor button is now live. BLOCKEDITOR sysvar.
- Layout and paper-space commands are refused while the editor is open; a
block can't be saved to contain a reference to itself.
- Dynamic blocks: their data is kept; the editor says it can't edit their
parameters yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Edit Block Definition dialog; BEDIT can start a new block
BEDIT typed or started from a menu or the Tool Sets with no block reference
selected opens the Edit Block Definition dialog: the drawing's blocks sorted
by name, a preview and the description. OK opens the Block Editor on the
block named; a name no block has yet starts a new block, which BSAVE creates
(`bedit {name, create: true}`). A selected block reference still opens at
once, and JSON calls never open the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Edit Block Definition: centred window, list box; gaps.md F3
The dialog opens centred on the window, the blocks are a full-width list
in a list box of fixed height, and gaps.md F3 mentions the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: find dynamic block data on the block's BLOCK_RECORD
A dynamic block's ACAD_ENHANCEDBLOCK dictionary hangs off its BLOCK_RECORD
table entry, not the BLOCK entity, so the "parameters are kept" note never
showed for AutoCAD files. Regression test with the data laid out as an
AutoCAD DXF has it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: a dynamic block reference opens its dynamic block
A dynamic block reference with values of its own shows an anonymous block
(`*U12`), so the right-click Block Editor (and BEDIT on a picked or selected
reference) refused it and asked for a name. The anonymous block's record
names its dynamic block in AcDbBlockRepBTag xdata; BEDIT now opens that, as
AutoCAD does. Regression test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Block Editor: BEDIT, BSAVE, BSAVEAS and BCLOSE for static blocks
BEDIT opens a block definition in the drawing's own tab with its base point
at the origin, and the block's objects are edited with the ordinary commands.
BSAVE writes them back into the definition, so every reference in the drawing
updates (one undo step in the drawing); BSAVEAS saves under a new name;
BCLOSE goes back to the drawing, asking whether to save unsaved changes.
- The drawing waits untouched while the editor is open (blockedit.rs): its
undo history, selection and views come back on BCLOSE. Objects left
unchanged are saved back exactly, so no coordinate drifts.
- Files save the drawing outside the editor; autosave keeps the editor's
unsaved changes in the block; the close/quit prompt's Save puts them into
the block first.
- Right-click a selected block reference: Block Editor. In the editor the
canvas is tinted, the base point is marked, and a bar offers Save Block,
Save Block As and Close Block Editor (also in the right-click menu). The
Block tool set's Block Editor button is now live. BLOCKEDITOR sysvar.
- Layout and paper-space commands are refused while the editor is open; a
block can't be saved to contain a reference to itself.
- Dynamic blocks: their data is kept; the editor says it can't edit their
parameters yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: find dynamic block data on the block's BLOCK_RECORD
A dynamic block's ACAD_ENHANCEDBLOCK dictionary hangs off its BLOCK_RECORD
table entry, not the BLOCK entity, so the "parameters are kept" note never
showed for AutoCAD files. Regression test with the data laid out as an
AutoCAD DXF has it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* BEDIT: a dynamic block reference opens its dynamic block
A dynamic block reference with values of its own shows an anonymous block
(`*U12`), so the right-click Block Editor (and BEDIT on a picked or selected
reference) refused it and asked for a name. The anonymous block's record
names its dynamic block in AcDbBlockRepBTag xdata; BEDIT now opens that, as
AutoCAD does. Regression test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Multiline attributes: read, draw and save their text
A multiline attribute (DXF attribute type 2, or 4 for a definition) has its
text as embedded MTEXT after its own groups (`101 Embedded Object`); its own
group 1 is empty. CADCraft read only the own groups, so the attribute drew
nothing, and a save wrote it back empty: its text was lost.
- `Attrib::multiline` keeps the multiline text; `text.value` holds its plain
text, which ATTEDIT and the other value editors change; an edited value
replaces the contents (`Attrib::multiline_text`).
- DXF read: ATTRIB and ATTDEF split at the marker; the MTEXT parsing is
shared with MTEXT entities (`mtext_from`).
- Drawn as multiline text; ZOOM Extents counts it.
- DXF write (2007 and later; earlier versions get one line): attribute type,
alignment point and the embedded MTEXT, only what differs from unrotated
text, as AutoCAD writes it.
- INSERT and ATTSYNC give references the definition's multiline text placed
with them; MOVE/ROTATE/SCALE, Properties rotation and scale, annotative
scaling and FLATTEN carry it.
- Tests: synthetic multiline ATTDEF and ATTRIB (read, drawn, saved, edited,
pre-2007 save, damaged embedded groups); engine INSERT, MOVE, ATTEDIT and
ATTSYNC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Multiline attributes: read MTEXT direction from its own groups (#667, as #834 does)
#834 moves these lines' fix into the MTEXT reader; the same fix in the shared
mtext_from keeps the two compatible.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Attributes keep Verify, Preset and Lock position
ATTDEF/ATTRIB flags 4 (verify) and 8 (preset) and Lock position (group 280
after the tag, DXF 2007 and later) were dropped on save. Without Lock
position AutoCAD lets an attribute be dragged out of its reference, and its
dynamic block actions no longer carry it. A reference's attributes take Lock
position from their definitions, as AutoCAD saves them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Cody Vogt <18035288+codyvogt@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>