#83 adds native format 2 and an upgrade that pins Keep Lines Together and Align Left Edge where a format-1 style chain leaves them unset. #305's tests save the same document as native ZIP and as legacy JSON (format 1) and compared both as whole documents. The base style now sets both attributes, and only the native ZIP is compared as a whole document; the nullable resolution is checked for both.
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>
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.
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.
Drop caps get the Drop Cap Detail options as paragraph attributes: Align
Left Edge (on by default) and Scale for Descenders (kept and
round-tripped; no layout effect yet). With Align Left Edge the drop
cap's origin moves left by its first letter's left side bearing so its
ink starts at the indent, and the lines beside it start where its
advance ends. Right-to-left drop caps are unchanged.
Drop cap characters are counted as code points, extended to the end of
the grapheme cluster so a letter keeps its combining marks.
IDML imports and exports DropcapDetail (bit 1 Align Left Edge, bit 2
Scale for Descenders). DropCapStyle is still imported but no longer
exported: IDML applies the drop cap's character style through a Dropcap
nested style instead.
Format 1 documents keep their drop caps unaligned where nothing set the
option. Paragraph Style Options > Drop Caps has Align Left Edge and Scale
for Descenders checkboxes.
Paragraph rules can be in Text Color: they take the colour of the
paragraph's first character (rule above) or last character (rule below).
That is the default, and IDML maps RuleAboveColor / RuleBelowColor
"Text Color" both ways.
Defaults for what a file leaves unset, in the model and in IDML import:
text frames auto-size from the centre, numbered lists don't continue
across stories, and alternating table and table style fills start
Black 20 % then None 100 %. Kashidas (DefaultKashidas / KashidasOff)
import and export. A tint of -1 is the colour's own tint everywhere tints
are imported (underline and strikethrough, footnote rules included), and
tints are capped at 100 %.
Format 1 documents load as saved: they wrote rules, text frame options,
lists and table fills in full, so nothing relied on the old defaults.
Keep Lines Together now defaults to "At Start/End of Paragraph" (2/2):
new paragraphs, and IDML that sets Keep Lines Together without
KeepAllLinesTogether anywhere in the style chain, keep lines at the
start and end instead of moving the whole paragraph.
The native format is now version 2. Loading a version-1 document pins
"all lines" where that document resolved it from the old default (the
start of each paragraph style chain that leaves it unset, and
paragraphs whose style is missing), so saved documents keep their
layout.
An .xlsx cell reference far from the others no longer allocates the whole
range before the cell cap (billions of cells, out of memory), and long
column names can't overflow. IDML import doesn't trust zip part sizes for
up-front allocation and adds header/footer counts saturating. Tagged Text
and IDML export use let-else; the font fallback has a compiled-in last
resort. These crates deny the panicking lints.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>