Commit Graph
4032 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 5.5 0c1676e612 fix(underlay): bound how far DWF packages and DGN streams inflate
The DWF package reader, the DGN stream inflater and the new DGN
ExtendedColors scan each read a zlib/zip payload to its end, so a
crafted or corrupt file could inflate until memory ran out. Cap them:
1 GiB for a whole DWF package, 512 MiB per DGN stream, 4 MiB per
ExtendedColors record candidate - far above real files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:17:38 +03:00
Hakan Seven d9899be35e Merge pull request #1514 from ramox81/codex/dwf-dgn-underlays
Attach Underlay ribbon menu, DWF/DGN attach dialog, DGN true colours
2026-09-28 17:17:17 +03:00
ramox81andClaude Opus 5.5 5b6cbff5b2 Attach Underlay ribbon menu, DWF/DGN attach dialog, DGN true colours
- Insert > Reference: the PDF Attach button becomes an Attach Underlay menu
  (PDF / DWF / DGN); its face runs the last one chosen.
- DWFATTACH, DGNATTACH and ATTACH on a .dwf/.dwfx/.dgn open the Attach
  dialog for that kind: sheets or models with thumbnails (one chosen),
  placement, path type, file details with the sheet / model size, and for
  DGN the conversion units (sub units offer 1 / sub units per master as the
  scale).
- DGN V8 true colours come from the ExtendedColors record packed in the
  non-model attributes stream; the colour word's high part numbers them.
- A DGN model's extent includes each text's box (its length along the
  baseline and 1.5 x its height), as the reference sizes a model.
- DWFx text uses the family named in its embedded (deobfuscated) font.
- DWF contrast pivots at 0.73 once colours are turned over for a dark
  background.
- Hairline strokes are drawn solid one pixel wide, and underlay rasters are
  made at or below their size on screen so those lines stay unbroken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:08:06 +03:00
