mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-31 21:56:50 -06:00
egui037: Port DesignCraft to egui 0.37
Pin the final egui, winit and shared UI revisions and reconcile current main. Preserve document-epoch input and screenshot boundaries, host action ordering, and Windows path regression coverage. Add click/End batch characterization. Validation: all nine Linux CI stages pass (3230 tests, zero failures); Windows CI and bounded native editing workflows pass on the same production source.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+8
-2
@@ -1,6 +1,6 @@
|
||||
# Where DesignCraft falls short of InDesign
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (gap 28 added: placed-PDF font repair remains after visible unembedded font detection, #909; gap 26 shrunk: autoflow fills the following pages before it adds pages at the end; gap 6 shrunk: Type › Reload Fonts reads fonts installed, edited or removed while running (#328); gap 3: Package links are relative, #340; gap 27 closed: the loaded text cursor threads into a frame inside a group (#1075); .indd and .indt open through indd-utils; gap 0 shrunk: text threads by hand; threading gaps added; Optical kerning from outlines (#181); gap 6: macOS lists fonts that font services and managers activate; shared print spooler; image clipping paths from IDML; Tabs panel listed as present (#343); book chapter update safety; gap 16: Based on Parent leftovers; bounded control click/drag input; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (gap 16: Convert Variable to Text; gap 28 added: placed-PDF font repair remains after visible unembedded font detection, #909; gap 26 shrunk: autoflow fills the following pages before it adds pages at the end; gap 6 shrunk: Type › Reload Fonts reads fonts installed, edited or removed while running (#328); gap 3: Package links are relative, #340; gap 27 closed: the loaded text cursor threads into a frame inside a group (#1075); .indd and .indt open through indd-utils; gap 0 shrunk: text threads by hand; threading gaps added; Optical kerning from outlines (#181); gap 6: macOS lists fonts that font services and managers activate; shared print spooler; image clipping paths from IDML; Tabs panel listed as present (#343); book chapter update safety; gap 16: Based on Parent leftovers; bounded control click/drag input; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6)
|
||||
|
||||
Every known shortfall against InDesign 2026, one entry each, ranked by how much it stops an
|
||||
InDesign professional from doing real work. This is the work list: agents pick from the top.
|
||||
@@ -177,9 +177,12 @@ Kind: **F** feature · **U** UI/UX · **T** typography · **FF** file format ·
|
||||
- **Estimate:** 30–50 h.
|
||||
|
||||
### 16. Menu items still missing (U)
|
||||
- **Missing:** 151 of 482 in-scope items of InDesign 21.6's menu dump have no match (measured 2026-10-10; some exist under other labels): Type ▸ Notes
|
||||
- **Missing:** 149 of 482 in-scope items of InDesign 21.6's menu dump have no match (measured 2026-10-10; some exist under other labels): Type ▸ Notes
|
||||
- **Missing:** 150 of 482 in-scope items of InDesign 21.6's menu dump have no match (measured 2026-10-10; some exist under other labels): Type ▸ Notes
|
||||
and Track Changes submenus (the panels and commands exist), hyperlink and cross-reference
|
||||
update commands, Convert Bullets/Numbering to Text, Convert Variable to Text, Object ▸ Clear
|
||||
Effects / Clear All Transparency / Rotate 180° / Reverse Path,
|
||||
update commands, Convert Bullets/Numbering to Text, Object ▸ Clear
|
||||
Effects / Clear All Transparency / Rotate 180° / Reverse Path, Layout ▸ Go Back/Forward,
|
||||
Window ▸ Arrange (2-up … 6-up), Trap Presets, Overlays, Edit ▸ Assign Profiles / Convert to
|
||||
Profile / Edit Original, File ▸ File Info / Open PDF / Document and Print Presets / User
|
||||
@@ -202,6 +205,9 @@ Kind: **F** feature · **U** UI/UX · **T** typography · **FF** file format ·
|
||||
- **Estimate:** 20–35 h.
|
||||
|
||||
### 19. Placed graphics depth (FF)
|
||||
- **Safety:** PDF visibility variants preserve catalog/configuration entries and nonzero-generation
|
||||
references, redefining the existing catalog rather than choosing an arbitrary object number.
|
||||
Encrypted, hybrid-reference and over-budget rewrites are rejected; no print-fidelity claim.
|
||||
- **Missing:** EPS is shown through its preview only (no PostScript interpreter); PSD layer
|
||||
comps beyond visibility; the Clipping Path Options dialog (tracing into a clip that keeps the
|
||||
frame, Threshold/Tolerance/Inset Frame preview, picking an alpha channel or a path saved in a
|
||||
|
||||
+18
-11
@@ -88,6 +88,8 @@ claude mcp add designcraft -- designcraft-cli mcp
|
||||
|
||||
```sh
|
||||
designcraft-cli mcp --automation-read-root /work/project --automation-write-root /work/project/out
|
||||
designcraft-cli mcp --automation-read-root /work/project --automation-read-root /work/shared-assets \
|
||||
--automation-write-root /work/project/out --automation-write-root /tmp/scratch
|
||||
```
|
||||
|
||||
```json
|
||||
@@ -98,16 +100,16 @@ designcraft-cli mcp --automation-read-root /work/project --automation-write-root
|
||||
The two flags (VectorCraft, PhotoCraft and the other Craft apps take the same ones, so one client
|
||||
config works across the suite) keep the agent to the folders you give it:
|
||||
|
||||
- Every file a command reads must lie inside the **read root**: `open_document`, `file.open`,
|
||||
- Every file a command reads must lie inside a **read root**: `open_document`, `file.open`,
|
||||
`file.openIdml`, `place_image` and `file.place` / `place.load` / `media.options` with a `path`,
|
||||
`links.relink`, `links.relinkFolder`, `color.loadProfile`, `swatch.load`, `library.open`,
|
||||
`book.open`, `data.source.select`, `data.merge` and `file.importXml` / `xml.loadDtd` with a `path`,
|
||||
and `file.recovery.list` / `file.recovery.open` with a `dir`. A DesignCraft document names more
|
||||
files than the agent does: linked images, data sources, book chapters, the `Document Fonts` folder
|
||||
beside a document, an IDML package's linked images and the files an image cell of a merge names.
|
||||
Those are read through the same checks, so a path in a document that leads outside the read root
|
||||
Those are read through the same checks, so a path in a document that leads outside the read roots
|
||||
reads as a file that isn't there.
|
||||
- Every file a command writes must lie inside the **write root**: `save_document`, `export_png`,
|
||||
- Every file a command writes must lie inside a **write root**: `save_document`, `export_png`,
|
||||
`render_page` with a `path`, `file.save`, `file.saveAs`, `file.saveACopy`, `file.exportPdf`,
|
||||
`file.exportEpub`, `file.exportFixedEpub`, `file.exportHtml`, `file.exportText`, `file.exportXml`,
|
||||
`file.exportIdml`, `file.printBooklet`, `snippet.export`, `swatch.save`, `library.new` and the
|
||||
@@ -115,21 +117,26 @@ config works across the suite) keep the agent to the folders you give it:
|
||||
`file.package`, `links.copyTo` and `file.recovery.save` / `file.recovery.open` with a `dir`
|
||||
(reopening removes the entries it read). `file.package` and `links.copyTo` check their folder
|
||||
before they create anything.
|
||||
- Read and write access are separate. Give the same folder twice for both. A root left out grants
|
||||
none of its access: with only `--automation-read-root` nothing can be written to disk. Without
|
||||
either flag nothing changes.
|
||||
- Each flag may be given more than once (#1552): a path inside any of the read roots may be read,
|
||||
one inside any of the write roots written, so one session can read a project folder and a shared
|
||||
assets folder, or write to an output folder and a scratch folder, without widening a root to
|
||||
their common parent (which the roots don't grant). A folder given twice counts once.
|
||||
- Read and write access are separate. Give the same folder to both flags for both. A kind left out
|
||||
grants none of its access: with only `--automation-read-root` nothing can be written to disk.
|
||||
Without either flag nothing changes.
|
||||
- A path is made absolute against the server's working directory, then its links are followed: a
|
||||
file (or folder) link that leads out of a root is outside it. For a file that doesn't exist yet,
|
||||
file (or folder) link that leads out of the roots is outside them. For a file that doesn't exist yet,
|
||||
its nearest existing folder's links are followed and the rest must be plain names, so `..` below a
|
||||
folder that doesn't exist is refused, as is a link that leads nowhere (writing through it would
|
||||
create its target). The result is compared with the root by whole folder names: `/work2/x` is not
|
||||
create its target). The result is compared with each root by whole folder names: `/work2/x` is not
|
||||
inside `/work`. On Windows case is ignored, UNC paths (`\\server\share\...`) are resolved like
|
||||
drive-letter ones, and device names (`CON`, `NUL`, `COM1`...) are refused.
|
||||
- A refused path is an ordinary tool error the agent can read and correct, for example
|
||||
`automation path rejected: outside the write root /work/project/out: /etc/x.designcraft` or
|
||||
`automation path rejected: outside the write root /work/project/out: /etc/x.designcraft` (with
|
||||
several, `outside the write roots /work/project/out, /tmp/scratch: ...`) or
|
||||
`automation filesystem access is not granted: write authority is absent: /work/project/out/x.designcraft`.
|
||||
- The roots must be existing folders; a missing one stops the server with an error. Each flag is
|
||||
given once (`--flag <dir>` or `--flag=<dir>`).
|
||||
- The roots must be existing folders; a missing one stops the server with an error. Each flag takes
|
||||
one folder per use (`--flag <dir>` or `--flag=<dir>`) and may be used again for more.
|
||||
|
||||
The flags confine the in-process server, so `--connect` together with them is an error: the server
|
||||
would otherwise talk to an app that isn't confined. DesignCraft's desktop app has no equivalent flags
|
||||
|
||||
+8
-2
@@ -1,7 +1,7 @@
|
||||
# Shared PDF backend
|
||||
|
||||
DesignCraft pins `craft-pdf`, patched Krilla 0.8.2 and the four Hayro reader crates to
|
||||
craft-libs revision `89dcbb3060377a26c99a6d80caa16084366704c4`. Existing `craft-ui` and `craft-print` revisions
|
||||
DesignCraft pins `craft-pdf`, patched Krilla 0.8.2 and the five Hayro reader crates (with
|
||||
`hayro-cmap`) to craft-libs revision `9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef`. Existing `craft-ui` and `craft-print` revisions
|
||||
remain unchanged. The reader migration is reviewed on top of the separate writer change.
|
||||
|
||||
## Writing
|
||||
@@ -49,6 +49,12 @@ are recorded separately in ASSETS.md.
|
||||
DesignCraft retains placement, layer-name policy, document state and the application render
|
||||
cache. Render output is premultiplied RGBA8. Page boxes use the same crop, rotation and
|
||||
UserUnit transform as raster output, including fractional placed-PDF dimensions.
|
||||
Layer choices are validated for every selected PDF before any document/undo state changes;
|
||||
a selection containing an unsupported or layerless PDF is refused rather than partially edited.
|
||||
Stale persisted/relinked choices that cannot be honored suppress the graphic on canvas rather
|
||||
than reveal hidden source content; resetting to file defaults remains available. All-content
|
||||
cropping keeps the whole page when real optional-content state cannot be rewritten, while
|
||||
layerless files and empty/null optional-content properties retain measured bounds.
|
||||
Layered-PDF export stops on failed layer rewriting, missing pages or reported incomplete
|
||||
content rather than saving an unchanged or incomplete placed page. Shared diagnostics only
|
||||
report known backend warnings; they do not certify all PDF fidelity.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# DesignCraft parity with Adobe InDesign
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (PDF/X-4 visible unembedded font detection, #909; autoflow fills the following pages first; File ▸ Open Recent; .indd and .indt open through indd-utils; text threads by hand; image clipping paths from IDML; anchored objects wrap text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; recovery checkpoint retention; cancelable macOS Dock Quit; Based on Parent; object styles carry effects; colour management on craft-cms, Coated FOGRA39 default CMYK; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6.0.57, macOS)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-24 · **Change:** minor (Convert Variable to Text; list buttons with the default hanging indent; custom anchored objects honour Relative to Spine; PDF/X-4 visible unembedded font detection, #909; autoflow fills the following pages first; File ▸ Open Recent; .indd and .indt open through indd-utils; text threads by hand; image clipping paths from IDML; anchored objects wrap text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; recovery checkpoint retention; cancelable macOS Dock Quit; Based on Parent; object styles carry effects; colour management on craft-cms, Coated FOGRA39 default CMYK; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6.0.57, macOS)
|
||||
|
||||
The authoritative assessment of how close DesignCraft is to Adobe InDesign. [ROADMAP.md](../ROADMAP.md)
|
||||
summarizes it; [gaps.md](gaps.md) lists every known shortfall one at a time; the feature-by-feature
|
||||
@@ -204,7 +204,7 @@ table is the one summed.
|
||||
| Area | Breadth (checklist) | Ready | Hours | Main gaps |
|
||||
|---|---|---|---|---|
|
||||
| Application shell & workspace | 99% | 55% | 40–60 | context menus not opening on some systems; window controls (#333); System theme (#237); New Window/Arrange; Help menu |
|
||||
| Documents, pages, spreads | 100% | 65% | 20–35 | Layout ▸ Pages submenu items, Page Attributes / Color Label, Go Back/Forward, layout grid (CJK) |
|
||||
| Documents, pages, spreads | 100% | 65% | 20–35 | Layout ▸ Pages submenu items, Page Attributes / Color Label, layout grid (CJK) |
|
||||
| Layers | 100% | 75% | 5–10 | IDML layer order fixed 2026-10-09; Layer panel options depth |
|
||||
| Frames, shapes & paths | 100% | 60% | 25–40 | object copy/paste failures, reference point relocation (#337), Join/Reverse Path/Convert Point menu |
|
||||
| Transform | 100% | 70% | 10–20 | Rotate 180°; transform panel depth |
|
||||
@@ -324,7 +324,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Object ▸ Generate QR Code (`object.qrCode`: web link, text, SMS, email, business card; vector modules as a compound path, into a frame or re-encoded in place).
|
||||
- Conditional text (`condition.new/options/delete/apply/list`, Conditional Text panel): hidden conditions drop their text from layout and exports, indicators underline on screen, IDML Condition/AppliedConditions.
|
||||
- Endnotes (`endnote.insert/edit/delete/list/options`, Type ▸ Insert Endnote): references number through the document, the endnote frame on a new last page lists them under a heading; IDML keeps the listed text only.
|
||||
- Editorial notes (`note.new/edit/delete/convertToText/list`, Notes panel): anchored in text, flagged on screen, never printed or exported.
|
||||
- Editorial notes (`note.new/edit/delete/convertToText/convertFromText/list`, Notes panel, Type › Notes › Convert to Note): anchored in text, flagged on screen, never printed or exported.
|
||||
- File ▸ Print Booklet (`file.printBooklet`): saddle-stitch or 2-up consecutive printer spreads as PDF, padded with blanks, with a gap between pages.
|
||||
- Edit ▸ Transparency Blend Space (`edit.transparencyBlendSpace`; RGB for web/mobile documents; IDML TransparencyPreference) — exported PDFs give pages with transparency a DeviceCMYK or DeviceRGB page group, so viewers and RIPs blend in that space. On screen, CMYK spreads with separable blend modes use two ink-channel passes through the working colour settings. Parent-page items, nested groups, effects and pasteboard share that path; 100% K in Color Dodge whitens coloured areas while paper stays outside the blend backdrop. Effect blend layers sit outside their clips and offscreen filters, preserving their backdrop in RGB too. The pass count is independent of blended-object count, and unchanged viewports reuse one cached raster (64 MiB cap). Spreads containing Hue, Saturation, Color or Luminosity still use the existing RGB blend followed by a CMYK proof approximation; full nonseparable CMYK blending remains open.
|
||||
- High Contrast interface theme (fifth Interface Color Theme: black chrome, white text, yellow selection).
|
||||
@@ -343,7 +343,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- View ▸ Fit Selection in Window (⌥⌘=) and Find/Change ▸ Object (`find.objects`, `find.changeObjects`: by fill, stroke, weight, opacity, kind, layer, label).
|
||||
- Custom workspaces (`window.newWorkspace/deleteWorkspace/resetWorkspace`; workspace switcher shows the current one): bars and panel arrangement saved by name. Essentials Classic shows the Control panel and InDesign's iconic panel groups with names. The Window menu follows InDesign's: Arrange, Workspace, then the panels alphabetically with their Color, Editorial, Interactive, Object & Layout, Output, Styles, Type & Tables and Utilities groups.
|
||||
- Word/RTF Import Options (File ▸ Place with Import Options…, `place.styles`, `file.place {styleMap, styleConflicts}`): map imported styles onto the document's, use existing / redefine / auto-rename on conflicts, or remove formatting.
|
||||
- Custom anchored objects (`anchored.insert/options {position: custom}`): placed relative to the anchor, frame, column, page margins or page edge with reference points and offsets, no space in the text, keep within column; IDML Anchored position. Their text wrap pushes aside the text of other stories they overlap and the lines of their own story after the anchor's line.
|
||||
- Custom anchored objects (`anchored.insert/options {position: custom}`): placed relative to the anchor, frame, column, page margins or page edge with reference points and offsets, no space in the text, keep within column, Relative to Spine (mirrored on right-hand pages); IDML Anchored position. Their text wrap pushes aside the text of other stories they overlap and the lines of their own story after the anchor's line.
|
||||
- Variable font axes: Character panel sliders; any axis values (`fontStyle: "Bold {wght:650}"`) make that instance for layout, screen and PDF.
|
||||
- Image Import Options › Crop to for placed PDFs (`file.place {pdfCrop: crop|trim|bleed|art|media}`, Place PDF dialog): the frame shows that page box.
|
||||
- Stroke styles: striped (thick-thin… and custom bands), wavy and straight-hash strokes now draw on screen and in PDF; named custom stripe/dash/dot styles (`strokeStyle.new/delete/list`, Stroke panel Type list; IDML Striped/Dashed/DottedStrokeStyle).
|
||||
@@ -382,7 +382,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Split Window / New Window (`window.split`, `window.newWindow`, Window ▸ Arrange): two side-by-side views of the document with their own zoom, scroll and render cache. New Window puts the second view in its own OS window (an egui viewport; a floating window on the web).
|
||||
- Transparency flattener (`file.exportPdf {flatten: high|medium|low|ppi}`, Edit ▸ Transparency Flattener Presets): each object involving transparency becomes an opaque image of its area over what's beneath it, so everything else stays vector (spreads with transparent parent items are rasterised whole).
|
||||
- Video and sound (place .mp4/.mov/.webm/.mp3/.wav…, `media.options/get`, Media panel): media frames show a poster or placeholder on screen, in print and in PDF, and export as HTML5 `<video>`/`<audio>` in EPUB. Interactive PDF export (`file.exportPdf {media: true}`, File ▸ Export PDF (Interactive)) embeds each file and plays it in a Screen annotation through a rendition action (controls, loop, play on page load). No in-app playback.
|
||||
- Right-to-left text (World-Ready basics): right-to-left runs are shaped right to left, lines are reordered by the Unicode Bidirectional Algorithm (matched against the reference implementation), Paragraph Direction (`type.para {direction}`, Paragraph panel, IDML ParagraphDirection, EPUB `dir`). Digits (`digits`: Default, Arabic, Hindi, Farsi, Native by language; Character panel and Character Style Options; IDML DigitsType) draw 0–9 in another script. Kashidas (`kashidas` paragraph attribute, on by default; IDML Kashidas): justified Arabic lines stretch at one join per word (after seen/sad when possible, never inside lam–alef) with a drawn tatweel before word spaces widen. Carets follow the drawing: the caret before a right-to-left glyph sits at its right edge, arrow keys move as drawn (by words in the line's direction), clicks find the nearest drawn caret position and selections highlight the selected glyphs. Binding: Right to Left (Document Setup, `layout.documentSetup {binding}`, IDML PageBinding) makes page 1 a left page and lays spreads out right to left.
|
||||
- Right-to-left text (World-Ready basics): right-to-left runs are shaped right to left, lines are reordered by the Unicode Bidirectional Algorithm (matched against the reference implementation), Paragraph Direction (`type.para {direction}`, Paragraph panel menu, IDML ParagraphDirection, EPUB `dir`). Digits (`digits`: Default, Arabic, Hindi, Farsi, Native by language; Character panel and Character Style Options; IDML DigitsType) draw 0–9 in another script. Kashidas (`kashidas` paragraph attribute, on by default; IDML Kashidas): justified Arabic lines stretch at one join per word (after seen/sad when possible, never inside lam–alef) with a drawn tatweel before word spaces widen. Carets follow the drawing: the caret before a right-to-left glyph sits at its right edge, arrow keys move as drawn (by words in the line's direction), clicks find the nearest drawn caret position and selections highlight the selected glyphs. Binding: Right to Left (Document Setup, `layout.documentSetup {binding}`, IDML PageBinding) makes page 1 a left page and lays spreads out right to left.
|
||||
- Interface language (Preferences ▸ General ▸ Interface Language, `app.language`; each language listed by its own name): German, French, Spanish, Italian, Japanese, Simplified Chinese and Arabic menu titles, common menu items and panel names (our own translations). Common dialog, panel and tooltip labels are also localized, with English fallback for untranslated strings. Arabic translations cover every key in the shared interface translation table, including menu commands and utility labels. The Type menu's Story Direction, Horizontal/Vertical, Tate-Chu-Yoko, Ruby… and Kenten are translated too. Arabic labels use Unicode bidi run ordering and contextual shaping; welcome and new-document form layouts follow RTL direction independently of document binding. CJK and Arabic glyphs come from [craft-fonts](https://github.com/storytold/craft-fonts) when built with `CRAFT_FONTS_DIR` (all releases): BIZ UDPGothic and Noto Sans CJK SC for the UI (Chinese forms first in the Chinese interface), Noto Sans Arabic, and Mincho for Japanese documents (the web build embeds BIZ UDPGothic only); otherwise from system fonts. Ukrainian covers all 1,430 existing catalog keys, including publishing dialogs and built-in names, with persisted selection, grammatical count captions, English fallback and bundled Cyrillic UI glyph coverage. Polish covers 1,717 catalog keys with the same category-first count captions and English fallback.
|
||||
- Page transitions (`page.transition/transitions`, Page Transitions panel): twelve transition types with speed and direction per spread, written into exported PDFs as `/Trans` entries through an incremental update.
|
||||
- PDF/X-4 export (`file.exportPdf {standard: "x4"}`): an output intent with the working CMYK space's profile (by default craft-cms's Coated FOGRA39 profile, identifier FOGRA39; Generic CMYK and Device CMYK embed our Generic CMYK profile, lut16 tables generated from the parametric press model), GTS_PDFXVersion in Info and XMP, `pdf:Trapped` in XMP as in Info, `xmp:MetadataDate` and `xmpMM:VersionID` in XMP, RGB images without a profile tagged sRGB, no image interpolation (none in PDF/A either), and built-in PDF/X-4 checks reported as warnings. qpdf finds no errors in the result.
|
||||
@@ -409,6 +409,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Drag and drop text editing: drag selected text to move it (Alt copies) with its formatting (`text.release`).
|
||||
- Input methods (IME) in the Type tool: a Chinese, Japanese or Korean composition shows its marked text in place in the story, underlined (the clause being converted twice), with the IME's candidate window at the caret through zoom, scrolling, view rotation and vertical text; the commit is one `text.insert` and one undo step, a cancelled composition leaves the document as it was; keys, shortcuts, the clipboard and Undo wait while the IME composes, and a click or another command keeps the marked text as typed. The control channel's `ui.ime` and the MCP `ime` tool (headless too) send IME events. Not yet checked by hand with a system IME (macOS, Windows, Linux, web).
|
||||
- Image Import Options: place any page of a multi-page PDF (`file.place {pdfPage}`; the app asks which page), shown on screen and embedded as that page in PDF export.
|
||||
- Bulleted and Numbered List buttons (Properties › Bullets and Numbering; Type › Bulleted & Numbered Lists › Apply Bullets / Apply Numbers, ✓ when the selection has them; `list.bullets`, `list.numbers`): as InDesign's, a paragraph with no indents gets the default hanging indent (Left Indent 0.25 in, First Line Indent −0.25 in), so the bullet or number sits at the margin and the text after its tab at the indent; pressed again, the list goes and so does that indent if the button set it (`listHang`) and it is still as applied (a hanging indent the paragraph had before, or its style gives, stays). A selection ending right after a return leaves the next paragraph out. One undo step; values equal to the paragraph style's are left to the style.
|
||||
- Define Lists: named numbered lists that continue across stories in page order (`list.define`, paragraph `listName` / `startAt`), round-tripped through IDML; `null` in `type.para` / `type.char` now removes an override.
|
||||
- View › Overprint Preview (⌥⇧⌘Y): overprinting fills, strokes and 100% [Black] text mix with what's beneath on screen.
|
||||
- Type on a Path (⇧T tool, `type.onPath`): a story along any line, curve or shape on screen and in PDF; Type on a Path Options (start, flip, baseline/ascender/descender/centre) and Delete Type from Path. Round-trips through IDML as TextPath; on-path caret drawing is still to come.
|
||||
@@ -453,7 +454,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Based on Parent (`layout.parents.options {parent, basedOn}`): a parent shows its base parent's items under its own, on its pages and on the parent itself; chains work, cycles are refused, and items from any parent in the chain can be overridden. IDML carries it as the parent pages' `AppliedMaster`; a cycle or missing base in a file is cleared with a warning on open. The Pages panel has no Parent Options dialog yet.
|
||||
- Place PDF: placed PDF pages are sized by their crop box, drawn on screen through hayro (with mip levels) and embedded in exported PDFs as vector form XObjects (krilla), `<PDF>` in IDML.
|
||||
- Menus expose the engine's features (TOC, numbering & sections, text variables, hyperlinks, cross-references, footnotes, step and repeat, spelling, fitting/content, effects, Data Merge, Preflight, EPUB); any menu command with parameters gets a dialog generated from its parameter documentation.
|
||||
- Table of contents (Layout ▸ Table of Contents dialog: included styles, per-style entry style, page number position and its character style, separator and its character style, alphabetical sorting and level, title style, Replace Existing; generate/update, dot leaders; the definition round-trips through IDML as a TOC style) and text variables (running headers, last page number, chapter number, file name, dates, custom) resolved per page.
|
||||
- Table of contents (Layout ▸ Table of Contents dialog: included styles, per-style entry style, page number position and its character style, separator and its character style, alphabetical sorting and level, title style, Replace Existing; generate/update, dot leaders; the definition round-trips through IDML as a TOC style) and text variables (running headers, last page number, chapter number, file name, dates, custom) resolved per page; Convert Variable to Text turns the selected instances, or every instance of one variable, into the text they show on their page.
|
||||
- Soft effects: blurred drop shadow, inner shadow, outer glow, basic feather.
|
||||
- ~200 commands, all reachable through the JSON control channel; headless CLI rendering to PNG.
|
||||
- MCP server (`designcraft-cli mcp [--connect PORT]`, docs/mcp.md): headless engine or the running app; commands, batch, document/story inspection, page renders as images, window screenshots, pointer/keyboard/dialog input.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Typography and composition parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-16 · **Change:** minor (Type › Reload Fonts reads fonts installed, edited or removed since start-up (#328, #547); Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate; Justification dialog for the selected paragraphs; anchored objects wrap text; Tabs panel listed as present (#343); character stroke behind fill) · **Target:** Adobe InDesign 2026 (21.6)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-24 · **Change:** minor (Optical Margin Alignment per story with a size in the Story panel, and Ignore Optical Margin in the Paragraph panel menu and paragraph styles, kept through IDML (#947); Type › Reload Fonts reads fonts installed, edited or removed since start-up (#328, #547); Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate; Justification dialog for the selected paragraphs; anchored objects wrap text; Tabs panel listed as present (#343); character stroke behind fill) · **Target:** Adobe InDesign 2026 (21.6)
|
||||
|
||||
Typesetting is what InDesign is bought for. A feature can exist and still set text differently
|
||||
from InDesign: different line breaks, different page count, overset where InDesign fits. This
|
||||
@@ -36,7 +36,7 @@ Fidelity: **unmeasured** unless stated.
|
||||
| Single-line Composer | greedy | greedy with the same ranges | ✓ | |
|
||||
| World-Ready composers | Paragraph / Single-line World-Ready | RTL, Arabic and bidi in the main composer | ~ | Indic scripts (Devanagari etc.) shape through harfrust but are untested |
|
||||
| Justification | word/letter spacing, glyph scaling min/desired/max, single-word, last line | all of these | ✓ | a justified line with a tab justifies after the tab (#284); set per paragraph in Type › Justification… and the Paragraph panel menu (#531) |
|
||||
| Hyphenation | per-language dictionaries (~40), zone, limits, capitalized, last word, across columns | Liang patterns: English (trained from the public-domain Moby list), Spanish (Bezos), Portuguese (hyph-pt), Norwegian (hyph-no) and Greek (hyph-el-monoton); zone, limits, exceptions in the user dictionary | ~ | other languages don't hyphenate (#87 reported "doesn't work") |
|
||||
| Hyphenation | per-language dictionaries (~40), zone, limits, capitalized, last word, across columns | Liang patterns: English (trained from the public-domain Moby list), Spanish (Bezos), Portuguese (hyph-pt), Norwegian (hyph-no) and Greek (hyph-el-monoton); zone, limits, exceptions in the user dictionary; Hyphenate Across Column off keeps automatic hyphens off the last line of a column or frame | ~ | other languages don't hyphenate (#87 reported "doesn't work") |
|
||||
| Spelling | per-language dictionaries | English (Moby) + document/user dictionary | ~ | |
|
||||
| Kerning | Metrics, Optical, manual, none | Metrics, Optical (outline-based: pairs pulled towards the font's stem gap, `crates/compose/src/optical.rs`), manual, none | ~ | Optical is an approximation of Adobe's algorithm (#181), not a match: imported display text can still break differently |
|
||||
| Tracking, scale, skew, baseline shift | ✓ | ✓ | ✓ | |
|
||||
@@ -46,7 +46,7 @@ Fidelity: **unmeasured** unless stated.
|
||||
| Leading | auto (120%), absolute, leading model | ✓ | ✓ | CJK leading models in cjk-typography.md |
|
||||
| First baseline | ascent, cap height, x-height, leading, fixed, min | ✓ | ✓ | |
|
||||
| Frame fit / overset | baseline of the last line must fit | descenders must fit | ~ | **differs** (#180): frames go overset where InDesign fits |
|
||||
| Baseline grid | document and frame grids | ✓ | ✓ | |
|
||||
| Baseline grid | document grid relative to the top of the page or each page's top margin; frame grids relative to the top of the page, top margin, top of frame or top inset | ✓ | ✓ | |
|
||||
| Vertical justification | top, centre, bottom, justify, paragraph spacing limit | ✓ | ✓ | |
|
||||
| Text in shaped frames | lines follow oval, polygon and freeform frame outlines, one inset from the outline | ✓ | ~ | concave shapes set one slot per line (the widest); vertical justification and paragraph shading use the frame's rectangle (#646) |
|
||||
| Columns, span / split columns | ✓ | ✓ | ✓ | split columns within a column (#295); text after a span flows below it (#276) |
|
||||
@@ -58,7 +58,7 @@ Fidelity: **unmeasured** unless stated.
|
||||
| Tabs | left/center/right/decimal/align-on, leaders, right-indent tab | ✓ | ~ | Tabs panel with a ruler over the text column, and a Tabs section in Paragraph Style Options (#343); wrapping of lines with tabs fixed (#282) |
|
||||
| Paragraph rules, borders, shading | ✓ | ✓ | ✓ | |
|
||||
| Balance ragged lines | ✓ | ✓ | ✓ | |
|
||||
| Optical margin alignment | ✓ | ✓ (hang table of our own) | ~ | hang amounts are ours, InDesign's unknown |
|
||||
| Optical margin alignment | per story with a size, Ignore Optical Margin per paragraph and style | ✓ (hang table of our own, scaled by the story's size; Story panel; IDML `StoryPreference`, `IgnoreEdgeAlignment`) | ~ | hang amounts are ours, InDesign's unknown (#947) |
|
||||
| Text wrap | bounding box, shape, jump object/column, wrap sides (text on both sides of an object), contour options, on page items and anchored objects | ✓ | ~ | Detect Edges, Alpha Channel and Photoshop Path contours follow the frame's path (composition doesn't read the image) |
|
||||
| Anchored objects | inline, above line, custom | ✓ | ~ | anchored objects in table cells not drawn (#163) |
|
||||
| Footnotes, endnotes | ✓ | ✓ | ~ | footnotes don't split across columns yet |
|
||||
|
||||
+6
-4
@@ -1,6 +1,6 @@
|
||||
# UI and interaction parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-15 · **Change:** minor (live corners work; document views row: scrollbars, Alt pans while editing text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; paragraph style override feedback and clearing) · **Target:** Adobe InDesign 2026 (21.6, Medium Dark, macOS)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-24 · **Change:** minor (Story panel; text Control panel Character/Paragraph modes; Properties ••• expands Character and Paragraph; live corners work; document views row: scrollbars, Alt pans while editing text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; paragraph style override feedback and clearing) · **Target:** Adobe InDesign 2026 (21.6, Medium Dark, macOS)
|
||||
|
||||
Tools, handles, snapping, nudging, modifiers, shortcuts, panels, menus, context menus and feel,
|
||||
against InDesign 2026. The look was measured from the running app
|
||||
@@ -26,8 +26,8 @@ basics of editing fail for too many users on Windows and Linux.
|
||||
|
||||
| Area | InDesign 2026 | DesignCraft | Status | Evidence |
|
||||
|---|---|---|---|---|
|
||||
| Chrome: app bar, Control panel, Tools panel, dock, doc tabs, status bar | Medium Dark, measured sizes | measured look | ✓ | 11-observed-ui.md |
|
||||
| Properties panel and Contextual Task Bar | per selection | ✓, task bar movable (#143) | ✓ | |
|
||||
| Chrome: app bar, Control panel, Tools panel, dock, doc tabs, status bar | Medium Dark, measured sizes | measured look; the text Control panel switches between Character (A) and Paragraph (¶) Formatting Controls (¶ with the Bulleted and Numbered List buttons, Shading and Border), and Escape in a field reverts what was typed | ✓ | 11-observed-ui.md; Learn Skills Daily course, chapter 16 |
|
||||
| Properties panel and Contextual Task Bar | per selection | ✓, task bar movable (#143); ••• expands Character (scales, baseline shift, skew, language, case and position buttons) and Paragraph (indents, spacing, drop cap, baseline grid, hyphenation) in place | ✓ | Learn Skills Daily course, chapter 16; `properties.rs` `more_options_expand_character_and_paragraph_in_place` |
|
||||
| Selection tool: click, marquee, move, Alt-duplicate, resize handles, rotate from corners | ✓ | ✓ | ✓ | Cmd/Ctrl held with another tool borrows the selection tool used last (Selection or Direct Selection) for one gesture, #919 |
|
||||
| Direct Selection, Pen family, Pencil, Scissors | ✓ | ✓ | ~ | moving reference point "0" fails (#337) |
|
||||
| Live corners (yellow handle) | ✓ | ✓ widget on a selected rectangle frame; diamonds drag the corner size (Shift: one corner), Alt-click steps the shape (Shift+Alt: all) | ✓ | #186 |
|
||||
@@ -47,7 +47,7 @@ basics of editing fail for too many users on Windows and Linux.
|
||||
| Quick Apply | ✓ | ✓ | ✓ | |
|
||||
| Numeric fields: units, arithmetic, scrubbing | ✓ | 21 pt spinner fields with arithmetic | ✓ | |
|
||||
| Colour fields: hex, picker from any swatch field | ✓ | ✓ | ~ | hex entry and picker issues (#323, #190) |
|
||||
| Panels: Pages, Layers, Swatches, Color, Stroke, Character, Paragraph, Styles, Links, Effects, Text Wrap, Align, Pathfinder, Table, Index, TOC, Hyperlinks, Bookmarks, Articles, Tags, Notes, Track Changes, Object States, Buttons and Forms, Preflight, Data Merge, Library, Scripts, Glyphs, Info, Tabs | ✓ | all present | ~ | Navigator, Trap Presets, Animation, Timing missing; pull-down panels can't scroll on Linux (#267) |
|
||||
| Panels: Pages, Layers, Swatches, Color, Stroke, Character, Paragraph, Styles, Links, Effects, Text Wrap, Align, Pathfinder, Table, Index, TOC, Hyperlinks, Bookmarks, Articles, Tags, Notes, Track Changes, Object States, Buttons and Forms, Preflight, Data Merge, Library, Scripts, Glyphs, Info, Tabs, Story | ✓ | all present | ~ | Navigator, Trap Presets, Animation, Timing missing; pull-down panels can't scroll on Linux (#267) |
|
||||
| Dialogs: New Document, Document Setup, Preferences (all pages), Paragraph/Character/Object/Table/Cell Style Options, Export PDF, Print, Package, Find/Change | ✓ | present | ~ | generated command dialogs fill the long tail; depth varies |
|
||||
| Workspaces | Essentials, Essentials Classic, Advanced, Book, Digital Publishing, Interactive for PDF, Printing and Proofing, Review, Typography, Touch | ✓ named workspaces (Essentials Classic: Control panel and iconic panel groups) + custom; Window › Workspace; no Review or Touch | ~ | tab bar overlaps menus in Book/Advanced (#182) |
|
||||
| Story Editor | ✓ | ✓ | ~ | style-name column, depth ruler missing |
|
||||
@@ -122,6 +122,8 @@ covers checking the sampled and redefined settings in the styles tutorial (2:45
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-24 | minor | Panels row: Story panel (Optical Margin Alignment and its size) |
|
||||
| 2026-10-21 | minor | Chrome row: the text Control panel's A/¶ modes; Properties row: ••• expands Character and Paragraph in place |
|
||||
| 2026-10-11 | minor | Live corners row to ✓: widget, diamonds, drag, Shift-drag, Alt-click shape cycling (#186) |
|
||||
| 2026-10-11 | minor | Added held Cmd+Space / Cmd+Alt+Space Zoom navigation and canvas input regression tests |
|
||||
| 2026-10-10 | minor | Threading row corrected to ✗ after checking the code (no out-port interaction, no thread command) |
|
||||
|
||||
Reference in New Issue
Block a user