Commit Graph
176 Commits
Author SHA1 Message Date
aiongg d241a22f80 Merge #83 update: drop cap fixes
Drop cap style through IDML as a Dropcap nested style, spaces after the cap, one-line caps, nested styles after the cap, own nested-style lists clearing an inherited drop cap style (cells and notes too), cleared styles round-tripping, tabs in right-to-left drop caps.
Conflict: ROADMAP.md: next's INDD, Interface language and Show CJK Features lines (the PR's main-merge resolution, already on next)
Conflict: crates/compose/src/lib.rs: next's warichu placement followed by the trimmed trailing spaces
Conflict: crates/compose/src/tests.rs: next's side; the PR's side repeats helpers and tests next already has
Conflict: crates/idml/src/import.rs: next's range_format
Conflict: crates/idml/src/tests.rs: next's side, with the PR's drop_caps_import_and_round_trip and its new drop_cap_fixture and nested-style clearing tests in place of next's older drop cap test
2026-10-10 16:18:49 +00:00
aiongg 7636af73e4 Drop caps: the cap style goes through IDML as a Dropcap nested style
IDML has no drop cap style attribute. Import reads the nested style list's leading "through 1 Dropcap" entry as the drop cap style; export writes the drop cap style as that entry. The drop cap style counts as that entry when composing, so nested styles after it start after the drop cap.
2026-10-10 15:48:58 +00:00
aiongg 7f23a5e05b Merge upstream main into feat/layout-parity
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
2026-10-10 15:34:23 +00:00
aiongg 54504fa341 Merge #341: feat(engine): Document chapter numbering and section prefix rules
Conflict: ROADMAP.md: kept both entries (New Document, then Document chapter numbering).
Conflict: crates/engine/src/cmd/book.rs: book.paginate keeps #341's chapter resolution with fix/section-start-bound's saturating page count (u32::try_from) and saturating "pages" result.
Conflict: crates/engine/src/cmd/layout.rs: page_numbering_view_tests keeps both tests (section_start_numbers_are_bounded, section_prefixes_are_short_and_avoid_plus_and_comma).
2026-10-10 14:55:15 +00:00
aiongg 39f72c5cd4 Merge fix/section-start-bound: Layout: section start numbers are bounded and page numbering can't overflow 2026-10-10 14:54:46 +00:00
aiongg 1ec2136c84 Layout: section start numbers are bounded and page numbering can't overflow
layout.section refuses a startNumber outside 1..=99 999, and so does layout.documentSetup for startPage (both go through one start_number check against designcraft_doc::MAX_PAGE_NUMBER). Document::page_number walks continuing sections in a loop with saturating arithmetic, so start numbers loaded from a file can't overflow it, and book pagination saturates its running page count.
2026-10-10 14:50:48 +00:00
moppeeerandClaude Opus 5.5 f061be9b3c feat(engine): Document chapter numbering
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>
2026-10-10 15:39:33 +02:00
aiongg 1abb74da0f Merge #330: Compose: the CJK leading model and character alignment apply only under the Japanese composers 2026-10-10 13:18:52 +00:00
aiongg 5dc8383a50 Compose: apply the CJK leading model and character alignment only under the Japanese composers
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.
2026-10-10 11:56:45 +00:00
aiongg 89ea36eb6c Merge #305: Preserve explicit nullable text defaults when reopening documents
Conflict: ROADMAP.md: both QA1 lines (#315, #305)
2026-10-10 11:09:24 +00:00
sanyamsingh001andCodex 4a9ebd858e QA1: preserve explicit nullable text defaults in native files
Co-Authored-By: Codex <codex@openai.com>
2026-10-10 18:53:42 +10:00
fc2ce5556f Text: Split Columns sets a paragraph in sub-columns within its column (#295)
Consecutive paragraphs with the same Split Columns settings form a split
block: their text fills the sub-columns of the column one after the
other from the block's top, inset by the outside gutter and separated by
the inside gutter, then moves on to the next column. When text follows
the block, its last part is balanced across the sub-columns and the text
continues below the deepest one at the full column width; a block that
ends the story fills its sub-columns in turn. Keep options don't apply
between a block's lines.

IDML: SplitColumnInsideGutter and SplitColumnOutsideGutter import and
export (paragraph attributes split_inside_gutter, split_outside_gutter).

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 04:27:59 -04:00
aiongg 123ee022b5 Merge #301: IDML: text variables keep their text
Conflict: crates/idml/src/import.rs: #301's TextVariableInstance arm, then next's ignored-elements arm without "TextFrame" (next imports embedded text frames)
2026-10-10 08:21:39 +00:00
aiongg aadd54a926 Merge upstream main 736acff into next
Upstream main moved 9e4f694 -> 736acff by 10 squashes: #258, #285, #153, #280, #288, #281,
#176, #299, #298, #297. New to next: #258 (datamerge test), #153 (temporary files and release
inputs), #280 (warichu), #176 (PDF image conversion cache), #297 (graphics backend before the
window). Already on next: #285, #288, #281, #299, #298.

