DRAW v1.8.0
DRAW v1.8.0
UNDO IS FIXED!
Released 2026-08-09
New Features
- APPLE ][ font family — 20 new Color Bitmap Fonts. 40- and 80-column, in colour plus white/amber/green phosphors, across three tiers: native (
7x8/3x8),-SCAN(alternate glyph rows dimmed), and-CRT(true scanlines,14x16/7x16). Colour is a reproduction of the NTSC composite artifact — dots clock at 7.16 MHz against a 3.58 MHz subcarrier, so a dot's column parity is its phase. Glyph shapes come from the verified character generator, not from a screenshot; only the colour was measured from one. Brings the bundled CBF library to 44 fonts. - Groups tell you they can't be drawn on. A group holds no pixels of its own, so drawing tools did nothing on one — silently. Now: a pencil-with-a-slash badge on the group row (hover for the reason), and a "denied" cursor over the canvas. Tools with distinctive art (fill bucket, dropper, spray) keep their cursor and gain a small X badge at a theme-configurable offset; tools without (brush, the shape tools) show a large X. Tools that remain legal on a group — move, picker, zoom, pan, marquee — are untouched.
- Two new options in Settings → Panels → Layer Panel: Warn Drawing on Group (default on) explains the refusal; Auto-Add Layer to Group instead creates a blank layer at the top of that group and lands the same stroke on it.
Improvements
- CBF loader now maps glyphs up to code 255 (was 126), so sheets with more than 94 glyphs expose their full set — including MouseText. Several bundled fonts gain previously unreachable glyphs at codes 127–128.
- Font dropdown sizes itself to its content instead of truncating.
- CI compiles every pull request and every push to
main. Previously it only ran on av*tag, so a PR touching QB64 source could go green without ever being built.
Bug Fixes
- Undo did nothing at all.
HISTORY_inithad been appended to the end of a comment line, so it never ran;HISTORY.maxRecords%stayed0and the capacity guard rejected the very first record. Undo was completely dead in 1.7.0. - Undo silently stopped recording after 1024 operations — only one of two capacity paths evicted.
- 21 sites used
AND/ORas guards. Neither short-circuits in QB64, soIF idx >= 1 AND arr(idx).fieldstill subscripts the array with0and raises ERR 9 — and becauseFatalErrordoesRESUME NEXT, the branch could then run anyway with the bad index. The most reachable fired on everyCtrl+Aoutside a text layer; two more sat in the render path. ENTERsubmitted the AI dialog even after the text area consumed the key.NOTis bitwise —NOT 1is-2, still truthy — andTI_process_key%returns a widget ID, soIF NOT tiAte%always passed.- AI prompt text rendered 50% too wide. The multiline field forced Tiny5 to load as MONOSPACE, giving a 6px cell against ~4px of natural advance.
- Runtime error 9 when moving a layer. Four sites indexed
HISTORY_RECORDS(HISTORY.current%)unconditionally, which is a subscript error when a record was declined andcurrent%is0. Worse, when declined while history was non-empty,current%pointed at an older unrelated record that was then silently corrupted with this operation's move delta. - Crash when saving to a protected directory, drive or mount.
- Save failures silently marked the document clean — a failed write looked like a successful one.
- Linux crash reports collected no system info at all.
DRAW-sysinfo.shwas written with CRLF line endings; dash does not treat a bare CR as whitespace, soexec > "..." 2>&1parsed as fd1<CR>and the script aborted on line 3. - Settings dialog stayed on screen after Cancel or Escape until some other input arrived. The repaint (
SCENE_DIRTY%/FRAME_IDLE%) lived only on the OK path, so cancelling left the main loop idle with the dialog's pixels still on the GUI layer. Escape was always closing it — you just couldn't see it. - Palette chip cache not invalidated on two of four list rebuilds.
- AI layer pool never released deleted layers.
- Layer duplication dropped AI metadata.
- Apron geometry was lost across undo.
- Counts and indices read from
.drawfiles were unvalidated. - CBF glyphs above code 126 were silently dead in any sheet with more than 94 glyphs.
- CRT scanlines were too heavy — the dimmed row of each pair crushed the glyph. Raised from 35% to 78% brightness: striping without banding.
- The font dropdown showed duplicate-looking entries — they were truncation collisions, not duplicates.
- 80-column APPLE ][ was taller than 40-column, which is backwards. Both modes are 24 rows of 8 scanlines on real hardware; 80-column makes characters narrower, not taller. Corrected from
7x16to3x8(plain) — only the dot clock differs. - Three compiler warnings.
candidate$inCRASH.BMwas used only inside$IF WIN, so it was unused on every non-Windows build;destHandle&inPREVIEW.BM(x2) were parameters kept "for signature compatibility" that every caller passed0to. The build is now warning-free.
Internal / QA
- The QA harness was measuring the wrong pixels.
DECORATION_Hinferred the title bar from_NET_FRAME_EXTENTSastop − 3×left_shadow— 33px on KDE Breeze — and added it to an originxwininfoalready reports as the client area. Every click landed 16.5 viewport px low and every capture was cropped 16.5 px low. It hid because the error was self-consistent: clicks and captures shifted together, so ~780 assertions passed and only targets smaller than the drift could detect it. Also correctedLP_Y(the layer panel starts at y=0, not below the menu bar). - Suite grew from 90 to 99 test files; 778 passed / 38 failed → 912 passed / 0 failed. Three tests were un-skipped after their skip reasons turned out to be symptoms of the calibration bug rather than real limitations.
- New coverage: harness calibration, undo/redo depth, tool-switch matrix,
.drawfile round-trip, group draw guard (both config paths), ungroup, and TEXT_BAR visibility. - Documented: CLAUDE.md gotchas 17–20 and a new QA section;
draw-project.mdgotchas 24–27, including that a group'simgHandle&is a 1×1 placeholder.
Breaking Changes
None. No changes to the .draw format, config keys, or hotkeys. Two new config keys (GROUP_DRAW_NOTIFY, GROUP_DRAW_AUTO_LAYER) are additive and default to existing behaviour.
Full Changelog: v1.7.0...v1.8.0