Roadmap
Each milestone ends with something a calligrapher can use. Items are sized
to become GitHub issues; the labels in brackets suggest who picks them up:
[engine] Rust, [web] front-end, [type] fonts/Python,
[ops] CI/release, [design] UX.
M0 — Foundation ✅ (this hand-over)
- Engine: shaping (HarfRust), bidi, alternates through the shaper, kashida
with style rules, per-glyph offset/scale/rotation, multi-line, alignment,
undo/redo with gestures,
.midad JSON, SVG export.
- Style compiler deriving alternates for Amiri;
naskh-amiri package.
- Web editor (Arabic/English), WebAssembly build, CLI.
- Tauri shell, CI, GitHub Pages deploy, desktop release workflow.
M1 — A dependable editor (≈ 4–6 weeks)
- ✅ [type] Curate the alternates.
midad review tries every alternate in
its position and lists the ones that open a join (with an HTML page of each
case); [alternates.remove] takes them away from one glyph. Done for the
three Naskh styles (52, 45 and 42 shapes removed); the other styles’ reports
are in docs/quality/alternates-review/, waiting for a calligrapher’s
decision. midad specimen shows every letter × position × shape. Whether a
shape is beautiful in its place still needs a calligrapher’s eye.
- ✅ [engine] Structured error codes instead of English strings:
Refusal
({ code, … }), carried to the UI, which says every message in its language.
- ✅ [engine][web] Several letters move and scale together (marquee, Shift),
and words or pieces as blocks.
- ✅ [web] Free transform: the selection’s box scales a word, letters or an
ornament from its corners and turns it from its knob, the box turning with
it (
docs/quality/free-transform/).
- ✅ [web] Harakat picked from the letter’s panel and placed on their own; a
switch for “harakat follow their letters”.
- ✅ [web] Copy SVG to the clipboard; PDF export (vector, written by the
engine: RGB or CMYK, halos as soft masks), and PNG for print at a set DPI.
- ✅ [web] Starter phrases and an empty sheet that invites typing.
- ⚠️ [web] Accessibility pass: every control named (checked in the page),
the sheet is a named, focusable application with a keyboard walk through
the letters (Enter, Tab, arrows, Escape). Not yet tried with a screen
reader.
- ⚠️ [ops] SVG snapshot tests for reference documents
(
crates/midad-core/tests/snapshots.rs); Playwright end-to-end tests not
yet (they need browsers downloaded in CI).
- ⚠️ [ops]
wasm-opt in CI and a size budget: CI installs binaryen and fails
above 2.2 MB. Today 2.15 MB / 0.71 MB gzip before wasm-opt, so the 1.8 MB
goal is not reached; opt-level = "z" saves 6 % but slows composing by
half, so it was not taken.
M2 — Desktop and files (≈ 3–4 weeks)
- ⚠️ [ops] Signed installers and auto-update: wired in the release workflow
and the app (
--features updater), switched on by repository secrets
(docs/RELEASING.md). Needs the project’s signing key and certificates.
- ✅ [engine] File association for
.midad: a double-click opens the
document in the app. Recent files and autosave to disk: not yet.
- ✅ [engine] Batch export: several documents to PDF or PNG in one go (the
print form’s “several documents”, into a folder on the desktop), and
midad batch on the command line.
- ✅ [web] Export for print: PNG at a height in cm and 150/300/600 DPI, PDF
in RGB or CMYK, colours per element.
M3 — Real calligraphy (≈ 8–12 weeks, research-heavy)
- ✅ [engine] Curved kashida: written by the engine’s reed pen between
the two letters, on the sheet and in exports; a style option can ask for
straight ones.
- ✅ [engine] Stacking (تركيب):
[[stacking]] sequence = "لم" with a
step per letter in nuqat, applied after shaping; manual offsets on top;
a piece can switch it off. Placement is by offsets, not anchors, so it
needs a font whose joins meet in that place; no shipped style uses a rule.
- ✅ [type] More styles: 17 style packages (Naskh, Nastaliq, Ruqaa, Thuluth,
Diwani, Kufi, Maghribi…).
- ✅ [type] Alternates that survive a rebuilt font: every alternate is stored
with the fingerprint of its outline (
alternate_shape) and found again by
it, in every font (most fonts here have no glyph names, so names would not
have helped). Building styles from named sources (UFO / Glyphs): not yet.
- ✅ [engine] Per-letter size rules (
[[sizes]]), growing a letter around
its join.
- ✅ [type] Ligatures of the same letters are alternates of each other
(lam-alef forms, mark ligatures) in nine styles.
M4 — Calligraphers as contributors
- ✅ [type][design] Authoring guide for calligraphers, in Arabic:
docs/CALLIGRAPHERS.md (specimen, review, style.toml, build, pull
request). A video: not yet.
- [type] First original style drawn by a calligrapher for Midad (OFL).
- ✅ [web] Style gallery inside the editor (the style menu writes each
style’s name in it, with its credits and license) and as a page
(
midad gallery, docs/gallery.html).
M5 — Reach
- ⚠️ [engine] Publishing:
midad-core has its crates.io metadata and README
(cargo package lists it); publishing it, and the wasm package on npm, is
the maintainers’ call.
- [web] Figma plugin built on the same wasm engine.
- ✅ [design] Templates as
.midad files: seven compositions in
templates/, offered on the empty sheet.
- Optional hosted service (accounts, cloud documents, sharing) in a separate
repository; the editor stays fully usable offline and without an account.
Known limitations (today)
| Limitation |
Where it is tracked |
| Alternates of styles other than Naskh not yet reviewed by a calligrapher |
M1 curation (docs/quality/alternates-review/) |
| Stacking by offsets: fonts without stacked forms show the gap |
M3 stacking |
| One chosen alternate per cluster (no style here puts two glyphs in one cluster) |
M3 |
| Paragraph direction is always RTL |
fine for Arabic; revisit if Latin-only pieces matter |
| Desktop shell not yet built into installers by the team |
first task of M2 |