* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)
Adds the craftrules standard (standards/contributors.md) to Help > About DesignCraft, which now
has tabs About · Contributors · Models (`help.about {tab}` selects one).
contributors/contributors.json is generated by craftrules/scripts/contributors.py and baked
into the binary by crates/ui-egui/build.rs as static tables (crates/ui-egui/src/credits.rs).
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 @.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Contributors docs: craftrules is two levels up (../../craftrules)
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>
Port the CJK1 and AR1 changes from 3ecdb78 and de83cdc onto current main. Resolve translation and font-stack conflicts by retaining main localization and craft-fonts integration while preserving all typesetting code, tests, and documentation.
Validation: all six CI gates passed, including 616 tests and WASM checks.
Scale: a small square grown into a larger one from their shared corner,
with a diagonal arrow. Shear: a rectangle slanted into a parallelogram
along its base, with an arrow. Both are drawn in code in the icon set's
stroke weight; Free Transform keeps its drawing.
A parameter written as `key (description)` was dropped by the command
form parser, so Object › Transform › Rotate… and Shear… (and Basic
Feather) had no required field, opened no dialog and ran with defaults.
The key is now the leading word and the parenthetical becomes its hint.
Double-clicking the Selection, Rotate, Scale or Shear tool opens Move,
Rotate, Scale or Shear.
check_pdfx4 didn't look at colour spaces, so a placed RGB PNG (or a CMYK
TIFF converted to RGB, #35) went into a PDF/X-4 file as DeviceRGB under the
CMYK output intent with an empty warnings list. PDF/X-4 lets RGB in only
when it is colour-managed: ICCBased, or DeviceRGB remapped by a DefaultRGB
colour space. DeviceCMYK and DeviceGray are the intent's own values.
The check now reads the file with hayro-syntax and, when the PDF/X output
intent's profile has four channels, walks each page: its content, the
images, forms (placed PDFs), patterns, shadings and soft masks it uses, and
the transparency groups. It reports DeviceRGB (or Indexed over it) images
with their object number and pixel size, RGB fills and strokes, RGB
gradients, RGB inline images and groups blending in RGB, each with the pages
it is on, unless a DefaultRGB is in scope. Like the other PDF/X findings
these are export warnings. The separate "some transparency groups still
blend in RGB" warning is gone: the group check covers it, with the page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Noto Sans CJK SC and Noto Sans Arabic now live in storytold/craft-fonts
(byte-identical to upstream); the UI picks them up by script (Hans,
Arab) from CRAFT_FONTS, Chinese forms first in the zh interface, and
the fonts reinstall when the interface language changes.
- Rebased onto main: zh column for the vertical-type and smart-guide
rows added since; duplicate rows removed; ROADMAP merged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extend interface language selection with Chinese and Arabic translations
across menus, dialogs, panels, tooltips, and common application controls.
Keep English fallback for untranslated strings, return borrowed translation
text, and validate translation key uniqueness and language switching.
Bundle redistributable Noto CJK and Arabic fonts with OFL license files and
ASSETS.md attribution so native and WASM builds have portable glyph coverage.
Register Arabic regular and semibold families while retaining existing font
fallbacks for proportional and monospace controls.
Render Arabic labels using Unicode bidirectional runs and contextual shaping.
Wrap logical text at grapheme boundaries before ordering each visual line,
mirror neutral punctuation, preserve logical source text for accessibility,
and handle truncation, empty lines, and mixed Latin text and numbers. Keep
ASCII labels on the normal rendering path. Disable selection on shaped RTL
labels because egui's default label cursor mapping assumes LTR text.
Adapt welcome controls, menu ordering, popup alignment, and new-document rows
for RTL layout. Bound popup geometry and avoid unsupported RTL grid behavior;
keep numeric inputs LTR. Isolate user-provided document names from Latin
application and zoom metadata. Interface language changes leave document
binding, paragraph direction, editable text, and engine state unchanged.
Add regressions for contextual Arabic joining, bidirectional punctuation,
mixed document names, logical wrapping, truncation, language switching, and
finite widget geometry. Update the roadmap with localization coverage.
Apply equivalent chunk-iteration and PDF Option/borrow simplifications needed
by the current Rust toolchain's strict Clippy checks.
Validation:
- cargo xtask ci: fmt, Clippy, native tests, assets, and layers passed;
native tests total 517 passed and 2 ignored.
- UI regression suite: 26 passed.
- Headless UI screenshots verified Arabic welcome/new-document creation,
menus, mixed-script document names, and switching back to Chinese/English.
- Default WASM gate is blocked by this host's missing precompiled wasm32
standard library. All 15 WASM crates pass using the installed Rust sources:
RUSTC_BOOTSTRAP=1 CARGO_UNSTABLE_BUILD_STD=std,panic_abort
target/debug/xtask wasm.
Dragging with the middle mouse button pans the canvas with any tool, like
Space-drag, and shows the grabbing hand. Tools still only see the primary
button. ui.click / ui.drag accept "button": "middle".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shippori Mincho (8.7 MB) and its licence leave assets/fonts. Japanese fonts now
come from storytold/craft-fonts when built with CRAFT_FONTS_DIR (never a
Cargo.toml dependency): crates/fonts/build.rs embeds its manifest as
designcraft_fonts::CRAFT_FONTS. Native builds embed all four fonts; wasm32
embeds BIZ UDPGothic Regular only (web size budget).
- UI (egui): the Jpan faces at the end of every family, BIZ UDPGothic first
(Bold first in the semibold family).
- Documents: FontDb loads them after the bundled fonts, Mincho first, so they
are the Japanese fallback ahead of system fonts; SVG text gets them too.
- Vertical alternates test runs on every craft-fonts face and skips when
CRAFT_FONTS is empty; new UI no-tofu test and without-craft-fonts tests.
- FreeBSD CI tests with craft-fonts; release.yml builds every platform with
CRAFT_FONTS_DIR + CRAFT_FONTS_REQUIRED=1 at a pinned commit, packages carry
OFL-<family>.txt; NOTICE, ASSETS.md, AGENTS.md/CLAUDE.md, README, ROADMAP.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- view.snapPreferences {alignEdges, alignCenters, smartDimensions,
smartSpacing, zone} sets the smart guide options; the Preferences
dialog goes through it, so the control channel and MCP reach them.
- Smart guide, gap and measurement colours come from theme::Tokens.
- Remove the unused closest-target helper (snap_rect and friends).
- Drop the agent planning docs (docs/superpowers) and the .worktrees
ignore line; ROADMAP entry for smart guides and snapping.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shift plus Alt restores the aspect from the original center after the size snaps. A line keeps the runner delta on both axes. Dimension guides are redrawn on the committed side. Grouped own size decomposes the absolute transform once.
FontDb cataloged the system fonts only when a character needed a fallback
(nothing else calls load_system_fonts), so a document set in an installed
family was composed in Source Sans 3, and font.list and preflight reported
the family missing (#22).
Every lookup by family name now waits for one scan of the font folders per
session, as VectorCraft does since #130: the app starts the scan in the
background at startup, other processes run it on first use. The scan reads
only each file's table directory and name table, and skips folders it has
already read, so a symlink loop can't hang it. has_family counts installed
families. FontDb::with_font_dirs and system_font_dirs let tests use their
own font folder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
preflight.run measured every placed graphic's "pixels", which for a PDF or
SVG is only the size of its screen preview, so a vector logo placed at its
own size was reported as low resolution:
{"kind": "lowResolution", "message": "logo.pdf: effective 72 ppi (< 150)", "severity": "warning"}
Placed PDF and SVG pages export as vectors; the effective-resolution check
now applies to raster images only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CMYK rewrite matches krilla's exact output; if that ever changes,
the export says so instead of silently writing RGB groups.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
krilla gives every transparency group it writes a DeviceRGB blending space,
including the group around a placed PDF page:
/Group<</Type/Group/S/Transparency/I true/CS/DeviceRGB>>
A print file therefore carried DeviceRGB (forbidden by PDF/X-4 under a CMYK
output intent) and blended CMYK art through RGB: a placed logo's black,
C91 M78 Y61 K97 in its own file, printed as C72 M67 Y67 K88. When the
document's transparency blend space is CMYK (the default for print) or the
export is PDF/X-4, the groups are rewritten to /CS/DeviceCMYK in place and
at the same length (the optional /Type/Group gives the room, the rest is
padded with spaces), only inside object dictionaries found through the
cross-reference table, so every offset stays valid. Booklets get the same.
Books merged by merge_pdfs are not covered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A PDF/X-4 export (PDF 1.6) of a page with a placed PDF 1.7 (VectorCraft's
default, and most tools') failed at the very end with
designcraft-cli: PDF writer error: Pdf(PdfDocument(PdfDocumentRepr { .. }), VersionMismatch(Pdf17), None)
krilla refuses to embed a PDF newer than the file it writes. PDF 1.7 changed
nothing in how a page draws, so a 1.7 file now goes in as 1.6 (its header
relabelled, as qpdf --force-version=1.6 does) with a warning. A PDF 2.0
file, or one whose catalog declares 1.7, fails the export with a message
naming it. hayro-syntax moves from dev-dependencies to dependencies (krilla
already builds it) because the check names its PdfVersion.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>