Hakan SevenandClaude Opus 5.5 267ba1ed48 chore(start): remove the CAD Editor mobile app promotion
Drops the Google Play banner and its image from the Start page sponsors; the OpenAEC sponsor stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:07:10 +03:00
Hakan SevenandClaude Opus 5.5 e26e0352b7 fix(underlay): malformed DWF and DGN files no longer crash or hang the reader
- W2D: a stream cut off right after an extended opcode's '(' sliced its
  body backwards and panicked.
- DGN V8: the compound-file header was indexed before its length was
  known (a short file with the signature panicked), the sector shift was
  taken on trust (0 or 1 underflowed `sector / 4 - 1` into an endless
  loop), and the DIFAT chain count was unbounded. The header must now be
  complete, the shift 9 or 12, and the chain no longer than the file.

Found fuzzing the #1514 readers with truncated and random input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:06:14 +03:00
Hakan Seven e7aee3baa9 Merge pull request #1514 from ramox81/codex/dwf-dgn-underlays
DWF and DGN underlays: attach, display, snaps and references
2026-09-28 16:59:57 +03:00
ramox81 fecbcd8138 Merge remote-tracking branch 'origin/main' into codex/dwf-dgn-underlays
# Conflicts:
#	Cargo.lock
2026-09-28 16:13:14 +03:00
ramox81andClaude Opus 5.5 56ecf786f1 DWF/DGN underlays: clipping, layers, text, 3D DGN, colours and zoom extents
- PDFOSNAP, DWFOSNAP and DGNOSNAP are separate; UOSNAP sets them all and
  reads 2 while they differ. Enable Snap switches the selected kind's.
- DWFCLIP / DGNCLIP clip their own kind with the kind's prompts and message;
  CLIP routes DWF and DGN underlays there; Enter at a corner asks again.
- The right-edge underlay tools show for DWF and DGN too (import is PDF
  only).
- Underlay layers: DGN levels (V8 level table, "Default" listed as "0"; V7
  used levels named from the level name table), hidden through the layer
  override data with the DGN placeholder string first; a plotted DWF has
  none.
- V8 colour read from its colour word (by level, index, or a true colour
  drawn as its nearest index); 3D V8 elements drawn in plan (lines, line
  strings, ellipses and arcs by their orientation, text); a model's extent
  includes its text.
- DWF 6 TrueType text (font, height, rotation from the font opcode) and DWFx
  glyph runs are drawn; the default W2D colour map is the measured one.
- Contrast pulls lightness towards a per-kind pivot as measured (PDF 0.5,
  DWF 0.243, DGN 0.65).
- Zoom extents includes raster images and underlays whose frames are hidden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:10:01 +03:00
Hakan SevenandClaude Opus 5.5 63230e6a4e test(pdf-export): build ImageModel with use_alpha
#1513 added the field; this integration test's struct literal was not updated, so the test target no longer compiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:14:34 +03:00
Hakan SevenandClaude Opus 5.5 eac19348d5 refactor(draw): TRIM geometry helpers come from the kernel; drop a probe test
#1511 added an orthogonal ellipse projection and a nearest-end
arc_parameter to draw/modify/geom.rs, the latter shadowing the kernel
function of the same name. Both now live in opencadkernel 237827e and
are re-exported here, so every kernel caller gets them too.

test_coincident_line_and_arc_grip_move only printed values and asserted
nothing; removed.

Pins opencadkernel 237827e, opencadgraph fe36957.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:08:36 +03:00
Hakan Seven 66ac8c4ec0 Merge pull request #1511 from yztink/feat/fluid-tangent-arc
feat(draw): add fluid tangent arc, circle, and line construction and snap trim cuts to boundary contacts
2026-09-28 14:02:11 +03:00
Hakan Seven 7694c506aa Merge pull request #1512 from ramox81/codex/frame-parity
Frames: follow the drawing state, DWF/DGN frames, image frame profile, frame-only picking

The codec [patch] to ramox81/cadcodec@ea5edaa is dropped: that commit landed as opencadcodec#63 and main already pins ad16215, which contains it.
2026-09-28 13:52:06 +03:00
ramox81andClaude Opus 5.5 1cbe89ef62 Underlays are rasterised for the view's scale; DGN V7 strokes one pixel wide
A page shown small was drawn from its full-size raster and thin lines broke
up into dots. Once a zoom settles on another quarter-octave step, PDF, DWF
and DGN underlays are rasterised again near their size on screen (never
above the full-size raster), frames are requested until that happens, and
the adjusted-pixel memo is kept per raster size. V7 element weights no longer
widen strokes, matching V8 models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:49:33 +03:00
Hakan Seven 6c481c92fe Merge pull request #1513 from ramox81/codex/image-transparency
Raster images: draw opaque when transparency is off; TRANSPARENCY command
2026-09-28 13:48:51 +03:00
Hakan SevenandClaude Opus 5.5 2e47e1fa95 chore: pin opencadcodec ad16215, opencadkernel 1e02630
Brings in the DWFFRAME/DGNFRAME header variables (codec #63) and robust 2D tangency plus ellipse-circle intersection (kernel #68). Pins opencadcodec ad16215, opencadkernel 1e02630, opencadgraph 7ef5ae4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:45:11 +03:00
ramox81andClaude Opus 5.5 5de0ce069f Image shader: fully transparent pixels are discarded
A transparent pixel wrote depth, hiding lines and objects under the image
that were drawn after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:17:31 +03:00
ramox81andClaude Opus 5.5 e9e05d89f3 Locale keys of the TRANSPARENCY prompts next to the other image strings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:58:24 +03:00
ramox81andClaude Opus 5.5 cb7860e50e DWF and DGN underlays: attach, display, snaps, frames and references
DWFATTACH / -DWFATTACH and DGNATTACH / -DGNATTACH attach a DWF / DWFx sheet
or a DGN (V7 or V8) model with the reference's prompts; ATTACH routes the
file types to them. The sheet or model is read into vector paths, drawn as a
transparent underlay raster (contrast, fade, monochrome and background
adjustment apply) and offers its geometry to object snaps. Definitions are
kept in ACAD_DWFDEFINITIONS / ACAD_DGNDEFINITIONS, the External References
palette lists and reloads them, and image textures get line-keeping mip
levels so thin underlay lines stay visible when zoomed out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:53:25 +03:00
Hakan SevenandClaude Opus 5.5 d40e6c8d1d chore(text): English-only comments for the hint-reliant font path
#1506 paired each comment with a Chinese line; the codebase comments in English. Code and test data are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:58:38 +03:00
yztink c827b87cf9 fix(trim): snap trim cut parameters to exact boundary contact points 2026-09-28 01:56:47 -07:00
Hakan Seven ee2a12f778 Merge pull request #1506 from Chrisyeh1983/fix/kaiu-hinting
fix(text): run the TrueType interpreter for hint-reliant fonts (DFKai-SB / MingLiU)
2026-09-28 11:56:45 +03:00
yztink 92fa661065 feat(draw): add fluid tangent arc, circle, and line construction with ellipse support 2026-09-28 01:56:03 -07:00
ramox81andClaude Opus 5.5 5ca7becd97 Raster images: transparency off draws pixels opaque; TRANSPARENCY command
An image's transparency flag decides whether transparent pixels show what
is behind the image or draw in their stored colour: the image pass and PDF
plots now follow it (it was ignored, so every PNG alpha showed through).
TRANSPARENCY selects images and asks for the mode, defaulting to the first
image's current one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:23:19 +03:00
ramox81andClaude Opus 5.5 7f8f8457c7 Frames: state-following ribbon list, DWF/DGN frames, image frame encoding and profile, frame-only picking
- The Frames list shows the drawing's frame state (hide / display and plot /
  display but not plot / frames vary), follows commands, undo and document
  switches, and lists the mixed state as a disabled item.
- DWFFRAME and DGNFRAME are frame variables of their own, kept in the header,
  and FRAME sets them with the others.
- Out-of-range frame values say "Requires an integer between 0 and 2." and
  ask again; a set value reports "Regenerating model.".
- IMAGEFRAME is stored in the image variables as bits (2 is written as 3) and
  a drawing without them uses the profile value, which setting IMAGEFRAME
  updates and the settings file keeps.
- Raster images, PDF underlays and wipeouts are picked on their frame only;
  underlay snap geometry is never picked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:53:53 +03:00
Hakan SevenandClaude Opus 5.5 8c9b485b6c refactor(io): R13/R14 plot flags come from the codec now
opencadcodec a35f43e reads R13/R14 LAYER records as plottable, the root
cause #1507 worked around on load; drop the host-side correction. Its
tests stay and now cover the codec fix end to end. They wrote one temp
file per version and ran in parallel, so each test now gets its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:16:19 +03:00
Hakan Seven 8834d77d12 Merge pull request #1507 from YsDirector/fix/r14-layer-plot-flags
fix(io): R13/R14 layers come back plottable so plots are not blank
2026-09-28 10:13:10 +03:00
Hakan SevenandClaude Opus 5.5 df2778f466 chore: pin opencadcodec a35f43e (R13/R14 layers plottable)
Brings in bounded object storage on DWG import (#62) and R13/R14 LAYER
records reading as plottable. Pins opencadcodec a35f43e, opencadkernel
ee41029, opencadgraph 8b8c7f3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:04 +03:00
Karim Jerbi 801882314f perf(explode): batch erasure, section map, pre-sized vectors
EXPLODE apply 504ms -> 61ms (-88%), geometry 70.2ms -> 58.1ms (-17%) on the 2,500-compound fixture.
2026-09-28 06:58:47 +01:00
Karim Jerbi 2fc7d15a36 test(explode): add golden, invariant, and differential regression tests
Locks explode behavior ahead of optimization: per-arm goldens, length/closed invariants, plan ordering, and legacy-vs-batch differential.
2026-09-28 06:58:47 +01:00
Karim Jerbi 7978d1eb2e bench: add COMMANDS suite with EXPLODE metrics
Shares the benchmark harness between both suites, extracts the plan/batch/apply helpers out of the EXPLODE command arm, and adds the command_benchmarks target.
2026-09-28 06:58:47 +01:00
github-actions[bot] c623a01695 Release v2026.39 v2026.39 2026-09-27 16:42:38 +00:00
ysdirector 29a252de81 fix(io): R13/R14 layers come back plottable so plots are not blank
The LAYER record only grew a plot flag in R2000: R13/R14 carry frozen,
off, frozen-in-new-viewport and locked as four separate bits and nothing
else, so the reader has no bit to read and leaves `is_plottable` at the
`false` it starts from. Every layer of such a drawing then read as "don't
plot", the plot pass dropped every wire, and PLOT, the preview and
QUICKPRINT all rendered a blank sheet while the drawing still looked right
on screen — display and plot visibility are separate flags, so nothing
about the drawing itself looked wrong.

Restore what the format means by default — a layer plots unless a file
says otherwise — for the two versions that carry the four-bit record, on
both load entry points (bytes and path). R2000 and later keep the flag the
file stores, so a genuinely unplottable layer (DEFPOINTS) stays unplottable.

Tests: an R14 DWG written and read back keeps every layer plottable, the
path-based entry point does the same for R13, a modern file keeps the flag
it stored, and an R14 drawing tessellating to wires that are all
plot_visible locks the whole chain that used to blank the page.
2026-09-28 00:36:24 +08:00
Chris YehandClaude Opus 5.5 5a36ecda74 fix(text): hint TrueType fonts that need the interpreter (DFKai-SB, MingLiU) before outlining
DFKai-SB (kaiu.ttf), MingLiU and other early DynaLab fonts assemble each
ideograph from stroke components that only the TrueType instructions move
into place. ttf-parser's `outline_glyph` returns the raw, unhinted `glyf`
outline, so these fonts rendered with missing or displaced strokes
('自' drawn as '目'; 範, 直, 啟, 動 broken). FreeType calls them "tricky"
and always runs the interpreter for them.

Every non-test `outline_glyph` call site in ttf_glyph.rs (`glyph`,
`outline_char` - shared by both native fallback paths -, the web
`build_fallback`, and both `build_shaped` variants) now goes through
`outline_glyph_into`; `outline_char` takes the font data and face index
for that. When skrifa's `require_interpreter()` says the face
is hint-reliant, the glyph is hinted with the TrueType interpreter
(Target::Mono) at 512 ppem and scaled back to font units (x upem / 512);
every other font keeps the exact ttf-parser outline. The decision and the
HintingInstance are cached once per face, keyed by (byte length, face
index, head.checkSumAdjustment) because fontdb may hand out a new buffer
per call. The hinted path is recorded first and replayed only on success,
so a failed draw falls back to ttf-parser without a half-drawn glyph.

skrifa 0.42.1 is already in the lockfile (via hayro / glifo).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 21:44:52 +08:00
Hakan Seven 78c9128a69 Merge pull request #1505 from ThaiLe-gt/bugfix/fix-dimension-arrow-export
fix(io): normalize missing dimension arrow block references on save
2026-09-27 13:07:47 +03:00
Hakan SevenandClaude Opus 5.5 b7498b176c chore: pin opencadcodec 42b44d2 (DXF saves polar stretch actions)
Pins opencadcodec 42b44d2, opencadkernel 4e67cd7, opencadgraph d89a9c5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 13:04:21 +03:00
thaile-gt a5468bb8f7 fix(io): normalize missing dimension arrow block references on save 2026-09-27 11:14:36 +07:00
Hakan SevenandClaude Opus 5.5 315df5cd47 chore: pin opencadcodec 4f7bd51 (merlinnot codec fixes #56-#61)
Brings in: unchanged ACSH extrusion history and DIMASSOC records kept
byte for byte; native dynamic-action field layouts corrected; evaluation
graph expressions written as owned; evaluated block metadata copy;
source class numbers kept on same-version legacy saves; explicit block
attribute flags kept.

The dynamic-action model now names its fields after their native
meaning, so the object summaries read parameter ids, the move offsets'
distance multiplier and the lookup table's columns. The empty
PropertiesTable variant is gone; such tables stay opaque objects.

Pins opencadcodec 4f7bd51, opencadkernel 8186605, opencadgraph 048c9c5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 07:11:40 +03:00
Hakan SevenandClaude Opus 5.5 1f1fba31b2 refactor(commands): plugin dispatch ends through finish_dispatch
The branch added by #1498 repeated finish_dispatch's focus and dynamic-input sync; call it instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 06:47:21 +03:00
Hakan Seven 15ab97c9e2 Merge pull request #1498 from yztink/fix/repeat-plugin-commands
fix(commands): record last_cmd on plugin dispatch to repeat on Enter
2026-09-27 06:46:14 +03:00
Hakan SevenandClaude Opus 5.5 25229f70d7 docs(readme): install on Linux as a Flatpak from FlatPark (#1487)
FlatPark installs the official AppImage through Flatpak extra-data and
follows new releases. The Flatpak works through the file chooser, so
external references and underlays need the home filesystem override.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 06:43:43 +03:00
yztink 43a16af060 test(commands): remove test relying on external opencad-py-runner plugin 2026-09-26 10:09:04 -07:00
yztink 7c0af700e8 fix(commands): record last_cmd on plugin dispatch to repeat on Enter
When a plugin command was dispatched, record_recent was called but
tabs[i].last_cmd was never set. Consequently, pressing Enter or Space on
an empty command line after running a plugin command failed to repeat it.

This records tabs[i].last_cmd on plugin dispatch and requests command-line
focus and dynamic input syncing when an interactive plugin command starts.
2026-09-25 23:51:19 -07:00
Hakan Seven 460a4c9cc5 Merge pull request #1491 from ramox81/codex/insert-attach-buttons
Insert Reference panel: separate Attach XREF and Attach PDF buttons
2026-09-25 22:27:32 +03:00
Hakan SevenandClaude Opus 5.5 83e1ebd44a fix(dimension): lay automatic text out from the style again (#1412)
Since the stored text point became authoritative (85619f49), new linear
and aligned dimensions drew their text at the placeholder the commands
stored (the middle of the dimension line), so DIMTAD Above/Below and the
text offset had no effect; a style or override edit left the stale point
in place too.

reset_automatic_text_position clears the point of text the user did not
place, so it is laid out from the current settings. DIMLINEAR, DIMALIGNED,
DIMBASELINE, DIMCONTINUE and QDIM call it on creation; a DIMSTYLE edit, a
dimension override row and a style change call it for the dimensions they
touch. Loaded, untouched dimensions keep their pictured position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 22:20:16 +03:00
Hakan SevenandClaude Opus 5.5 eb84bae779 fix(3d): seat axis steps on 3D snaps; raised bases follow the cursor (#1030)
Height and distance steps (PUSHPULL, CYLINDER, CONE, PYRAMID, BOX,
EXTRUDE) replaced the point with the cursor's screen mapping onto the
command axis, discarding an acquired 3D object snap. A genuine snap now
supplies its own coordinate along the axis, as axis grips already do.

Base steps after the first base point (BOX/WEDGE opposite corner and cube
size, CYLINDER/CONE/PYRAMID radius) read the cursor on the base plane
through that point. A base started on a raised face intersected the ray
with world XY instead, so in oblique views the footprint ran far past the
mouse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:46:47 +03:00
Hakan SevenandClaude Opus 5.5 89512c2f20 fix(text): no stroke-font tracking after big-font and fallback glyphs (#1470)
Every glyph advanced by the face's letter spacing, including CJK glyphs a
style's big font or the TrueType fallback supplies. Their advances already
carry the gap (big font) or side bearings (TrueType), so with an LFF primary
such as iso each ideograph took 1.33 heights instead of one.
Face::spacing_after(ch) gives the tracking only to glyphs the stroke font
draws itself; every layout path uses it.

The 1.8-height widths in the report were the TEXT bounds estimate counting
UTF-8 bytes; opencadcodec 1109d52 counts characters.

Pins opencadcodec 1109d52, opencadkernel 8a246b0, opencadgraph 3c4af1c.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:27:17 +03:00
Hakan SevenandClaude Opus 5.5 fdc01e13c8 fix(render): show Inventor drawing views, each in its own viewport (#1285)
Inventor DWG exports place every sheet block with AcIdBlockReference,
which the codec skipped, so these drawings opened blank. opencadcodec
7c20aa7 decodes it as an INSERT and keeps the viewport each model-space
view reference is bound to.

Those view blocks overlap in model space, so a content viewport now also
hides model-space references bound to a different viewport. The handles
join the viewport's frozen-layer set (entity and layer handles never
collide), which the wire and render-graph visibility checks and every
per-viewport cache key already use.

Pins opencadcodec 7c20aa7, opencadkernel d71a828, opencadgraph 1543a5a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:48:36 +03:00
Hakan SevenandClaude Opus 5.5 5fcf741c51 fix(pdf-dialogs): SVG ticks and page arrows instead of glyphs
Review of #1489: the chips and the chosen page tiles drew a check mark and
the import preview's previous / next buttons single guillemets as text.
The web build's bundled font has no check-mark glyph, so it showed as an
empty box; UI icons are SVG. The ticks use the CHECK icon in the chip's or
tile's accent colour and the page buttons the shared arrow icons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:20:03 +03:00
Hakan Seven 2801ac2007 Merge pull request #1489 from ramox81/codex/pdf-dialog-redesign
PDF dialogs: own look with cards, segmented choices and chips
2026-09-25 15:19:07 +03:00
Hakan Seven 82fe204a70 Merge pull request #1486 from ramox81/codex/xref-context-tab
Selection tools on the right-edge toolbar for PDF underlays and xrefs
2026-09-25 15:18:33 +03:00