#343 adds its twelve Tabs strings to the shared table; next's ja.rs (#272) keeps a row for every
shared key. The rows carry over the shared table's Japanese column, so lookups are unchanged.
#343 adds its twelve Tabs strings to the shared table; next's de.rs (#311) keeps a row for every
shared key. The rows carry over the shared table's German column, so lookups are unchanged.
Conflict: ROADMAP.md: both lines kept (next's IDML1 line, then the Tabs panel line)
Conflict: crates/engine/src/cmd/mod.rs: both spec lists kept (thread::specs, then tabs::specs)
Conflict: crates/ui-egui/src/dialogs.rs: next's delete_paragraph_style and the PR's style_tabs both kept, without the section_list doc comment that next removed; in the tests the PR's copies of draw, ruled_paragraph, undo_steps, the rule tests, command_app, the generic command tests and the text frame options test duplicated next's identical ones and were dropped, keeping only the PR's new Tabs section test
Conflict: crates/ui-egui/src/i18n/it.rs: both blocks kept (next's machine-translated rows, then the Tabs rows)
Conflict: crates/ui-egui/src/i18n/uk.rs: both blocks kept (next's machine-translated rows, then the Tabs rows)
Swatch lists (Character panel, Properties, task bar) shaded the row under
the pointer with the theme's hover grey, a few levels from the popup's
own background, so it looked as if nothing changed. The row under the
pointer is now white on blue, like a menu; the current swatch keeps its
shading. The lists also grow to fit their longest name, and their rows
stop short of the scroll bar that floats over the list's edge, so names
like C=15 M=100 Y=100 K=0 are no longer cut by it. The four copies of
the list are one shared function now.
The Glyphs panel counted its columns from the panel's whole width, so
the last column ran under the floating scroll bar and was cut off; the
columns now leave the bar room.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Type › Tabs (Cmd+Shift+T) floats a Tabs panel: alignment buttons, X,
Leader and Align On fields, and a ruler where a click adds a stop, a
drag moves it and dragging it off the ruler deletes it. The triangles
on the ruler drag the first-line, left and right indents. The panel
menu has Clear All, Delete Tab, Repeat Tab and Reset Indents. The panel
opens above the selected horizontal text frame with the ruler at the
view's zoom over the column; the magnet button places it there again.
type.tabs.* edit the stops of the selected paragraphs or, with a style
parameter, of a paragraph style. Positions are finite and clamped, a
paragraph holds at most 100 stops, leaders up to 8 characters and the
align-on character is one character. type.tabs.get reports the stops,
indents and the text column they are measured in.
Layout > Numbering & Section Options now opens its own window instead of
the generated command form, on the section of the page in view: Start
Section (always on for page 1), Automatic Page Numbering or Start Page
Numbering at, and a Page Numbering group with Section Prefix, Style,
Section Marker and Include Prefix when Numbering Pages; then Document
Chapter Numbering with its style, Automatic Chapter Numbering, Start
Chapter Numbering at, Same as Previous Document in the Book (only in a
book) and the book's name. OK and Cancel sit beside the options, out of
the scrolling body.
OK runs layout.section and layout.chapterNumbering; a refused value
(a prefix over eight characters or with + or a comma, a start number
below 1) keeps the window open and changes nothing. Opening the window
reads the chapter numbering without running a command, so it doesn't
stop a Data Merge preview. New strings are translated (German, French,
Spanish, Japanese, Chinese, Italian).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#336 adds the Show CJK Features string to the shared table and the ja, ar, pt_br, it and uk tables; next's German table (#311) covers every key of those tables, so it gets a row too (machine translation, the shared table's German column).
Conflict: ROADMAP.md: next's Right-to-left and Interface language lines (IDML Kashidas, German and Japanese cover every catalog, Ukrainian covers every key) plus the PR's Show CJK Features line
Conflict: crates/ui-egui/src/lib.rs: the PR's cjk_features() before next's opens_as_document (with .indd/.indt and its doc comment)
Preferences > Type > Show CJK Features (cjkFeatures; unset follows the
interface language: on for Japanese, Chinese and Korean) hides the
CJK-only Type menu items (Tate-Chu-Yoko, Ruby, Kenten, Warichu) and the
Ruby Quick Apply entry. The commands, layout and IDML work either way.
A section prefix is at most eight characters and contains no plus or
comma (page references and ranges use them); `layout.section` refuses
others and leaves the section unchanged. Symbols, a footnote style,
no longer number pages. The parameter documentation lists the 01, 001
and 0001 styles, and a test pins the fields the generated dialogs read
from both numbering commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A document's chapter number now has a style (1, I, i, A, a, 01, 001,
0001) and a source, as in Numbering & Section Options > Document
Chapter Numbering: Automatic Chapter Numbering (one more than the
previous document in the book; 1 first), Start Chapter Numbering at,
or Same as Previous Document in the Book.
`layout.chapterNumbering {style?, start?, source?}` sets them (undoable)
and, with no parameters, reports them with the open book that holds the
document. The book's Update Numbering (`book.paginate`) resolves chapter
numbers in book order and reports them. Chapter Number variables and
cross-reference chapter numbers use the style.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Static families such as Alexandria name every weight's legacy family
"Alexandria <Weight>" with subfamily "Regular". Matching names and aliases in
one pass let the first such face (Black) answer for Regular, so text set in
Regular came out in Black, wider, and pushed lines into overset.
(cherry picked from commit 681a3ec499834b866dd18244e5b25b425c682b10)
File > New > Document now shows Recent, Saved, Print, Web and Mobile
tabs of page cards (drawn to the preset's proportions; double-click
creates) beside the preset's details: document name, width and height
with arrows, units, orientation, pages, start page #, facing pages,
primary text frame, columns and gutter, and collapsible margins and
bleed and slug per edge with link toggles. Save Document Preset keeps
presets by name; documents made are remembered for the Recent tab.
Small windows stack the details above the presets and scroll; the
layout mirrors for right-to-left languages. New strings go through the
translation tables (Italian, German, French, Spanish, Japanese, Chinese).
file.new takes intent, units, startPage and per-edge bleed and slug.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nested repetitions such as ((a)*)* asked the group below for the same end
positions again and again, which is exponential in their depth: remember
the positions of a group per start position while one element's children
are matched. The search for the closing semicolon of a parameter-entity
reference had a 256-byte window, so a longer name was left unexpanded
without an error: stop the search at whitespace or the next percent sign
instead, which keeps a round linear and puts no limit on the name.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Every IDML root style carries LeadingModelAkiBelow and AlignEmCenter, but only
the Japanese composers (HL Composer J, HL Single J) use them; the Adobe and
World-Ready composers set lines baseline to baseline with every character on
the Roman baseline. Applying them everywhere moved lines down after a size
change and lowered smaller-em glyphs, pushing the last lines of tight frames
(and whole keep-together paragraphs) into overset.
Composer gains Japanese and JapaneseSingleLine, read from and written to IDML;
the composer choice in the UI keeps the kind.
Automatic page numbers (and section markers) were set from the page name as
typed, so a page number in Hindi Digits text drew Western digits, which an
Arabic-only font shows as missing-glyph boxes. They now map their digits like
typed text does.
#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.
When OS/2 has no usable sCapHeight / sxHeight, the face measures them from the
unhinted outlines of flat-topped letters (H I E T for cap height, x z v for
x-height) at the face's variation location, and falls back to a share of the
ascent only when none of those letters has a plausible outline. Measuring
outlines instead of the glyf bounding box also covers CFF and variable fonts.
Based on seanth's measurement in #292.
Co-authored-by: Sean Hammond <sean.hammond@und.edu>
A run that begins with combining marks, after a run that differs only in
OpenType features (ligatures, kerning, OTF features), now gives those marks
to the run before it. The shaper attaches each mark to its base, and a
missing font's fallback draws the mark in the same face as its letter
instead of the substitute's missing-glyph box. Runs in another font, size
or colour keep their marks.
Parameter entities were expanded by up to eight rounds of text.replace
per entity over the whole text, so a few hundred bytes of DTD grew
exponentially and a large one cost entities x length per round. Expand
them one scan per round with a map, bound the result and the depth, and
refuse cycles. Content-model groups recursed once per parenthesis with
no limit (a stack overflow), and the positions after each item of a
sequence were kept as a list of paths (2^n for n optional items): limit
the nesting and keep the positions a set.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
#311's de.rs translates "Select an object to color its fill or stroke."; #81/#84 on next say "Select an object or text to color its fill or stroke.", so the German interface showed it in English. The row takes the new key.
Conflict: crates/compose/src/tests.rs: tests only, both (#310's tight word spacing test, #316's GREP style test)
#316's overlay test calls overlays() with the drop_end argument next added (#83).
One shared compiler (designcraft_compose::grep) translates the GREP dialect
documents and users write: \l \u \L \U letter classes, \h \H \v \V \R \N,
\r paragraph end and \n forced line break, ~ special-character codes,
Unicode-aware POSIX classes, and literal [ & -- inside character classes.
It compiles with fancy-regex, so lookahead, lookbehind, atomic groups,
possessive quantifiers, backreferences and \K work; a backtrack limit stops
pathological patterns with an error.
GREP styles skip a pattern that fails to compile or gives up on a search,
with one log warning. Find/Change returns the error. The paragraph style
dialog validates with the same compiler. Fixes en dash (~=) mapping to an
em dash in Find/Change.
Conflict: crates/tools/src/snap.rs: first_on_axis: a guide or margin in reach competes with the baseline grid through #84's nearer(); otherwise #309's smart-guide passes run and the baseline grid comes last. #84's nearer_of_margin_and_baseline_wins and #309's tests pass.
#171's style.character.delete (and the style.paragraph.delete it copies) reassigned only text runs;
next's rename_style already rewrites styles, stories, table cells, nested and GREP styles and
footnotes. Both deletes now go through one delete_style that removes the style, rebases its
children and calls rename_style, in one undo step.
- Children of the deleted style are based on the replacement ([None] and [No Paragraph Style]
clear Based On); when the replacement descends from the deleted style they take its parent,
so no based-on chain loops.
- rename_style also covers drop cap styles, cell styles' paragraph style, footnote and endnote
paragraph styles, the endnote heading style, TOC entries and the default paragraph and
character styles, which fixes renames too.
- A missing, empty, unknown or built-in name, an unknown replacement and a replacement equal to
the deleted style are errors that change nothing.
A German table (crates/ui-egui/src/i18n/de.rs) covers every key of the shared,
Japanese, Arabic, Brazilian Portuguese, Italian and Ukrainian catalogs (1,697
rows; before, 164 strings were German). The shared table's German column stays
the fallback for keys added after it. Tests check placeholders, padding, colons
and ellipses against the English source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflict: crates/compose/src/breaker.rs: next's multi-line Item::boxed/penalty with edge_elastic and start_elastic plus #310's over; glue in items() keeps next's edge_elastic and sets #310's over; kp_pass first node keeps next's first_box/first_hang/first_elastic and ty/tz plus #310's to
On the vertical axis the baseline grid was tried before smart guides.
It snaps while hidden, and with lines every 12 pt and a box's top,
centre and bottom each reaching 4 pt either side, one of them is nearly
always in the zone. It took almost every vertical move and drew nothing,
so object alignment and equal spacing hardly ever showed on y. The
baseline pass now runs after the smart guide passes.
Smart spacing also only matched a gap between two other boxes. A box
dragged between two neighbours now snaps to where both of its gaps are
equal, and both gaps are marked.
Fixes#188
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5fQBTFb4hhKXsCFYitZ1P
Stretch past the maximum word spacing was shared by every space on the
line, so em, en and thin spaces widened along with word spaces. Only word
spaces take it now; a line without word spaces gives it to its letter
gaps, matching how the paragraph composer rates such a line.
Stretch past the maximum word spacing was rated in units of the word
spaces' own stretch. With a narrow range (100-105%) that unit is tiny, so
a loose line with several word spaces rated far worse than a single word
letter-spaced across the measure, and the paragraph composer chose the
single word. Rate the overflow in units of at least a third of the word
spaces' width (the default range), so word spaces take the extra stretch.