Conflict: ROADMAP.md: next's lines; CJK1 takes main's wording (ruby unfinished, warichu set after the line is broken)
Conflict: crates/compose/src/lib.rs: list labels (#298): next's list_label structure; paragraph start / break moves: next's `go` (with #295's sub-columns) under the maintainer's #285 comment; Cursor: next's start/next_page/next_baseline with tops; line placement: #280's warichu::place right after layout_line, before next's trimmed trailing spaces and the drop cap splice (so neither is stacked and the spaces follow the closed-up end_x); caret(): next's drop-cap branch first, then #280's stacked-row metrics
Conflict: crates/compose/src/tests.rs: next's tests kept; #280's tests auto-merged
Conflict: crates/engine/src/cmd/text.rs: both (next's TypingFormat/typing_format, #280's warichu_cmd)
Conflict: crates/idml/src/tests.rs: next's side; #280's warichu round-trip test auto-merged
Conflict: crates/pdf/src/export.rs: #176's content cache and test counter with next's RasterMode (no Exporter `interpolate` field on next, so the maintainer's `mode.interpolate &= self.interpolate` is not carried); test exporter gets next's drawing_items field
Conflict: crates/ui-egui/src/canvas.rs: #280's compose::highlight_quads (its RTL branch equals next's mixed-direction spans) followed by next's drop-cap highlight
Conflict: crates/ui-egui/src/menus.rs: next's formatting_affects_text test kept

Auto-merge duplicates removed: #288's table-style tests and #298's list test in idml tests.rs,
#288's tests in doc styles.rs and #285's docx test (both files equal next's), #281's dialog
tests in dialogs.rs (equals next's) and its menu_button/menu_max_height/clipped_submenu in
menus.rs. contributors/people.toml takes main's (next had a duplicated
[people.emanuelebonaventura] table from the 9e4f694 merge, which broke the ui-egui build
script's TOML parse).

Maintainer edits carried over: #285 break characters and Next Column through one closure
(next's `go`, comment added); #281 viewport-aware menu_button in the app bar and the Paragraph
menu, per-dialog widths clamped to the window (all already on next); #280 warichu after the
last-line rules (layout_line with ends_para/forced_mid) and rules at each warichu row's
baseline (rule_baseline in render and pdf text_rules); #176 CMYK fallback through
lossless(.., mode) and its updated contract tests; #258 test fixes; #153 and #297 as landed.
2026-10-10 08:20:36 +00:00
aionggandBrandon Thomas 70974afc66 Lists: numbering formats and expressions from IDML; an empty paragraph gets no bullet or number (#298)
* Lists: numbering formats from IDML (A, B, C; i, ii, iii; 01, 02 …)

A paragraph's numbering format, number expression, bullet character and
text after the bullet import from IDML and export back. Numbered labels
come from the expression ("^#.^t", "Tabel ^#^t") with its
metacharacters expanded, in place of a fixed "n." label. Adds 001 and
0001 number styles, keeps letter and roman labels short for huge
numbers, and counts saturate instead of overflowing.

* Lists: an empty paragraph gets no bullet or number

A list paragraph with no characters before its return draws no label,
and numbering carries on past it: in a story's own list, in named lists
(also across stories) and in cross-reference paragraph numbers.

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-10 04:08:56 -04:00
aiongg 2b8dc2bdeb IDML: text variables keep their text
A TextVariableInstance becomes the document's variable character instead
of being dropped. The file's TextVariable definitions replace the default
set: custom text, dates, file name, last page number, chapter number and
running headers are computed; other types (live captions) keep their
settings and show the result recorded in the file. Creation and
modification dates come from the package's XMP metadata.

Export writes the definitions, each instance with its current result,
and the XMP dates.
2026-10-10 07:55:33 +00:00
b581031d91 IDML: resolve table styles and correct cell height fitting (#288)
* ci: simplify testkit dependency match for Clippy

* IDML: resolve table styles and shared cell edges

* Compose: size table cells by baseline and physical bounds

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:50:09 -04: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 <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:47:14 -04:00
8146737e97 Text: a column, frame or page break ends its paragraph (#285)
A break character is stored as the last character of the paragraph it
ends, followed by the usual '\n' separator. The story model, paragraph
ranges, styles, editing and every exporter keep splitting paragraphs on
'\n' only, so the change stays in the places that create, lay out or
write break characters:

- IDML import writes the break and ends the paragraph, so the range that
  follows keeps its own paragraph style. NextOddPage and NextEvenPage map
  to new odd and even page break characters; IDML export writes a
  paragraph that ends in a break as that one Br with its
  ParagraphBreakType, so export and re-import give the same story.
- Word and RTF import, Type > Insert Break Character (with odd and even
  page breaks added) and typing end the paragraph after a break. Typing
  between a break and its return goes to the next paragraph; deleting
  either deletes both.
- Layout: a break that ends a paragraph leaves no empty line; the next
  paragraph starts in the next column, frame or page, as a paragraph start
  option would. Page breaks and Next Page start options move to the next
  frame on a later page; odd and even ones to the next page with that
  page number parity (no such frame: overset). A break inside a paragraph
  from an older document still moves the rest of that paragraph on.

Storing the break as a paragraph separator of its own would have changed
every place that counts or splits paragraphs on '\n'.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:36:47 -04:00
aiongg 8ae759a848 Merge #298: Lists: numbering formats and expressions from IDML; an empty paragraph gets no bullet or number
Conflict: crates/compose/src/lib.rs: next's list_label match with its list_label glyph flag; arms take #298's empty-paragraph rule, number_label/bullet_label and saturating counter
Conflict: crates/compose/src/tests.rs: next's file with #298's appended tests
2026-10-10 07:15:49 +00:00
aiongg 107f658f0e Lists: an empty paragraph gets no bullet or number
A list paragraph with no characters before its return draws no label,
and numbering carries on past it: in a story's own list, in named lists
(also across stories) and in cross-reference paragraph numbers.
2026-10-10 07:01:05 +00:00
aiongg 2a2d20e0c2 Lists: numbering formats from IDML (A, B, C; i, ii, iii; 01, 02 …)
A paragraph's numbering format, number expression, bullet character and
text after the bullet import from IDML and export back. Numbered labels
come from the expression ("^#.^t", "Tabel ^#^t") with its
metacharacters expanded, in place of a fixed "n." label. Adds 001 and
0001 number styles, keeps letter and roman labels short for huge
numbers, and counts saturate instead of overflowing.
2026-10-10 06:57:28 +00:00
60ad82497b Text frames: column rules on screen, in PDF and in IDML; Column Rules in Text Frame Options (#274)
* Text frames: column rules draw between columns on screen and in PDF

A frame with Column Rule on gets a bar centred in each gutter, inside the
insets, broken around paragraphs that span columns; right-to-left and
vertical frames included. object.textFrameOptions takes columnRuleWeight
and columnRuleColor (unknown swatches are an error) and an inset array
whose null sides stay; document.inspect reports the rule.

* Text Frame Options: Column Rules fields; OK changes only edited fields

The dialog shows the selected frame's options, with an inset field per
side, and sends only what the user changed, so unequal insets survive.
The rule weight is read in points.

* Column rules: tint, horizontal offset and top/bottom insets; IDML import and export

Text Frame Options gains Tint %, Top Inset, Bottom Inset and Horizontal
Offset for the rule, and object.textFrameOptions and document.inspect
take and report them. IDML reads the ColumnRule attributes of
TextFramePreference on frames and object styles and writes them when a
rule is set.

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:49:00 -04:00
aiongg 57801d86a5 Merge #295: Text: Split Columns sets a paragraph in sub-columns within its column
Conflict: crates/compose/src/lib.rs: #295's split_cfg block and sub-column-aware next_column closure, then next's `go` closure unchanged (StartParagraph::NextColumn and column breaks reach the next sub-column; other start options go through Cursor::start, whose next_frame/next_page start a new split part)
Conflict: crates/compose/src/tests.rs: both sides' tests (closing brace restored after next's last test)
Conflict: crates/idml/src/tests.rs: both sides' tests (closing brace restored after next's last test)
2026-10-10 06:41:22 +00:00
01500ceb04 Paragraph Rules: a dialog for the selected paragraphs and a section in Paragraph Style Options (#263)
* Paragraph rules: a partial ruleAbove/ruleBelow edit keeps the other rule fields; Rule Above honours Text width

* Paragraph Rules: dialog for the selected paragraphs and a Paragraph Style Options section

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:28:09 -04:00
aiongg f39897db0b Text: Split Columns sets a paragraph in sub-columns within its column
Consecutive paragraphs with the same Split Columns settings form a split
block: their text fills the sub-columns of the column one after the
other from the block's top, inset by the outside gutter and separated by
the inside gutter, then moves on to the next column. When text follows
the block, its last part is balanced across the sub-columns and the text
continues below the deepest one at the full column width; a block that
ends the story fills its sub-columns in turn. Keep options don't apply
between a block's lines.

IDML: SplitColumnInsideGutter and SplitColumnOutsideGutter import and
export (paragraph attributes split_inside_gutter, split_outside_gutter).
2026-10-10 06:22:38 +00:00
06b4e4e860 Add A6 sheet preset to the welcome page (#248)
Co-authored-by: moppeeer <339764117+moppeeer@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:18:47 -04:00
617e487dff Styles: Character Style Options dialog (#144)
* Styles: editing a character style renames it everywhere it is used, changes its Based On and unsets attributes; [None] can't be edited

* UI: Character Style Options edits a character style's name, Based On and character formats, opened by double-clicking the style, Edit in its menu, or New Character Style…

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:14:30 -04:00
aiongg fe16e00e37 PDF/A keeps placed images; right-to-left tables and columns (#128)
* PDF: PDF/A exports keep placed PNG, JPEG, GIF and WebP images by writing them without interpolation (#71)

* Tables: new tables take their paragraph's direction, and the Table panel sets a table's direction (#100)

* Text: stories made in a right-to-left-bound document fill their columns from the right (#100)
2026-10-10 01:13:48 -04:00
aiongg e1ed4ff118 Merge #288: IDML: resolve table styles and correct cell height fitting
Conflict: crates/idml/src/import.rs: #288's table style import (based_on, region flags, borders, row/column fills and strokes) and #288's table() style resolution; next's alt_fills (#83) is unused and removed (#83's defaults hold under #288's cascade)
Conflict: crates/idml/src/tests.rs: next's file with #288's appended tests
Conflict: crates/doc/src/styles.rs: tests only; kept both
2026-10-10 05:12:12 +00:00
skylartaylor 56a8150709 IDML: resolve table styles and shared cell edges 2026-10-09 21:57:31 -06:00
aiongg 2a80cfe54c Merge #285: Text: a column, frame or page break ends its paragraph; odd and even page breaks
Conflict: crates/compose/src/lib.rs: start options, the break after the previous paragraph and a break inside a paragraph go through a local `go` that sends NextColumn to next's span-aware next_column (#276) and the rest to #285's Cursor::start; the in-paragraph break takes #283's `brk` (the line's last glyph); #283's ends_para uses is_break_char; Cursor keeps next's resume() and adds #285's start/next_page (#285's old next_baseline header dropped, next's is kept); the table branch is #285's
Conflict: crates/idml/src/tests.rs: tests only; kept both
Conflict: crates/textimport/src/docx.rs: tests only; kept both
2026-10-10 03:51:42 +00:00
aiongg 69f8d0fcdd Text: a column, frame or page break ends its paragraph
A break character is stored as the last character of the paragraph it
ends, followed by the usual '\n' separator. The story model, paragraph
ranges, styles, editing and every exporter keep splitting paragraphs on
'\n' only, so the change stays in the places that create, lay out or
write break characters:

- IDML import writes the break and ends the paragraph, so the range that
  follows keeps its own paragraph style. NextOddPage and NextEvenPage map
  to new odd and even page break characters; IDML export writes a
  paragraph that ends in a break as that one Br with its
  ParagraphBreakType, so export and re-import give the same story.
- Word and RTF import, Type > Insert Break Character (with odd and even
  page breaks added) and typing end the paragraph after a break. Typing
  between a break and its return goes to the next paragraph; deleting
  either deletes both.
- Layout: a break that ends a paragraph leaves no empty line; the next
  paragraph starts in the next column, frame or page, as a paragraph start
  option would. Page breaks and Next Page start options move to the next
  frame on a later page; odd and even ones to the next page with that
  page number parity (no such frame: overset). A break inside a paragraph
  from an older document still moves the rest of that paragraph on.

Storing the break as a paragraph separator of its own would have changed
every place that counts or splits paragraphs on '\n'.
2026-10-10 03:41:12 +00:00
aiongg 66d6479c09 Merge #274: Text frames: column rules on screen, in PDF and in IDML; Column Rules in Text Frame Options
Conflict: crates/idml/src/import.rs: next's text_frame_options(&[&El]) object-style chain with #274's column rule fields; #274's frame_options takes the prefs list and looks up ColumnRuleStrokeColor through Prefs; the frame site resolves the rule colour's swatch after building options from the chain (the chain borrows the importer)
Conflict: crates/idml/src/tests.rs: tests only; kept both
Conflict: crates/compose/src/tests.rs: tests only; kept both
Conflict: crates/pdf/src/tests.rs: tests only; kept both
2026-10-10 01:05:14 +00:00
aiongg 7d0bdbc916 Column rules: tint, horizontal offset and top/bottom insets; IDML import and export
Text Frame Options gains Tint %, Top Inset, Bottom Inset and Horizontal
Offset for the rule, and object.textFrameOptions and document.inspect
take and report them. IDML reads the ColumnRule attributes of
TextFramePreference on frames and object styles and writes them when a
rule is set.
2026-10-10 00:33:27 +00:00
aiongg e1cc16325a Merge #263: Paragraph Rules: a dialog for the selected paragraphs and a section in Paragraph Style Options
Conflict: ROADMAP.md: kept next's IDML1 line and #263's Paragraph Rules line
Conflict: crates/compose/src/lib.rs: Rule Above uses #263's first line and Column/Text width with #83's rule_color() for colour and tint
Conflict: crates/engine/src/cmd/text.rs: type.para params doc lists next's drop cap fields and #263's ruleAbove/ruleBelow; format_paras is #263's
Conflict: crates/ui-egui/src/dialogs.rs: kept both confirm arms (characterStyleOptions, paragraphRules) and both sets of tests
2026-10-09 23:59:08 +00:00
aiongg fa13bf24f4 Paragraph rules: a partial ruleAbove/ruleBelow edit keeps the other rule fields; Rule Above honours Text width 2026-10-09 23:42:11 +00:00
aiongg ee24cb949b Merge #129: Fix IDML Mojikumi spacing, kinsoku composition, and nested text preflight
#129's first commit (4f8d230) holds #124 and #126, which are already merged. Each conflicted file is a three-way merge of #129's own commits (4f8d230..pr/129) onto this branch, which takes #129's side against #126 and keeps the chain's (#81/#84) code.
Conflict: ROADMAP.md: kept both entries
Conflict: crates/compose/src/shape.rs: #129's Mojikumi metrics added; #81's pieces, the #126 composite-note piece and the #124 inline-object metrics unchanged
Conflict: crates/compose/src/tests.rs: tests only; #129's tests added, no duplicates of #124/#126's
Conflict: crates/engine/src/cmd/fonts.rs: #129's pub(super) for_each_story; #126's tests kept once
Conflict: crates/engine/src/cmd/preflight.rs: #129's nested-story paragraph rules; the used_fonts loop kept once
Conflict: crates/engine/src/tests.rs: tests only; #129's test added
Conflict: crates/fonts/src/fontdb.rs: #126 content (same in #129); no change
Conflict: crates/idml/src/import.rs: #129's Mojikumi import added
Conflict: crates/idml/src/tests.rs: tests only; #129's tests added
Conflict: crates/ui-egui/src/dialogs.rs: #126 content (same in #129); no change
Conflict: crates/ui-egui/src/lib.rs: #126 content (same in #129); no change
2026-10-09 22:52:22 +00:00
aiongg 988e45b0bb Merge #126: Fix composite font resolution, missing-glyph diagnostics, and document-wide font replacement
Conflict: crates/compose/src/shape.rs: #81 collects paint-only pieces and shapes them later, #126 shapes composite-font note labels inline. A footnote reference in a composite font becomes a Piece with `composite_note`, shaped alone in the piece pass with #126's per-entry label code (from the run's env, as in #126); other references stay ordinary pieces. #126's label fallback in shape_segment passes #81's StyleRuns.
Conflict: crates/fonts/src/fontdb.rs: #126's canonical_family lookup sits at the top of exact_style_traits, so #81's styles/traits_of/linked_style and #247's format-suffix fallback all use it; face() resolves canonical, then canonical without the format suffix, then #126's substitute_family, through #247's find_or_load; has_family is canonical_family as named or without the suffix
Conflict: crates/ui-egui/src/lib.rs: kept #84's system-clipboard copy match and added #126's Find Font on open and _fonts reset after it
Conflict: crates/ui-egui/src/dialogs.rs: OK label match has #146's Save and #126's Replace All; #80's alert-only OK kept, #126's Done label for findFont; find_font keeps #143's font_combo with #126's FALLBACK_FAMILY default
Conflict: crates/compose/src/tests.rs, crates/idml/src/tests.rs: tests only; kept both
Conflict: ROADMAP.md: kept both entries
2026-10-09 22:49:44 +00:00
aiongg 01799b4927 Merge #124: IDML: preserve anchored text frames and footnote artwork
Conflict: crates/compose/src/shape.rs: inline object on the baseline: #124's rule (its box alone sets the extents, not max with the font's) applied to every metric #83 tracks (ascent, typo_ascent, cap, xh); the above-line arm keeps #83's four fields
Conflict: crates/compose/src/tests.rs: tests only; kept both
Conflict: crates/engine/src/tests.rs: tests only; kept both
Conflict: crates/idml/src/tests.rs: tests only; kept both
2026-10-09 22:46:08 +00:00
aiongg 277c442814 Merge #96: Compose: an empty paragraph takes its mark's character format 2026-10-09 22:43:00 +00:00
aiongg 71074a987b Merge #84: Text editing, snapping and text threading (#23)
Conflict: crates/ui-egui/src/control.rs: tests only; kept #118's automation_contract_tests module and #84's tests module
Conflict: crates/ui-egui/src/lib.rs: kept #119's ImportedFile Inbox type and #84's ClipboardFn
Conflict: crates/ui-egui/src/menus.rs: tests only; kept #239's two Quick Apply tests and #84's copy/paste test
2026-10-09 22:41:29 +00:00
aiongg 4b24103b24 Merge #83: Layout: first baselines, Jump Object wrap, drop caps, IDML defaults 2026-10-09 22:40:47 +00:00
aiongg f4f0896f85 Merge #144: Character Style Options dialog; style.character.edit renames everywhere, validates Based On, null unsets; New Character Style opens the dialog
Conflict: crates/ui-egui/src/dialogs.rs: took #144's structure (shared basic_character_formats and character_color sections); paragraph_style_options reads a clone of the document as #143 does, so the font menu can borrow the app; basic_character_formats takes &mut DesignApp and uses #143's font_combo (font_menu_rows is gone) with a × button that clears a style's family
2026-10-09 22:35:29 +00:00
aiongg c18912db69 Merge #128: PDF/A keeps placed images; right-to-left tables and columns
Conflict: crates/pdf/src/export.rs: took #223's side (RasterMode with #147's decode check) and dropped #128's Exporter interpolate field; #128's RTL story/table work and its PDF/A test are kept
2026-10-09 22:16:55 +00:00
moppeeer 84be68d9c2 Add A6 sheet preset to the welcome page 2026-10-09 23:28:49 +02:00
aiongg ca0ab6e551 UI: Character Style Options edits a character style's name, Based On and character formats, opened by double-clicking the style, Edit in its menu, or New Character Style… 2026-10-08 10:03:57 -04:00
Shao Wenbin 9f655739fa CJK-REVERT2: withdraw speculative spacing rules and narrow import rejection
Restore the previous preset and character-class coverage. Remove regional punctuation and Tsume policy changes while retaining cluster, tracking, and spacing-allocation repairs. Preserve finite unsupported rows for diagnostics instead of rejecting whole documents.
2026-10-08 20:36:21 +08:00
Shao Wenbin 56febef6ab CJK-REVERT1: revert CID preference and diagnostic expansion
Revert 20ce4f5 because the compatibility extension does not implement CID-based layout and is not required for the verified spacing repairs.
2026-10-08 20:32:53 +08:00
Shao Wenbin 20ce4f5ecd CJK-MOJI9: preserve CID preferences and report unsupported glyph classification 2026-10-08 20:24:59 +08:00