68 Commits
Author SHA1 Message Date
moppeeer ed6bcae877 Merge remote-tracking branch 'origin/main' into codex/gradient-cmyk-blend 2026-10-14 09:12:51 +02:00
Brandon Thomas 43a46c04bf Merge PR #843 2026-10-14 01:54:43 -04:00
0f4f382b0e feat(text): improve editing, snapping, and threading
Add multi-click text selection, pending caret formatting and clipboard support, text-aware colour controls, guide/grid snapping, and frame threading with loaded-port interactions.

Include the layout, drop-cap and IDML updates carried from #83, with safeguards for generated and linked stories, external text references, local IDs, locked frames and atomic colour edits.

Fixes #23.

Co-authored-by: Sean Hammond <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 21:41:46 -06:00
dotCooCoo 7a89954937 Placed PDFs: render with pdfcraft's patched hayro crates
Placed PDFs rendered through hayro 0.7 from crates.io, whose
hayro-interpret divides integers in calculator functions without a
check, does not limit how deep functions nest and samples each mesh
triangle over its whole bounding box. A placed PDF whose calculator
function runs `1 0 idiv` or `-2147483648 -1 idiv` panicked the render.
A chain of 100,000 functions, each stitching function naming the next,
overflowed the stack and aborted the process. Mesh shadings with points
far off the page, ten thousand overlapping triangles or forty thousand
patches ran for over a minute or passed 2 GiB of memory.

[patch.crates-io] now takes hayro, hayro-interpret, hayro-syntax and
hayro-jbig2 from pdfcraft's vendor/ directory at b5467d93, with the
patches its vendor/README.md lists. The crate versions do not change.
The patched hayro-syntax sizes a page with a /UserUnit in points, and
pdf_page_box scales the page's boxes by the same unit, so with Crop to
the frame still shows the chosen box. NOTICE names the new source and
the licenses. The function and mesh tests in
crates/render/tests/placed_pdf.rs follow pdfcraft's tests in
crates/render/src/raster.rs.
2026-10-13 12:52:10 -07:00
moppeeerandClaude Opus 5.5 dc712baeca fix(color): gradients between process colours blend as inks, as InDesign shows them
LYH Studio episode 6 builds every gradient from C=0 M=100 Y=0 K=0 to
C=100 M=0 Y=0 K=0. InDesign blends a gradient's process stops as inks:
halfway is C 50 M 50, a light lilac. DesignCraft converted both ends to
RGB and blended there, so the middle came out a darker violet (117, 88,
189 instead of 135, 119, 181), and every Episode 6 gradient looked
different. A midpoint between CMYK stops also became an RGB colour, so
the PDF shading turned RGB with a conversion warning.

- color: `Color::lerp` blends CMYK with CMYK (or grey), and grey with
  grey, in ink space; anything with RGB still blends in RGB.
- `Gradient::display_stops`: the expanded stops plus samples through
  each span that isn't RGB at both ends, for renderers that interpolate
  in RGB; the screen renderer uses it.
- pdf: a midpoint's expanded stop now keeps the stops' space; the
  colour-space test expects no conversion for CMYK or grey midpoints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 20:38:38 +02:00
moppeeerandClaude Opus 5.5 1dc33dd280 fix(render): One underline bar per stretch of text, no seams
The canvas drew an underline (and a strikethrough) as one rectangle per
glyph; where two anti-aliased edges met at a fractional pixel they left
a lighter seam between the letters. Contiguous bars of the same colour
and position are merged into one, as the PDF export already does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 18:29:09 +02:00
seanth a21e8db14f fix(compose): key parent-page compositions by absolute page index
Parent-page text now uses the absolute page index as its cache key, so repeated page numbers and renumbering do not reuse another page's composition.

Validation: targeted canvas and PDF regressions, plus all six cargo xtask ci gates on main after #514 (1,179 native tests passed, 3 ignored; 15 crates passed WASM compilation checks).

