Commit Graph

10 Commits

Author SHA1 Message Date
aj e493d83899 feat(io): add Gravograph .CHR font reader with text-to-geometry
Add ChrFont, a reader for Gravograph .CHR engraving fonts, plus UI to
convert placed text into engraved geometry in the CAD converter.

The .CHR files are obfuscated with a single-byte XOR. Different
GravoStyle releases use different keys (0x2F in older versions, 0xCF in
the 7000 series, and others across the font library), so the key is
auto-detected from byte 1 of the file: the font name is ASCII stored as
UTF-16LE, so the high byte of its first character is 0x00 in plaintext
and the raw byte equals the key. This reads every font in a GravoStyle
install regardless of version, not just one hardcoded key.

UI: right-clicking a text item in EntityView raises TextConvertRequested;
CadConverterForm renders it via ChrFont with H/V alignment and adds the
result on an ENGRAVE layer.

Tests use Xunit.SkippableFact and a gitignored test-config.json so the
suite points at a local .CHR file without committing proprietary assets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 14:37:48 -04:00
aj e63be93051 fix: emit G52 bracket for hole sub-program calls
CincinnatiSheetWriter.WriteHoleSubprogramCall emitted
`M98 P<num> X<x> Y<y>`, but per manual §3.98 ("M98 SUB-PROGRAM CALL
WITH NO ARGUMENTS") M98 takes only P and L — the X/Y had no defined
meaning to the control. The intent was to position the sub-program at
the hole center, which is what G52 is for per §1.52 ("local work
coordinate system") and which explicitly does not move the nozzle.

Emit the documented G52 bracket instead:
  G52 X<hole.x> Y<hole.y>
  M98 P<holeSubNum>
  G52 X0 Y0

The hole sub-program is authored in hole-local coordinates, so its
first rapid (the lead-in to the pierce point) resolves to the absolute
pierce under the G52 shift and moves the tool directly there from the
previous feature's end — no phantom rapid to the hole center.

Also add docs/cincinnati-post-output.md as the reference for the full
post output format, with every emitted G/M code cross-referenced to
the Cincinnati programming manual. Un-ignore docs/ (docs/superpowers/
stays ignored) and track the PDF manual alongside the reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:21:15 -04:00
aj 3a0267c041 chore: add docs/ to gitignore and remove tracked superpowers docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:01:20 -04:00
aj 61b917c398 chore: remove docs/superpowers and add to gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:48:59 -04:00
aj 4060430757 chore: remove stale superpowers docs and update gitignore
Remove implemented plan/spec docs from docs/superpowers/ (recoverable
from git history). Add .superpowers/ and launchSettings.json to gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:13:01 -04:00
aj bf104309b4 chore: ignore SQLite database files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 13:15:00 -04:00
aj c68139e15e merge: resolve .gitignore conflict, keep both entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 07:22:45 -04:00
aj 0c395421cd chore: add .claude/ to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:02:54 -04:00
aj 9f84357c34 chore: add .worktrees/ to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:48:08 -04:00
aj f2595d7cba First commit. 2016-05-16 22:09:19 -04:00