Commit Graph

386 Commits

Author SHA1 Message Date
Brandon Thomas b05fe0aed4
Merge pull request #78 from ShaoWenbinSaleh/multi-language-fix
Complete Arabic translations, refine Chinese terminology, and cache RTL label layouts
2026-10-07 22:46:52 -04:00
Brandon Thomas 8d2d180062 Merge origin/main into multi-language-fix
Resolve i18n conflicts: keep this branch's revised zh/ar wording plus
main's new rows (font-name, missing-glyph, Korean line-break labels).
Brazilian Portuguese (#103) now uses the same cached HashMap lookup as
Arabic; the cached-lookup test covers pt-br too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:32:13 -04:00
Brandon Thomas 8e2a5b1fc3
Merge pull request #55 from EthanSuquet/fix/cmyk-tiff-pdf-export
PDF: placed CMYK TIFFs keep their inks
2026-10-07 22:13:56 -04:00
Brandon Thomas 2c8ea6d167 Merge remote-tracking branch 'origin/main' into r55
# Conflicts:
#	Cargo.toml
2026-10-07 22:13:23 -04:00
Brandon Thomas e97d98977f
Merge pull request #103 from RicSchonfelder/i18n-pt-br
i18n: add Brazilian Portuguese (pt-br) UI translation
2026-10-07 22:13:15 -04:00
Brandon Thomas 9f2f61bfbf
Merge pull request #82 from aiongg/fix/psd-channels
Images: PSD composites decode by colour mode
2026-10-07 22:13:10 -04:00
Brandon Thomas 84f2eadb39 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:05 -04:00
Brandon Thomas a39c8893b9 Merge remote-tracking branch 'origin/main' into fix/cmyk-tiff-pdf-export
# Conflicts:
#	crates/pdf/Cargo.toml
#	crates/pdf/src/tests.rs
2026-10-07 22:05:52 -04:00
Brandon Thomas 1c2aa451cf
Merge pull request #85 from aiongg/feat/cjk-and-fonts
CJK: language-aware shaping and fallback, vertical metrics, document fonts, missing-glyph boxes (builds on #75)
2026-10-07 22:05:01 -04:00
Brandon Thomas aee756d604 Merge remote-tracking branch 'origin/main' into feat/cjk-and-fonts
# Conflicts:
#	crates/ui-egui/Cargo.toml
2026-10-07 22:04:42 -04:00
Brandon Thomas 625e6b0e01
Merge pull request #58 from EthanSuquet/feat/pdfx4-flag-rgb-under-cmyk-intent
PDF/X-4: flag device RGB under the CMYK output intent
2026-10-07 22:04:21 -04:00
Brandon Thomas dd8d3037b1
Merge pull request #75 from ShaoWenbinSaleh/arabic-chinese-typesetting-rules-fix
Preserve and compose Chinese and Arabic typesetting rules
2026-10-07 22:04:16 -04:00
Brandon Thomas 27909c6cbb
Merge pull request #66 from Luskish/fix/control-close-on-malformed-input
Control: close the connection on input that isn't a request
2026-10-07 22:04:11 -04:00
Brandon Thomas feb3808029
Merge pull request #56 from storybored379/fix/guide-layer-locks
Guides: honor layer protection in move and delete commands
2026-10-07 22:04:06 -04:00
Brandon Thomas 864d0b6008
Merge pull request #53 from epfabian/middle-mouse-pan
Canvas: middle-mouse drag pans the view
2026-10-07 22:04:01 -04:00
Brandon Thomas a42bd84e89
Merge pull request #79 from aiongg/fix/34-transform-dialogs
Transform: Rotate and Shear open their dialogs (#34)
2026-10-07 22:03:56 -04:00
Brandon Thomas 3b8a58fcc4
Merge pull request #97 from denizkoekden/feat/office-fonts-macos
Fonts: read Microsoft Office's bundled fonts on macOS
2026-10-07 22:03:51 -04:00
Brandon Thomas 45866e6037
Merge pull request #101 from skylartaylor/fix/idml-packaged-link-resolution
IDML: resolve nested packaged image links after relocation
2026-10-07 22:03:46 -04:00
Brandon Thomas 8d828f6efb
Merge pull request #104 from skylartaylor/fix/render-outside-stroke
Render: keep outside-aligned strokes out of closed interiors
2026-10-07 22:03:41 -04:00
Brandon Thomas 08b6e335dd
Merge pull request #102 from skylartaylor/fix/idml-cell-edge-priority
IDML: honor explicit cell edges at table borders
2026-10-07 22:03:36 -04:00
Brandon Thomas fd0e801968
Merge pull request #105 from skylartaylor/fix/idml-scalar-inset-spacing
IDML: import scalar InsetSpacing property values
2026-10-07 22:03:31 -04:00
Brandon Thomas fdffbb4b23 M9: distinct zh label for Revert; translations are our own
Revert no longer shares Undo's Simplified Chinese label. Drop the
comments and ROADMAP wording that tied terminology to a vendor's help.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:01:57 -04:00
Brandon Thomas 330b8c18f2 Images: PSD checks the image data is present before allocating
Header dimensions are untrusted: a tiny file claiming a ~460 MiB composite
allocated it before finding the data missing. ImageData::holds verifies
raw planes fit in the data, or that RLE row counts each reach a full row
and sum to no more than the data, before the RGBA buffer is allocated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:59:39 -04:00
Brandon Thomas 211589a80a 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:54:59 -04:00
Brandon Thomas a79351e249 Glyph outlines: minimal boolean form (clippy 1.96 nonminimal_bool)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:49:48 -04:00
Brandon Thomas 730d598d48 Kinsoku::allows: minimal boolean form (clippy 1.96 nonminimal_bool)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:48:33 -04:00
Brandon Thomas 927191d25f
About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#108)
* 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>
2026-10-07 21:16:42 -04:00
skylar taylor-barrick 0629137ef7 IDML: import scalar InsetSpacing property values 2026-10-07 16:10:32 -06:00
skylar taylor-barrick 4910e42bcc Render: keep outside-aligned strokes out of closed interiors 2026-10-07 16:10:24 -06:00
RicSchonfelder bd8291c55f i18n: add Brazilian Portuguese (pt-br) UI translation
Registers pt-br in the interface-language menu (Edit › Interface
Language) with a dedicated pt_br.rs catalog mirroring the ar.rs
pattern: 1005 (en, pt-br) pairs covering the same key set, with the
'pt-br' dispatch added to i18n::tr and the translation test extended.
2026-10-07 17:43:34 -03:00
skylar taylor-barrick 0f888ef794 IDML: honor explicit cell edges at table borders 2026-10-07 14:38:40 -06:00
skylar taylor-barrick 089b1ac28f IDML: resolve nested packaged image links after relocation 2026-10-07 14:27:50 -06:00
Deniz Kökden 2a3b3e6661 Fonts: read Microsoft Office's bundled fonts on macOS 2026-10-07 21:23:57 +02:00
Brandon Thomas f17397c305
Rename PrintCraft to PdfCraft (storytold/pdfcraft) (#95)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:55:09 -04:00
aiongg 2866f617a7 UI: font menu previews draw upright
text_line flipped glyph outlines that the font database already gives
y-down, so each family's preview in the font menu was drawn upside down
below its baseline and cut off at the bottom of the image.
2026-10-07 10:44:46 -04:00
aiongg 99f1e653f2 Text: locale-coded language names (de_DE_2006) get their language
IDML names some languages by locale code
(AppliedLanguage="$ID/de_DE_2006", "$ID/nl_NL_2005") beside names such
as "English: USA" and "Spanish: Castilian". language_tag maps any locale
code (ll, ll_CC, ll-CC, with a reform year after them) to its BCP 47 tag
(de-DE, nl-NL; kept once per process, at most 512 distinct tags), ignores
IDML's $ID/ prefix, and knows Spanish: Castilian (es-ES) and Swiss French
and Italian. The stored name stays as written, so IDML round trips are
unchanged.

What depends on the language now goes by the tag: typographer's quotes
(by language subtag; Swiss regions take guillemets), English
hyphenation and spelling (is_english), Korean word breaking and the CJK
fallback chains (ja-JP, ko-KR are Japanese and Korean whatever the
region).
2026-10-07 10:44:46 -04:00
aiongg c64e538de5 UI: the font menu groups fonts by script, CJK fonts by language
Font menus list Western (and other-script) families first, then
Japanese, Simplified Chinese, Traditional Chinese and Korean families,
each group alphabetical by the name shown, with a separator between
groups. The group comes from the font's own data, strongest signal
first: the meta table's dlng (else slng) languages, family names in a
CJK language (Windows and Macintosh language IDs), OS/2 code pages (JIS,
Chinese Simplified, Korean Wansung, Chinese Traditional, Korean Johab);
a font declaring none of these goes by what it covers (kana, Hangul,
ideographs). Ties go Japanese, Simplified, Traditional, Korean. Loaded faces are classified
once; installed fonts by the font scan, which also reads their OS/2 and
meta tables (and cmap only for fonts declaring nothing), capped.

CJK families show their family name in their language, the English
name on hover; Preferences > Type > Show Font Names in English
(prefs.set {showFontNamesInEnglish}, off by default) shows English
names. Search matches either name; documents store the English name.
The Character panel, Control bar, Properties, style dialogs, Find Font
and Glyphs panel lists all follow this order. The main font menu stays
open while searching or starring (it closed on any click inside).

Font previews don't draw DesignCraft's missing-glyph box for fonts
whose .notdef is empty.
2026-10-07 10:44:46 -04:00
aiongg 1ef187ad02 Text: missing glyphs show as boxes
A character the applied font lacks is drawn as that font's missing-glyph
box (its .notdef, gid 0), on screen and in PDF, and Preflight lists the
characters by font ("Missing glyphs in <family> <style>: …", an error,
at most 20 named). A .notdef without an outline is drawn as a hollow box
across its advance, so a missing character never disappears. PDF draws
.notdef glyphs as paths, which PDF/A and PDF/UA accept. Kenten marks are
set in their text's font the same way.

The document setting Draw Missing Glyphs from Fallback Fonts
(DocSettings::glyph_fallback; Preferences > Composition,
document.preferences {glyphFallback}, undoable) draws them from fallback
fonts instead (the language-aware chains, then any font; kenten marks
from a fallback font, else a bullet). It is off in new documents and
IDML imports and on in files saved before it existed, which keep
drawing as they did. A missing font's substitute always uses fallback
fonts. The composition cache's signature includes the setting. Tests
whose Arabic comes from a fallback font turn the setting on.
2026-10-07 10:44:46 -04:00
aiongg a08198e139 CJK 1.11: Chinese language names in their common spellings
language_tag ignores case and punctuation and recognises Chinese in its
common spellings and locale codes (Simplified Chinese, Chinese
(Simplified), zh_CN, zh-Hans; Traditional Chinese, zh_TW, zh_HK,
zh-Hant), and Japanese and Korean locale codes (ja_JP, ko_KR).
Typographer's quotes for Chinese and Japanese follow the tag, so every
spelling takes the same quotes. IDML import keeps the name as written.
2026-10-07 10:44:46 -04:00
aiongg 76c0b79760 CJK 1.10: Package copies the fallback fonts that draw text
Composition draws the characters a named font lacks with fallback faces
(the language's CJK chain, then the generic fallbacks). Package now also
copies their font files: it collects the distinct faces of the visible
glyphs of every composed story (table cells and footnotes included) and
copies those that aren't a named font's face by the same rules (restricted
licence listed, bundled included with DesignCraft, no file noted, each file
once). The report lists them under Fallback fonts.
2026-10-07 10:44:46 -04:00
aiongg 5f52150b31 CJK 1.9: document fonts belong to their document
The fonts in a document's Document Fonts folder are registered under a
font scope that the document holds while it is open (Document::font_scope,
runtime only; DocState keeps the scope alive and closes it when the last
copy of the state goes: file.close, closing a tab, revert, a book
chapter's export, the session ending). Composition, preflight, font.list,
Package and the font menus, Glyphs panel and previews look fonts up
through FontDb::scoped(scope): the document's own faces first, then the
shared ones. Other open documents don't see them, and two documents with
fonts of the same name each set text in their own. Composite fonts'
member fonts and the fallback for kenten marks are looked up the same
way.

Font files stay in memory for the session (FaceRef keeps faces for the
process); a document opened again reuses the faces of its unchanged files
(same path, length and modification time) instead of reading them again.
The composition cache's signature includes the scope; the word cache and
the outline and PDF font caches are keyed by face. Variable font
instances are kept per base face.

A family's installed faces join the shared fonts all at once, and a
face two lookups load at the same time is kept once, so a parallel
fallback lookup never takes a family's bold before its regular has
loaded.
2026-10-07 10:44:46 -04:00
aiongg e6e843dc26 CJK 1.8: arrow keys follow vertical lines
In vertical text Down and Up move along the line by a character (by a
word with Alt), Left and Right to the next and previous line keeping the
position along it, and Shift extends, as the arrows do in horizontal
text turned a quarter. The caret is a bar across the vertical line.
2026-10-07 10:44:46 -04:00
aiongg 6df33fa344 CJK 1.7: story direction belongs to the story
Vertical is a story property: every frame of a thread is vertical or
horizontal together, a frame threaded onto a story takes its direction,
and frames split off by threading or breaking a thread keep theirs.
Type > Story Direction is type.storyDirection {vertical} (checked in the
menu) for the stories of the text selection or selected frames;
object.textFrameOptions {vertical} and frame.create {vertical} set the
frames' stories. Documents that stored Vertical on the frame open with
each story taking its first frame's direction. IDML StoryOrientation is
read into and written from the story, beside its column direction
(StoryDirection), which stays a separate setting.
2026-10-07 10:44:46 -04:00
aiongg 1574dcdd45 CJK 1.6: upright text is shaped top to bottom
In vertical frames upright runs are shaped TopToBottom (vert; vkrn/vpal
when asked), advance by their vertical metrics and hang from their
vertical origins on the em box centre, on screen and in PDF; their line
ascent and descent are the em box. Turned runs stay horizontal without
vrt2 (rather than every run taking vert and vrt2), and tate-chu-yoko
stays horizontal and centres on the em box, its offsets moving it along
and across the line. Horizontal Kana in upright runs takes vkna. Each
run is shaped with the text around it, as horizontal runs are.
2026-10-07 09:33:52 -04:00
aiongg 1602b37ec9 CJK 1.5: fonts read vertical metrics
FontFace::v_advance, v_origin and em_box read vmtx/vhea, VORG (else the
glyph top plus its top side bearing) and the ideographic em box (BASE
ideo/idtp, else OS/2 typo metrics, else ascender/descender, centred on one
em); fonts without them fall back to the em box. shape_vertical shapes
top to bottom with those metrics (vert, and vkrn/vpal when asked).
2026-10-07 09:33:52 -04:00
aiongg e0fb78a230 CJK 1.4: Korean breaks at spaces
Korean is set word by word (KLREQ): Hangul, in any language, and Han
ideographs in Korean-language text take no line breaks between
characters, so lines break at spaces. Glyphs carry their language tag
for this. A paragraph attribute, koreanCharBreaks (type.para, paragraph
styles, Paragraph Style Options > Justification), breaks between
syllables instead. It is DesignCraft-only; IDML doesn't carry it.
A paragraph's kinsoku set decides which breaks it forbids, and Korean
still breaks at spaces under one.

Kinsoku still holds, also when the single-line composer has to split a
word wider than the measure: the split moves back so no line starts
with closing punctuation.
2026-10-07 09:33:52 -04:00
aiongg 832939691c CJK 1.3: documents bring their own fonts
Opening a .designcraft or .idml file from disk (file.open, file.openIdml,
book chapters, recovered documents) loads the fonts in the "Document
Fonts" folder beside it. Their faces come before installed faces of the
same family and style. The files are untrusted: at most 200 are read,
256 MB each (full CJK collections fit) and 512 MB in all; files over a
limit by their listed length are skipped unread, and damaged, oversized
and surplus files are listed in the open result's warnings. Document fonts stay
loaded for the session (the font database is process-wide).

Faces record their source (bundled, installed file, document file,
memory); font.list reports it. File > Package copies the font files the
document uses into the package's Document Fonts folder unless OS/2
fsType restricts the licence, and the report says which fonts weren't
copied and why.
2026-10-07 09:33:52 -04:00
aiongg 2da99b70e2 CJK 1.2: font fallback follows the language
Characters the primary font lacks try a fallback chain by language
before the language-blind search: Japanese (the craft-fonts Japanese
faces first, Mincho first), Simplified Chinese (also plain Chinese),
Traditional Chinese and Korean each list their macOS, Windows and Linux
system families. Hangul, kana and Bopomofo pick their language's chain
whatever the character language; ideographs and CJK punctuation follow
it, and keep today's fallback without a CJK language. Chain families
load from the system font catalog the first time they are needed.

designcraft_fonts::testing (feature `testing`) builds synthetic fonts
with a given family name and coverage for tests.
2026-10-07 09:33:51 -04:00
aiongg 2a516761ef CJK 1.1: the character language reaches the shaper
The character's language (as IDML names it) maps to a BCP 47 tag
(designcraft_doc::language_tag) and is the shaping context's language
on the harfrust buffer, so OpenType locl applies for every language in
the list (Japanese, Chinese, Korean, Turkish, ...), not only Arabic,
Persian, Urdu, Hebrew and English: other names used to reach the
shaper as they were written, which it doesn't know, so their locl never
applied. designcraft_fonts no longer maps names itself. The word-shaping
cache is keyed by the tag. Chinese: Simplified and Chinese: Traditional
join the language list (plain Chinese stays, tagged zh); Simplified
Chinese takes curly quotes, Traditional Chinese corner brackets.
2026-10-07 09:33:40 -04:00
aiongg d6a67bdcd1 CJK: plan for the East Asian feature set
Phased plan for professional CJK typesetting (the East Asian feature set):
sources (JLREQ, CLREQ, KLREQ, JIS X 4051, OpenType, IDML), current state
and known bugs, architecture (character classes, mojikumi, kinsoku and the
Japanese composer, vertical metrics, annotations, grids, composite fonts),
IDML attributes, phases with estimates and open decisions. It builds on
the CJK composition of docs/cjk-typography.md (composite fonts, kinsoku
sets, aki, tsume, jidori, hanging punctuation, em alignment and leading
models, kenten characters, tate-chu-yoko offsets) and plans what remains.
2026-10-07 09:25:17 -04:00