Task: #523
2026-10-11 21:27:52 -06:00
japbcoelhoandClaude Opus 5.5 3dc0a1563a Place: PDF pages and SVGs keep their exact size (#511)
file.place sized a placed PDF page (and SVG) from its size rounded to
whole points, while the export draws the page into that size: a page of
91.774 x 613.276 pt became 92 x 613 and was drawn 0.25 % wider and
0.3 % shorter, so pieces laid edge to edge left gaps of up to 1.9 pt.
A 100.4 x 50.4 pt page placed 100.4 pt wide came out 50.2 pt tall:
`Rect { x0: 0.0, y0: 0.0, x1: 100.4, y1: 50.2 }`.

The graphic's natural size is now the exact page (crop box) or SVG size;
the rounded pixel size stays for display and preflight. place.load (the
place cursor) gets the same exact size.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-11 17:39:40 -06:00
d0d4812ada Set a text selection as warichu inside the parent line (#280)
* Set warichu as smaller lines inside the parent line.

Type › Warichu stacks the selected run after the line is broken, closes up the rest of the line, and round-trips the IDML warichu properties. The line break itself still sees the full-size run.

* Keep clicks, the caret, and Up/Down on each warichu row.

The glyphs were already stacked inside the parent line, but hit testing, the caret, and vertical movement still used that parent line. Break minimums, row widths, spacing, and tab leaders now follow the small lines, and underlines sit on the small baseline.

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 03:47:14 -04:00
skylar taylor-barrick 452134c13b FID2: preserve decoration color resets, geometry and paint order (#230) 2026-10-10 01:50:52 -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 ThomasandClaude Opus 5.5 a79351e249 Glyph outlines: minimal boolean form (clippy 1.96 nonminimal_bool)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 21:49:48 -04:00
skylar taylor-barrick 4910e42bcc Render: keep outside-aligned strokes out of closed interiors 2026-10-07 16:10:24 -06: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 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 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 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
Brandon ThomasandClaude Opus 5.5 82d6def80b Never crash: render and pdf
Rasters stay below vello_cpu's u16 limits (a 65535-pixel-wide render
panicked inside it), page renders larger than 2^29 pixels decline instead of
allocating, PNG encoding never panics, and the PDF heading tag can't fail.
Both crates deny the panicking lints.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 12:43:33 -04:00
Brandon ThomasandClaude Opus 5.5 8490965e71 CI: fix new Rust 1.99 clippy lints (as_chunks, ?, redundant ref)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:37:09 -04:00
Brandon ThomasandClaude Opus 5.5 558e798dfc E: CMYK transparency blend space on screen
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 02:09:26 -04:00
Brandon ThomasandClaude Opus 5.5 fe40d4b80b T: tate-chu-yoko in vertical frames
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 00:46:52 -04:00
Brandon ThomasandClaude Opus 5.5 b13135472a V: Rotate Spread per spread — canvas layout through per-spread transforms
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 00:25:16 -04:00
Brandon ThomasandClaude Opus 5.5 7b636fb9f5 C: separations from source colours
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 23:54:54 -04:00
Brandon ThomasandClaude Opus 5.5 dc2114be26 I: PDF form fields — text, check box, combo, list, signature
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 10:48:58 -04:00
Brandon ThomasandClaude Opus 5.5 55af964ea8 X: inline XML tagging and tag markers
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 10:48:58 -04:00
Brandon ThomasandClaude Opus 5.5 84d8f498eb E: Directional Feather
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 08:55:15 -04:00
Brandon ThomasandClaude Opus 5.5 9ecd3fb9fd E: Inner Glow, Bevel and Emboss, Satin; soft effects kept in PDF export
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 08:50:43 -04:00
Brandon ThomasandClaude Opus 5.5 37f0cd99e1 P: Object Layer Options for placed PDFs
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 08:38:23 -04:00
Brandon ThomasandClaude Opus 5.5 77fc006b02 T: vertical type — Vertical Type tool, upright CJK, CJK line breaking
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 08:18:14 -04:00
Brandon ThomasandClaude Opus 5.5 fb747c5fa5 C: Color Settings, Proof Setup and Proof Colors
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 07:44:40 -04:00
Brandon ThomasandClaude Opus 5.5 839887eb04 I: video and sound — media frames, posters, EPUB players (+ Media panel)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 05:20:35 -04:00
Brandon ThomasandClaude Opus 5.5 08495e45d0 T: graphic cells — images in table cells
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 04:30:47 -04:00
Brandon ThomasandClaude Opus 5.5 3fc38549d4 I: Object States — multi-state objects (+ panel)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 04:08:35 -04:00
Brandon ThomasandClaude Opus 5.5 a4e76ed620 T: Track Changes — marked insertions and deletions, accept/reject all
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 03:57:22 -04:00
Brandon ThomasandClaude Opus 5.5 adb054df46 V: Separations Preview and ink limit view
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 03:43:22 -04:00
Brandon ThomasandClaude Opus 5.5 ba95a6f900 F: stroke styles — stripes, wavy, hash drawn (screen + PDF); named custom styles (+ IDML)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 02:39:39 -04:00
Brandon ThomasandClaude Opus 5.5 10dd488e72 H: Image Import Options — crop placed PDFs to trim/bleed/art/media box
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 02:23:41 -04:00
Brandon ThomasandClaude Opus 5.5 c9785ae1ed U: Font menu with search, favourites and previews; persist engine preferences
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 00:27:52 -04:00
Brandon ThomasandClaude Opus 5.5 2f54f0b53d O: Frame Fitting Options — auto-fit on resize, align from, crop (+ dialog, IDML)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 00:14:47 -04:00
Brandon ThomasandClaude Opus 5.5 eb2e8d8b4f C: Appearance of Black — output rich black, Overprint [Black] at 100%
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 23:51:51 -04:00
Brandon ThomasandClaude Opus 5.5 3b462285c5 T: editorial notes — anchored, flagged on screen, never printed; Notes panel
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 23:18:21 -04:00
Brandon ThomasandClaude Opus 5.5 af0d241190 T: conditional text — conditions, hide/show in layout and exports, panel, IDML
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 23:02:15 -04:00
Brandon ThomasandClaude Opus 5.5 98d8edf764 T: Composition highlights — keep and H&J violations, custom tracking/kerning
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 22:35:23 -04:00
Brandon ThomasandClaude Opus 5.5 3609862c2e C: Attributes panel — overprint fill/stroke/gap, nonprinting
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 22:18:30 -04:00
Brandon ThomasandClaude Opus 5.5 74e352698e F: Global Light and Generate Static Caption
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 21:42:46 -04:00
Brandon ThomasandClaude Opus 5.5 cd72171859 O: Script Label, alt text, isolate/knockout groups, sort table rows
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 21:27:26 -04:00
Brandon ThomasandClaude Opus 5.5 aa54531472 F: Gradient Feather — tool, effect on screen, soft mask in PDF
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 21:19:57 -04:00
Brandon ThomasandClaude Opus 5.5 175aaf28fd H: place a chosen PDF page (Image Import Options)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:57:38 -04:00
Brandon ThomasandClaude Opus 5.5 b10a06f7b8 V: Overprint Preview
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:36:07 -04:00
Brandon ThomasandClaude Opus 5.5 eb4fa9c64c T: Type on a Path — tool, options, screen and PDF
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 20:34:20 -04:00