79 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 1660982e58 File tab: PowerPoint's File view (Home, New, Open, Info, Save As, Print, Export, Close) (#76) (#344)
* Engine: file.info and PowerPoint-style print slide ranges (#76)

file.info reports what File › Info shows (name, path, format, unsaved
changes, slide and hidden-slide counts, sections, size on disk,
properties). file.export's PDF `slides` also takes the range typed in
PowerPoint's Print page ("1-3, 5", 1-based); bad or out-of-range text is
an error instead of a silent full export.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* UI: the File tab (Backstage) like PowerPoint's (#76)

File (first ribbon tab) or Alt+F opens a full-window view in place of the
ribbon, slides and status bar: a side menu (Back, Home, New, Open, Info,
Save, Save As, Print, Export, Close; Account and Options at the bottom)
and the chosen page. Esc or Back returns; Up/Down walk the side menu and
show each page as it gets the focus; Enter runs Save/Close/Options.
Laid out after PowerPoint for Windows as observed: 160-pt menu a step
darker than the page, outline icons, current page in the accent colour.

The start screen is now File › Home (as in PowerPoint), with only Home,
New and Open at the top and no Back. Pages call existing commands and
file helpers: file.new {theme} and the sample deck (Home, New); recent
files with search, Browse and Recover Unsaved (Open); file.info and
file.properties, Accessibility Checker, Revert (Info); file.save /
file.saveAs / file.export by type (Save, Save As); a PDF with the Print
page's slides, layout (full page, notes, handouts 1-9), hidden slides and
frames, opened in the system viewer or downloaded on the web, with a
page preview (Print, Ctrl+P); Create PDF, Create Handouts and Change File
Type (Export); appearance and About (Account); Preferences (Options).
Share (cloud) is left out.

Close and Ctrl+W now ask Save / Don't Save / Cancel about unsaved
changes instead of closing at once. The Export dialog shares
SlideApp::export_as with the Export page. New UI commands: app.backstage
{page}, app.closePresentation, app.print; ui.inspect reports the page.
New icons drawn in code: back, save as, account, recent, new file, open
folder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Docs: File tab (Backstage) in ui-parity, gaps, checklist and progress log (#76)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 23:56:02 -04:00
Brandon ThomasandClaude Opus 5.5 f6c143ac85 Text: symbol-font characters draw in the run's a:sym font (#343)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 23:52:01 -04:00
Brandon ThomasandClaude Opus 5.5 a68da9f51d Effects: fill overlays (a:fillOverlay) blend over the shape's fill, and round-trip (#342)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 23:50:02 -04:00
Brandon ThomasandClaude Opus 5.5 cdfaaf4a38 Docs: text in scaled groups is drawn (#340) (#341)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 23:28:37 -04:00
Brandon ThomasandClaude Opus 5.5 10d3333344 Render: text in a scaled group keeps its point size, as in PowerPoint (#340)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 23:27:47 -04:00
Brandon ThomasandClaude Opus 5.5 bb6f0dc88a Render: pictures cast their shadow from their pixels, as in PowerPoint (#338)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:46:32 -04:00
Brandon ThomasandClaude Opus 5.5 e28851d2f1 Pictures: WMF/EMF text, pattern and hatch brushes draw; ActiveX previews show (#336)
* ActiveX controls show their pictures

A slide's p:controls are read: each control with a p:pic (the image PowerPoint shows for it,
often a WMF) becomes a picture above the slide's shapes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Metafiles draw their text, pattern and hatch brushes

deckcraft-metafile (still kurbo + thiserror only, so it builds for wasm):
- Text: WMF EXTTEXTOUT/TEXTOUT and EMF EXTTEXTOUTW/EXTTEXTOUTA/SMALLTEXTOUT with the
  selected font (CREATEFONTINDIRECT, EXTCREATEFONTINDIRECTW: face, signed LOGFONT height,
  width, weight, italic, underline, strike-out, escapement, charset), text and background
  colour, background mode, TA_* alignment and TA_UPDATECP, the dx array (ETO_PDY pairs too),
  ETO_OPAQUE fills and ETO_CLIPPED clips. 8-bit strings decode through their charset
  (Windows-1252/1250/1251; symbol fonts keep their codes at U+F000; double-byte sets keep
  their advances). The neutral Item::Text carries a text-space-to-picture transform, so the
  mapping and escapement are folded in and glyphs are never mirrored.
- Brushes: WMF DIBCREATEPATTERNBRUSH, EMF CREATEDIBPATTERNBRUSHPT and CREATEMONOBRUSH, and
  BS_HATCHED, as Item::Pattern tiles in 96-dpi pixels; WMF PATBLT. The XOR / AND-pattern /
  XOR see-through shadow of old PowerPoint WMFs draws its pattern in the XOR colour.
- MFCOMMENT escapes with an embedded EMF are ignored: PowerPoint draws the WMF's records.
- Pattern pixels and text count against the byte budget; strings are capped.

deckcraft-render draws text through deckcraft-fonts with the face slide text would use
(document_face), symbol fonts mapped as bullets map them (deckcraft_text::symbol_char, now
public, with Webdings), per-character fallback, the file's advances, GDI cell metrics for
top/bottom alignment, underline/strike-out and synthetic bold/italic. Tiles below 1.5 output
pixels per cell are drawn as their average colour.

On the 24 corpus slides that show a metafile, mean abs diff against PowerPoint goes from
28.31 to 5.06 (with the OLE/ActiveX preview commits).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:40:56 -04:00
Brandon ThomasandClaude Opus 5.5 d6ab3d10da UI: en and em dashes show in interface text (#334)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:26:34 -04:00
Brandon ThomasandClaude Opus 5.5 6334d689d2 Text: Ctrl+arrows, Ctrl+Backspace/Delete and other text keys work like PowerPoint (#268) (#333)
* Text: Ctrl+arrows, Ctrl+Backspace/Delete and the other text keys work like PowerPoint (#268)

Observed black-box in PowerPoint for Windows on synthetic text:
- Word stops (crates/model/src/words.rs): words, punctuation runs, symbol
  runs, tabs, line breaks and each CJK character are tokens; trailing spaces
  join the token before. it's, a-b, 3.14, 1,000 are one word; e.g., a_b and
  x@y.com are not. Grapheme clusters never split.
- Ctrl+Left/Right and Ctrl+Shift+Left/Right move by those stops, across
  paragraphs; with a selection they go on from its start/end. In a
  right-to-left paragraph Left and Right swap.
- Ctrl+Backspace deletes to the previous stop; Ctrl+Delete deletes the rest
  of the word, or spaces plus the next word, then applies PowerPoint's smart
  spacing. With a selection both work from its start.
- Ctrl+Up/Down by paragraph, Ctrl+Home/End to the text's ends.
- End on a wrapped line goes past the trailing space and the caret stays
  drawn at that line's end (TextSel::line_end); End again stays, Home
  returns to the same line.
- Ctrl+]/[ and Ctrl+Shift+>/< change font size (egui's Period/Comma/
  bracket key names now match registry shortcuts).
- Shift+F3 cycles lower -> Title -> UPPER; a caret changes its word.
- Double-click selects the word without trailing spaces; triple-click
  includes the paragraph mark.
- Mac keeps Option for words and Cmd for line/text ends (Session::mac_keys).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* rustfmt

* Canvas: one caret, drawn at a wrapped line's end after End

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:09:50 -04:00
Brandon ThomasandClaude Opus 5.5 9d571ef644 Selection Pane: reorder by drag and drop, groups, Show/Hide All and Lock, as in PowerPoint (#133) (#332)
* #133: Selection pane engine: restack inside groups, Show/Hide All, Lock like PowerPoint

- arrange.bringForward/sendBackward/bringToFront/sendToBack and arrange.reorder work on a
  group's children, which stay in their group (as PowerPoint's pane arrows and drag do);
  steps that change nothing leave no undo step.
- selection.select (pane click: Ctrl toggles, children and top-level objects don't mix,
  picking a hidden object shows it), selection.showAll (everything, children too) and
  selection.hideAll (top level).
- shape.lock cascades through groups; locked objects can be selected, formatted and typed
  in, but not moved, sized, rotated, flipped, reshaped or cropped (commands and canvas).
- PPTX: Lock reads and writes PowerPoint's full locking attribute set per element kind
  (observed by saving locked objects from PowerPoint); partial locks aren't Lock.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Front-most first with groups folding; drag a row to restack among its siblings (accent
insertion line); Bring Forward / Send Backward arrows; Show All / Hide All; per-row eye and
padlock; double-click or F2 renames in place; Ctrl+click toggles, Shift+click selects a run;
arrows, Home, End and Esc in the list; right-click menu. Lock/Unlock on the canvas menu,
greyed handles on locked objects. egui_kittest tests drive the pane.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:05:44 -04:00
Brandon ThomasandClaude Opus 5.5 ea3b1159d5 Korean, Japanese and Chinese: input-method composition and interface text (#101) (#331)
* Text: input method composition as commands, one undo step per composition (#101)

text.compose shows an input method's preedit in place at the insertion point and replaces it on
each update; an empty preedit cancels and restores the text and selection. text.commit replaces
the composition with the result as one undo step. Any other edit, key or click settles an open
composition first. The composition is underlined under the baseline (thicker under the part being
converted), and the caret line is measured for empty placeholders too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* UI: Korean, Japanese and Chinese input and interface text (#101)

The slide turns the input method on while it takes typing, with the candidate window at the
caret, and forwards egui Ime events to text.compose / text.commit, so a Korean keyboard composes
syllables instead of separate jamo. Interface text in scripts the interface fonts lack (Hangul,
Simplified Chinese, Thai...) borrows faces from the font database (installed fonts such as Malgun
Gothic; nothing bundled): file names, titles, notes, outline, sections, comments and typed text.
Ported and widened from WordCraft's #565/#840 fallback. The notes pane keeps text typed before
focus leaves in the same frame (Escape, another slide). Control channel: ui.ime.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:03:42 -04:00
Brandon ThomasandClaude Opus 5.5 23a3b6eba2 Fills: a gradient without stops takes them from its style, and keeps none when saved (#330)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:01:29 -04:00
Brandon ThomasandClaude Opus 5.5 f94f3c12d1 Canvas: objects off the slide show and can be grabbed around it, as in PowerPoint (#270) (#329)
PowerPoint's Normal view draws shapes, pictures and text that sit partly
or wholly off the slide on the area around it, at full strength, with
their effects, master and layout graphics included; the slide show,
exports and thumbnails clip to the slide. DeckCraft clipped everything to
the slide in the editor too.

- render: `slide_extent`/`layout_extent` estimate how far a slide's
  drawing reaches (boxes, outlines, shadow, glow, reflection);
  `render_slide_drawn` also reports what a render actually drew (text
  spilling out of its box, table rows that grew); `pasteboard_region`
  picks the pixels the editor renders: the slide plus what reaches off
  it and is in view, rounded to 256 px tiles so scrolling rarely
  re-renders. A slide with nothing off it renders exactly as before.
- ui-egui: the canvas texture covers that region (slide and master
  views); it re-renders only when the slide, zoom or the region changes,
  and a second time only if text drew beyond the estimate.
- Hit testing, selection, marquee and moves already worked in slide
  space; tests now cover them off the slide.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 21:47:05 -04:00
Brandon ThomasandClaude Opus 5.5 75bfd1da3e Embedded objects draw their preview picture, including old VML previews (#328)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 21:40:45 -04:00
Brandon ThomasandClaude Opus 5.5 85366b1a62 Fonts: Office's downloaded fonts are used; opening a file says which fonts are missing (#326)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 20:34:54 -04:00
Brandon ThomasandClaude Opus 5.5 8159db8ba5 Render tests: the arch top bound allows Linux's fallback font (#323)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 19:06:46 -04:00
Brandon ThomasandClaude Opus 5.5 55a53f8ecb Fonts: missing fonts draw as PowerPoint draws them, and Windows family names resolve (#322)
* Text: a missing font is drawn in Calibri, as PowerPoint does

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fonts: Windows family names find their faces; PowerPoint's twins for missing fonts

"Segoe UI Semibold", "Arial Black" and the like are the faces' Windows (GDI) family
names; a family's installed files now load together; Liberation Sans and Serif draw as
Arial and Times New Roman when missing, as PowerPoint draws them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fonts: Office cloud fonts (Aptos…) keep their open substitute

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 19:05:48 -04:00
Brandon ThomasandClaude Opus 5.5 f8d54d7af4 Pictures: WMF and EMF draw, with the metafile reader ported from WordCraft (#317)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:27:19 -04:00
Brandon ThomasandClaude Opus 5.5 a293b68258 Shapes: add 38 missing preset geometries (#315)
lineInv, nonIsoscelesTrapezoid, pieWedge, the left-right / up-down / quad
arrow callouts, circularArrow / leftCircularArrow / leftRightCircularArrow,
the four curved arrows, swooshArrow, callout1-3, accentCallout1-3,
borderCallout2-3, accentBorderCallout1-3, ellipseRibbon / ellipseRibbon2,
leftRightRibbon, flowChartOfflineStorage, gear6 / gear9, funnel, the corner
tabs (corner, square, plaque) and chartX / chartStar / chartPlus no longer
fall back to plain rectangles.

Each outline is our own construction in crates/geom/src/preset/extra.rs,
fitted black-box against PowerPoint renders of synthetic probe decks at
default, changed and extreme adjust values and several aspect ratios
(outline within ~1pt on 300-480pt shapes). Tests cover catalog presence,
hostile sizes/adjusts and measured outline points.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:15:54 -04:00
Brandon ThomasandClaude Opus 5.5 dedb20890b Text: WordArt transforms (prstTxWarp) draw, and their adjusts round-trip (#312)
* Text warps: draw WordArt prstTxWarp presets, round-trip their adjusts

All 40 DrawingML text-warp presets now render instead of drawing flat text.
A warp is a list of bands over the shape's text rectangle (insets ignored):
fill bands stretch the ink of their lines between a top and a bottom guide
(positions by arc length, one horizontal scale for the whole text), follow
bands (arch, circle, button) set lines at natural size along an ellipse arc,
lines stacking outwards on parallel curves, with no wrapping. Lines are
shared over multi-band presets in order (ceil(n/k) per band).

The guide curves were fitted to PowerPoint renders of synthetic decks of
"I" bars (black-box observation, defaults and changed adjusts, 1-3 lines);
most presets match within about a point on a 420 x 200 pt box.

- geom: warp module (guides, presets, band mapping) with unit tests
- render: glyph outlines and underlines flattened, subdivided and mapped
- text: follow warps lay out without wrapping
- model/pptx: BodyProps.warp_adj read from and written to prstTxWarp/avLst

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Text warps: bands with fewer lines keep the fuller band's text height

Multi-band fill warps (Deflate-Inflate, Button Pour) map a box as tall as
the tallest band's ink onto every band, centred on the band's own ink, as
PowerPoint does: a band holding one line next to a band of two keeps the
line at the same size instead of stretching it over the whole band.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:12:58 -04:00
Brandon ThomasandClaude Opus 5.5 5835f0a106 Text: no Latin ligatures, and kerning only from the run's kern size (#309)
PowerPoint keeps fi, ffi and Calibri's ti apart and kerns a run only when
a:rPr/@kern is set and the size reaches it; DeckCraft shaped with the font's
defaults (ligatures and kerning always on), so Calibri text read differently
and kern="0" text came out narrower.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:11:10 -04:00
Brandon ThomasandClaude Opus 5.5 a520dd4d1d Render: shadows, inner shadows and glows spread like PowerPoint's (#305)
* Render: shadows, inner shadows and glows spread like PowerPoint's

Measured on PowerPoint's export of probe shapes:
- outer and inner shadows are blurred by a third of the blur radius (was
  half), so their profile matches pixel for pixel;
- an inner shadow falls inside along the edges its direction points to (45
  degrees: bottom and right); DeckCraft put it on the opposite edges;
- a glow of radius r is half strength about r/2 out and gone by r (was a
  wider, softer halo).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Render tests: probe the outer shadow where the narrower blur still reaches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:09:46 -04:00
Brandon ThomasandClaude Opus 5.5 fd2f8146b4 Bullets: an installed symbol font draws its own glyph (#293)
Bullets in Wingdings, Wingdings 2/3, Symbol and other symbol fonts were
always swapped for a look-alike from one Wingdings table, so a Wingdings 2
star (0xEA) became a round dot. When the deck's symbol font is installed,
its glyph is drawn (symbol fonts map character codes at U+F000 + code), as
PowerPoint does; otherwise Wingdings 2 and 3 codes get their own
look-alikes.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:06:30 -04:00
Brandon ThomasandClaude Opus 5.5 1679836540 Tables: the table's own fill (a:tblPr fill) is drawn behind its cells (#294)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:05:12 -04:00
Brandon ThomasandClaude Opus 5.5 d8407c11f9 Tables: styles the file defines are read, drawn and kept (#292)
* Tables: styles the file defines are read, drawn and kept

PowerPoint writes the definition of every table style a deck uses into
ppt/tableStyles.xml. DeckCraft mapped a handful of GUIDs to its own looks
and drew any other style as Medium Style 2, so themed and light styles came
out in the wrong colours, and dropped the definitions on save.

The reader now keeps each definition (whole table, bands, first/last
rows and columns, corner cells, table background; fills, theme fill and
line references, borders, text colour and bold) on the presentation, and
tables using one keep its GUID. The renderer applies the parts that cover
each cell in the spec's order, a part's edge lines on its region's edges
and its inside lines within it, and paints fills as real fills (gradients
and see-through colours). The writer puts the definitions back as read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Tables: DeckCraft's own table styles still map back to their ids

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fix a brace lost in the rebase

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:03:19 -04:00
Brandon ThomasandClaude Opus 5.5 880b974cff Render: soft edges fade to the shape's outline (#289)
The soft-edge mask was the bounding box shrunk and blurred, so ovals and
other non-rectangular shapes kept hard edges where the box was wider, and
a rectangle's fade began outside it. The mask is now the outline itself,
shrunk by 0.85 r (a stroke punched out of the fill) and blurred by r/3:
transparent at the outline, half opaque 0.85 r inside, as measured on
PowerPoint's export of a 12 pt soft edge.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:00:38 -04:00
Brandon ThomasandClaude Opus 5.5 b3e33928e2 Render: rectangle and outline path gradients (#288)
Path gradients that follow a rectangle (path="rect") or the shape's own
outline (path="shape") were drawn as circles. They're now rasterised into
a small image of the bounds: rect takes the larger of the horizontal and
vertical shares of the distance from the focus to the edge (X-shaped
contours), shape the share of the way from the focus to the outline along
the same ray (an ellipse gives ellipses, a triangle triangles), as
measured on PowerPoint's export. The two path probe decks now match it to
a mean pixel difference of 1.7 and 0.6 (from 15.6 and 22).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:59:32 -04:00
Brandon ThomasandClaude Opus 5.5 d0a3d924bf Render: compound outlines (double, thick-thin, thin-thick, triple) (#287)
a:ln/@cmpd was read but every outline was drawn as one band. Each band is
now stroked along the path moved to its place across the width, in the
shares PowerPoint uses (measured on its export of 24 pt lines: double
1/3-1/3-1/3, thin-thick 1/5-1/5-3/5, triple 1/6-1/6-1/3-1/6-1/6), the
first band on the left of travel (the outside of a shape). Line corners
meet at their miter points; curves are offset with kurbo.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:58:10 -04:00
Brandon ThomasandClaude Opus 5.5 81b6a9df39 Render: pattern fills draw PowerPoint's preset tiles (#285)
Pattern fills were approximated (dots, bars or a grid per family, on an
8-point cell), so pct30 looked like sparse dots and wave like a dot grid.
Every one of the 54 DrawingML presets now draws its 8x8 tile, each cell one
96-dpi pixel (0.75 pt), laid out from the slide's origin. The tiles were
read from PowerPoint's own export of each preset at two output pixels per
cell; the pattern probe deck now matches it to a mean pixel difference of
0.2 (from 62).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:56:30 -04:00
Brandon ThomasandClaude Opus 5.5 d7fbbaeab1 Bullets: a symbol the text font lacks falls back to a font that has it (#284)
Circled-number lists (circleNumDbPlain) and character bullets whose glyph
isn't in the paragraph's font were drawn as missing-glyph boxes (numbers)
or always from Inter (characters). Both now go through the usual font
fallback, as PowerPoint draws them.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:54:25 -04:00
Brandon ThomasandClaude Opus 5.5 2bf62c97e2 Text: shadows and glows are drawn (#283)
Run shadows and glows (a:rPr/a:effectLst outerShdw, glow) were read but
never drawn. The text layout now carries them on each glyph run (colours
resolved, sizes scaled with autofit) and the renderer draws every run's
shadow, then every glow, blurred, under the text. A text glow is solid to
about a third of its radius past the letters and fades out by two thirds,
as measured on PowerPoint's export. needs_filters also looks at text
effects (runs, list styles, master text styles), so they render with the
blur filter.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:53:17 -04:00
Brandon ThomasandClaude Opus 5.5 1bb86db54a Text: gradient fills draw, starting over on every line (#281)
A gradient on text was read but drawn in its first colour. Each line is now
filled with the whole gradient, spanning that line's text from its top to
its bottom and its first to its last character, as PowerPoint does. The
gradient builder moves out of fill_path into paint::gradient so fills and
text share it (and PowerPoint's two-colour ramp). Gradient colours are
resolved when the text style is made.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:51:20 -04:00
Brandon ThomasandClaude Opus 5.5 ba56742fa9 Emoji: drawn in colour, with families, skin tones and flags joined (#278)
* Emoji: colour glyphs, and emoji take the colour emoji font

Emoji were drawn as black outlines from a symbol font, with ZWJ sequences
(families, flags) falling apart into their parts. Now:

- an emoji cluster (emoji presentation, U+FE0F, ZWJ between pictographs,
  skin tones, regional indicators, keycaps) takes an installed colour font
  (COLR, CBDT, sbix or SVG tables) before the document's fonts, so its
  sequences ligate as in PowerPoint; U+FE0E keeps a plain face;
- COLR v0 and v1 glyphs are painted in their CPAL colours (solid fills,
  linear, radial and sweep gradients, transforms, composite modes), with
  palette index 0xFFFF in the text colour.

A tiny COLRv0 test font (two squares, CC0, regenerated by
make_colr_font.py) backs the render test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Render: lock skrifa for colour glyphs

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:48:51 -04:00
Brandon ThomasandClaude Opus 5.5 8b160d5b03 Text: wrap URLs, Korean and CJK punctuation where PowerPoint does (#276)
* Text: wrap lines where PowerPoint does

- Without latinLnBrk (PowerPoint's default) a word doesn't break after '/'
  or '\': URLs and paths fill the line and break at its edge.
- Korean wraps between words, not between syllables.
- With hangingPunct, closing East Asian punctuation hangs past the end of
  the line instead of dragging the previous character down.

ParaProps gains latin_line_break and hanging_punct, read and written as
latinLnBrk and hangingPunct.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Text: simpler break guard (clippy)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:47:12 -04:00
Brandon ThomasandClaude Opus 5.5 39a8234633 Render: slide backgrounds are laid over white (#275)
PowerPoint shows white around a background picture stretched into part of
the slide and under a see-through background colour. DeckCraft left those
areas transparent, which exports and the slide show draw black.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:45:31 -04:00
Brandon ThomasandClaude Opus 5.5 98ea8d3195 Render: shapes filled with the background (useBgFill) show it (#274)
A shape with useBgFill="1" is a window onto the slide's background, laid
out on the slide. DeckCraft drew nothing in it, so a master that covers the
background with a white panel and cuts a background-filled frame into it
(tdf93868) rendered all white.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:44:20 -04:00
Brandon ThomasandClaude Opus 5.5 2e68504e7c Text: single-spaced lines are 1.2 times the font size apart, as in PowerPoint (#266)
* Text: single-spaced lines are 1.2 times the font size apart, as in PowerPoint

PowerPoint spaces single-spaced lines 1.2 x the font size apart in every
font (measured on twenty Latin, CJK, Thai and Indic fonts at 18 and 40 pt
with PowerPoint's slide export) and puts the baseline where the font's
Windows ascent/descent split it. DeckCraft used each font's own ascent plus
descent, so Calibri lines were 15% too tight and Segoe UI ones too loose.

FontFace gains line_split (usWinAscent / (usWinAscent + usWinDescent));
line_metrics uses it with LINE_PITCH = 1.2.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Text: tidy the line pitch test

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fonts: line_split guard reads plainly (clippy)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Text: note that the 1.2 line pitch was measured on one Windows install

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:42:53 -04:00
Brandon ThomasandClaude Opus 5.5 e6050b7d37 Text: a hang past the box edge keeps its width on the first line (#265)
When marL + indent is negative, PowerPoint pins the bullet to the box's edge
and starts the first line's text at -indent; DeckCraft put the text right
after the number, so numbered lists written with indent=-457200 and no marL
lost their gap.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:41:01 -04:00
Brandon ThomasandClaude Opus 5.5 72d8e0ab42 Draw only the first character of a multi-character bullet (#307)
PowerPoint draws buChar char="••" (seen in a LibreOffice test deck) as a
single dot; DeckCraft drew both, pushing the text right.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:36:44 -04:00
Brandon ThomasandClaude Opus 5.5 2347a53845 PPTX: a placeholder without geometry takes its layout's (#301)
PowerPoint leaves an inheriting placeholder's spPr without a geometry and
draws it with its layout (or master) placeholder's: a picture placeholder
cut into a shape, or with holes, keeps that shape on every slide. DeckCraft
read such placeholders as rectangles. They're now marked while reading
and given their parent's geometry once the layouts are read; anything
without a parent stays a rectangle. DeckCraft itself already writes
inheriting placeholders this way.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:36:37 -04:00
Brandon ThomasandClaude Opus 5.5 692aa0103b PPTX: a picture fill with no stretch or tile tiles (#290)
A shape or background blipFill with neither a:stretch nor a:tile (as some
tools write it, tdf#128596) was stretched across the shape; PowerPoint
tiles the picture at its own size.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:36:28 -04:00
Brandon ThomasandClaude Opus 5.5 ceb6e3b990 Render: two-colour gradients ramp like PowerPoint's (#273)
PowerPoint blends a gradient of exactly two stops at 0% and 100% in linear
light, with the second colour's share following an S-shaped curve (black to
white is 105/186/238 at a quarter/half/three quarters, not 64/128/191).
Gradients with more stops, or a stop moved off an end, stay linear in sRGB.
Measured with PowerPoint's slide export on shapes and backgrounds, in both
directions. The two-colour case is expanded into sixteen pieces per
segment so vello's sRGB interpolation draws the same ramp.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:35:59 -04:00
Brandon ThomasandClaude Opus 5.5 4d13652f0f Pictures: duotone recolours, and layout/slide colour map overrides apply (#269)
Theme background pictures (Office 2007-era themes such as Treck) carry an
a:duotone recolour in phClr; DeckCraft read it but drew the picture
unchanged, so those backgrounds came out grey. The painter now resolves the
duotone's colours against the slide's colours and placeholder colour, and
the decoded-image cache applies them (luminance picks a colour between dark
and light) and keys on them.

Layouts and slides can replace the master's colour map
(p:clrMapOvr/a:overrideClrMapping, e.g. dark section layouts mapping bg1 to
dk1). They were read as the master's map; now Layout and Slide carry an
optional colour map, resolve::Ctx uses slide > layout > master, and the
writer keeps them.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:35:52 -04:00
Brandon ThomasandClaude Opus 5.5 235e34613b Text: superscript and subscript advance at their drawn size (#264)
Superscript and subscript glyphs were drawn at two thirds of the run's size but
advanced by the full size, so the letters spread apart ("s u p e r") and the
line ran wider than in PowerPoint. The cluster advance now uses the same scale
as the glyphs.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 17:35:28 -04:00
Brandon ThomasandClaude Opus 5.5 688c7ef592 Release 0.6.1: rebuild with the fixed shared release workflow
The previous release build failed in craft-common-actions, not in this
repo: riscv64 packaging got --formats deb,rpm,tar (fixed in
craft-common-actions#3), Linux jobs lacked the ALSA headers
(craft-common-actions#5), and Windows signing needed the AZURE_* secrets
listed in the caller.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:11:13 -04:00
Brandon ThomasandClaude Opus 5.5 a4540c1f0e Release workflow: pass the Azure signing secrets so Windows builds are signed (#181)
Since the release workflow moved to storytold/craft-common-actions, it has
passed only the Apple and WINDOWS_CERTIFICATE secrets. The signing job reads
values from the release environment, but only for names the caller lists, so
the AZURE_* names that Trusted Signing uses came through empty and Windows
builds would ship unsigned. Same fix as storytold/craft-launcher#174.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:08:13 -04:00
Brandon ThomasandClaude Opus 5.5 0ec0cc5e81 Release prep: 0.6.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 05:44:22 -04:00
Brandon ThomasandClaude Opus 5.5 a98df49b21 Release prep: 0.5.0 and Linux riscv64 release build (#102)
- release.yml: new linux-riscv64 job, ported from GridCraft. Cross-compiles on
  ubuntu-24.04 against ports.ubuntu.com riscv64 libs (incl. libasound2-dev:riscv64),
  packages a tar.gz and smoke-tests deckcraft-cli --version under QEMU. The release
  job needs it, so the draft and SHA256SUMS include it.
- packaging/linux/package.sh: CROSS_ARCH/CROSS_TARGET/CROSS_COMPILE/EMULATOR support.
- README Downloads: list the riscv64 tarball.
- Version 0.4.0 -> 0.5.0 (cargo xtask version set).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:51:07 -04:00
Brandon ThomasandClaude Opus 5.5 f44857624e Progress docs: target-app parity, gaps, alpha gate, readiness by audience (#89)
Progress docs per craftrules standards/progress-docs.md: target-app parity, gaps, roadmap with alpha gate, readiness by audience (full / mainstream / essentials) with Opus 5.5 hours, and feature, format, hardware, UI and localization parity docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:09:21 -04:00
Brandon ThomasandClaude Opus 5.5 84acb49895 Bump version to 0.4.0 (from 0.3.0) for release; refresh contributors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:02:02 -04:00
Brandon Thomas baff6a2ff2 Merge pull request #8 from XusBadia/dmg-background
macOS DMG: branded window background and icon layout
2026-10-09 09:21:03 -04:00
68aff057bf CI: no macOS on PRs or main; macOS is built and tested by releases (#22)
The org has 5 macOS slots in total (GitHub Team), shared by every repo's CI and
release builds, and PR CI kept them full, so release builds queued behind it.
macOS now runs only in release.yml; a release that fails on macOS is fixed and
rebuilt.

Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:51:28 -04:00
3e9bd4398a README Downloads: where to get it first, then builds with Windows before macOS (#10)
Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:50:48 -04:00
db67e0109f Release: Windows arm64, Flatpak aarch64, AppImage zsync updates, README Downloads (#9)
- Windows: add arm64 (aarch64-pc-windows-msvc) to the matrix. package.ps1, sign.ps1 and the
  WiX source already handled it; nothing in the dependency tree blocks the target (clippy -D
  warnings is clean for it).
- Flatpak: x86_64 and aarch64 bundles repackage the Linux job's tarball (PhotoCraft's
  approach: same binaries and embedded fonts as the AppImage/deb/rpm, no Rust build). The
  from-source manifest stays for Flathub; packaging-lint keeps the two in sync. Both now grant
  --socket=pulseaudio so slide-show audio/video plays in the sandbox.
- AppImage: embed gh-releases-zsync update information and publish the .zsync beside it.
- Jobs that sign nothing (version, linux, flatpak, freebsd, web) leave the release environment,
  so a branch dispatch is a dry run; the draft-release job now requires every build.
- README: Downloads section.

Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:43:53 -04:00
Brandon ThomasandClaude Opus 5.5 286ff74c8b Release CI: macOS job on macos-15-xlarge
Custom macOS larger runners in a runner group do not pick up jobs; the
built-in M2 Pro label does. Only release.yml uses it, and the
actions_macos_xl budget caps the monthly spend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:08:08 -04:00
Brandon ThomasandClaude Opus 5.5 e659ebcd27 Release CI: macOS job on the org macos-release runner
The standard macOS runners are shared with all CI and queue for an hour or
more. The macos-release runner (GitHub-hosted M2 Pro) is in a runner group
usable only by release.yml on the release branch, with a monthly spend cap
on the actions_macos_xl SKU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:55:01 -04:00
Brandon ThomasandClaude Opus 5.5 a4bb8fe763 About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#3)
* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)

Adds the craftrules standard (standards/contributors.md) to DeckCraft's About window:
tabs About · Contributors · Models. contributors/contributors.json is generated by
craftrules/scripts/contributors.py and baked into the binary by crates/ui-egui/build.rs as
static tables. Each contributor line: @username, opt-in display/real name, PRs, commits,
lines +/−/Δ, binary assets +/−, first/last commit. Sortable by every column; alphabetical
ignores case and the leading @. The control channel's ui.dialog.open now honours its
documented `fields` param (e.g. About {"tab": "contributors"}).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: self-submitted names in contributors/people.toml; AGENTS.md credit-yourself section

build.rs reads contributors/people.toml next to the generated contributors.json and shows a name only
for entries the generator verified as written by that person (craftrules standards/contributors.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: regenerate (verified people.toml entries)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:16:38 -04:00
Brandon ThomasandClaude Opus 5.5 9da767d5f7 ROADMAP: v0.1.0 released (signed, notarized)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:23:52 -04:00
Brandon ThomasandClaude Opus 5.5 efb03b90a8 Rename PrintCraft to PdfCraft (storytold/pdfcraft) (#1)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:45:28 -04:00
Brandon ThomasandClaude Opus 5.5 942a2c80cc Release: ALSA build/runtime deps (Linux, FreeBSD, deb/rpm); vendor Flatpak crate sources on a plain runner
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 02:28:20 -04:00
Brandon ThomasandClaude Opus 5.5 0c2a68ecdb Release workflow: build only on the release branch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 02:07:54 -04:00
Brandon ThomasandClaude Opus 5.5 c7614ecec8 README: screenshots, feature overview and alpha/parity summary; docs use control port 7990
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 02:01:34 -04:00
Brandon ThomasandClaude Opus 5.5 ae9d525bce Rename SlideCraft to DeckCraft: crates, apps, binaries, app id, file extension (.deckcraft; .slidecraft files still open), packaging, docs; ROADMAP alpha and parity estimates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:46:40 -04:00
Brandon ThomasandClaude Opus 5.5 49278565ea Media playback: module order
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:35:09 -04:00
Brandon ThomasandClaude Opus 5.5 4375fe7b89 Media playback: slidecraft-media (probe, audio decode, H.264/HEVC/VP9/AV1 video, mixer and clock), cpal output, editor control bar, slide show playback, media.* commands
- crates/media: probe (duration, rate/channels, size/fps; WMA/WMV recognised), audio decode to
  f32 PCM (MP3, AAC M4A/ADTS, ALAC, WAV, AIFF, CAF, FLAC, Vorbis via symphonia; Opus with our
  decoder in Ogg/WebM/MKV), video decode (MP4/MOV/WebM/MKV) with YUV->RGBA, poster frames,
  trim/fade/volume, Player mixer + per-voice clock (device-clocked or wall-clocked), VideoFeed.
- Codec crates ported from FilmCraft: bitstream, h264, hevc, vp9, av1, isobmff, matroska, ogg, opus.
- insert.audio/insert.video probe and store duration/size and a poster frame; unplayable media
  is embedded with a warning. New media.play/pause/toggle/stop/seek/info/posterFrame.
- UI: MediaHost (cpal output injected by the desktop app), control bar under media, video frames
  on canvas and in the show; autoplay, click to play, loop, rewind, across slides, hide, full screen.
- Tests with in-code WAV/AIFF and CC0 self-generated fixtures (make.sh, ATTRIBUTION.md rows).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:35:09 -04:00
Brandon ThomasandClaude Opus 5.5 56f31158c7 Gradient editor (type, direction, angle, stops with colour/position/transparency) for shape fill and Format Background; pattern backgrounds; painted dropdown chevrons
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:34:50 -04:00
Brandon ThomasandClaude Opus 5.5 b899290f4b AutoRecover: unsaved presentations saved to a recovery folder and reopened after a crash; save-changes prompt when quitting
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:26:54 -04:00
Brandon ThomasandClaude Opus 5.5 ad469f9b13 Merge Shapes (union, combine, fragment, intersect, subtract); CI workflow running cargo xtask ci; control protocol and MCP docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:14:15 -04:00
Brandon ThomasandClaude Opus 5.5 f0d230bdcd Freeform, Curve and Scribble drawing tools; shape.freeform command; composite commands are one undo step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:00:06 -04:00
Brandon ThomasandClaude Opus 5.5 8598c41085 Cargo.lock: sync with slidecraft-pptx dependencies (release builds use --locked)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:55:34 -04:00
Brandon ThomasandClaude Opus 5.5 0b394ad433 Web build and release CI: slidecraft-web, packaging, release workflow
- apps/slidecraft-web: SlideApp in the browser via eframe's web runner (trunk; WebGPU with
  WebGL2 fallback). Opens the sample deck (?blank for empty, ?show to present, ?webgl to force
  WebGL2). Open/Insert use the browser file picker through Services::open_async + inbox;
  Save/Export download; dropped files are read asynchronously.
- ui-egui: native-only synchronous drop handling (wasm uses the inbox), real clock on wasm
  (js_sys::Date::now), About shows build commit/date when SLIDECRAFT_BUILD_SHA/DATE are set.
- .github/workflows/release.yml (push to `release` / workflow_dispatch): macOS universal
  signed+notarized dmg, Windows x64/x86 signed msi + portable zip, Linux AppImage/deb/rpm/tar.gz
  (x86_64, aarch64), Flatpak bundle, FreeBSD tar.gz (vmactions), web zip; draft GitHub Release
  "SlideCraft v<version>" from [workspace.package] version. Same secret names as DesignCraft.
- freebsd.yml and packaging-lint.yml CI, ported from DesignCraft.
- packaging/: macOS (Info.plist, entitlements, cert import), Windows (WiX with new UpgradeCode,
  .slidecraft ProgId, Open-with for pptx), Linux (.desktop, AppStream, MIME, nfpm, Flatpak),
  FreeBSD and web scripts; shared setup in packaging/common.sh.
- apps/slidecraft/build.rs embeds icon + VERSIONINFO on Windows; slidecraft.icns/.ico generated
  from the committed PNGs by packaging/icons.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:53:58 -04:00
Brandon ThomasandClaude Opus 5.5 e273d60f22 PPTX import/export: full OPC package, themes, masters/layouts, shapes, text, pictures, media, tables, charts, transitions, animations, comments; verified opening in PowerPoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:50:02 -04:00
Brandon ThomasandClaude Opus 5.5 74ea37b36a Connectors: glue ends to connection sites, reroute on move/resize, shape.connect / shape.sites commands, site feedback on canvas
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:49:15 -04:00
Brandon ThomasandClaude Opus 5.5 639957c68a PDF export: slides, notes pages and handouts with selectable text layer, links and bookmarks; Export dialog PDF options
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:39:54 -04:00
Brandon ThomasandClaude Opus 5.5 0c0f55e47c xtask (ci, assets, layers, wasm, parity, version, ico), PowerPoint parity catalog, ROADMAP
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:17:57 -04:00
Brandon ThomasandClaude Opus 5.5 55a5752d25 Slide show: by-paragraph text builds render per paragraph, sub-bullets follow their parent
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:14:59 -04:00
Brandon ThomasandClaude Opus 5.5 e62b7ccd15 M0: PowerPoint-style egui UI, slide show engine, icons, desktop app
- ui-egui: title bar, ribbon with every tab (Home, Insert, Draw, Design, Transitions,
  Animations, Slide Show, Record, Review, View) plus contextual Shape/Picture Format,
  Table Design/Layout, Chart Design, Playback and Slide Master tabs; thumbnail pane with
  sections and drag reorder; canvas with selection handles, smart guides, marquee,
  in-place text editing; notes pane; status bar with views and zoom; task panes
  (Format Shape, Background, Animation, Selection, Comments, Design Ideas); dialogs;
  Slide Sorter, Notes Page, Outline view; command palette; control channel
- anim: timelines for every animation effect, transition layers for every transition,
  morph pairing, show navigation (hidden slides, custom shows, loops)
- show: full-screen slide show with transitions, animations, pen, black/white
  screens, presenter view window, rehearse timings, reading view
- icons: 238 original icons drawn in code
- render: filters force single-threaded rendering (regression test), panic guard
- engine: chart type/data/options, SmartArt-style graphics
- apps/slidecraft: desktop host with control server, file dialogs, clipboard images
- placeholder app icon rendered by SlideCraft itself

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:08:13 -04:00
Brandon ThomasandClaude Opus 5.5 6078b68e97 M0: workspace, model, geometry, fonts, text, renderer, engine, MCP and CLI
Clean-room PowerPoint-class presentation engine in pure Rust:
- geom: units, transforms and 150+ re-derived preset shapes with adjust handles
- color: theme slots and colour transforms
- model: presentations, masters, 11 layouts, placeholder inheritance, themes,
  text, tables, charts, transitions, animations, text edit operations
- fonts: font DB with craft-fonts, system fonts and open substitutes
- text: shaping, line breaking, bullets/numbering, alignment, autofit, caret hit tests
- render: vello_cpu slides with fills, gradients, pictures, effects, tables, charts
- format: native .slidecraft (zip + JSON)
- engine: ~200 commands, undo/redo, clipboard, pointer tools, keys, sample deck
- mcp: MCP server (headless or bridged to the app); slidecraft-cli

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:27:20 -04:00
Brandon Thomas 9e68eb6d60 initial commit 2026-10-05 22:13:02 -04:00