Conflict: ROADMAP.md: took main's restructured roadmap; this branch's inventory changes (Keep Lines Together default, IDML defaults, drop caps, IDML Kashidas) go into docs/target-app-parity.md, where the inventory lives now
Conflict: crates/format/src/lib.rs: load runs the format upgrade, then merges duplicate assets; kept both sets of tests
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 <noreply@anthropic.com>
Conflict: ROADMAP.md: this branch's Text engine, IDML interchange and Right-to-left lines; main's FID2, PDF export and Interface language lines
Conflict: crates/compose/src/lib.rs: list labels as main's number_label/bullet_label/empty-paragraph arms, kept in this branch's list_label form that marks label glyphs; main's layout_line call (ends_para, forced_mid) and warichu::place, then the drop cap splice; rule above uses main's first-line column/end_x span with this branch's rule_color; caret(): drop-cap branch, then main's stacked-row metrics
Conflict: crates/compose/src/tests.rs: both sides' tests
Conflict: crates/engine/src/cmd/text.rs: type.para doc lists the drop cap fields and main's rule fields
Conflict: crates/fonts/src/fontdb.rs: both (plausible/measured_top/typo_ascent and without_format_suffix)
Conflict: crates/idml/src/import.rs: main's table style regions, borders and alternating fill/stroke attrs (this branch's alt_fills helper dropped, unused); underline/strikethrough colour from main with this branch's tint(); frame_options takes the object-style chain's TextFramePreference elements, the frame's column rule colour resolved after it
Conflict: crates/idml/src/tests.rs: main's tests, plus this branch's added tests and helpers
Conflict: crates/ui-egui/src/canvas.rs: main's compose::highlight_quads, then this branch's drop-cap highlight
* 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 <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Resolve conflicts with the CJK/Arabic composition work: line metrics keep
the first-baseline tops and add the CJK alignment shift; the CJK line
reference adjustment applies before baseline-grid snapping; layout_line
takes the bidi info and the drop cap is spliced in after it; vertical text
is now the story's direction (FrameSpec::vertical); IDML insets use main's
validated inset_spacing over the object style chain; format's JSON upgrade
(vertical frames) and model upgrade (format v2 defaults) both run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
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.
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.
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.
A frame takes the corner options and Text Frame Options it doesn't write
from its applied object style, the styles that one is based on, then
[None]: IDML frames write only what differs from their style. Each
corner's shape and radius resolve separately, item first; at each level
a per-corner attribute wins over the legacy CornerOption / CornerRadius
pair, so a frame that writes one corner keeps the style's other corners,
and a shape without a radius takes the chain's (12 pt at the root). Fill
and stroke lookups end at [None] too.
Checked, unchanged: corner radii are drawn clamped to half the shorter
side as circular arcs, and inside-aligned strokes are the stroke of the
path inset by half the weight (screen and PDF); tests pin both.
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 <noreply@anthropic.com>