chore: sync upstream (157 Commits) #11

Merged
alf merged 157 commits from chore/sync-upstream-20261027 into main 2026-10-27 20:37:15 +00:00
Owner

Upstream-Sync von upstream/main (157 Commits). Fast-Forward.

  • 4b8b06fe Merge pull request #4602 from Silvertree2010/perf/export-speed
  • de3bfaf0 Keep harfrust shape plans per face
  • f8e327b0 Merge pull request #3936 from benandez/fix/3907-section-marks
  • 50a8ebe3 Merge pull request #4387 from benandez/fix/3872-followup
  • f270dbd3 Merge pull request #4060 from benandez/fix/3995-thai-test-guard
  • 436d444e fix(ui): dropdown menus grow back after a search with no matches (#4577)
  • ffa127c6 Skip per-character table lookups for plain text in layout and PDF export
  • 8cdc1721 Lay out the paragraph after a kept heading once
  • 1b485e1f #3907: CodeRabbit — a kept paragraph is measured against the next page's body (a different first-page header)
  • 751eb4b2 #3907: CodeRabbit — a stacked mark past the page bottom draws no line number either
  • 5225569d #3907: review — an empty mark taking no room, or stacked past the page bottom, draws no list label; an empty mark after a text paragraph closing a section stays quiet
  • f2fe7654 #3907: review — a kept paragraph low in a continuous section moves to the next page; a page break before a stacked mark keeps the new page's bottom
  • 77578282 #3907: continuous sections running off a page go onto the next; empty marks in a row stack to the page bottom
  • 04ebc4ed #3995: Thai one-face fallback tests skip unless a Thai font with Latin is installed
  • cd683a9f #3872: review — privacy rewrite keeps attribute values as written, escaping only quotes
Upstream-Sync von `upstream/main` (157 Commits). Fast-Forward. - 4b8b06fe Merge pull request #4602 from Silvertree2010/perf/export-speed - de3bfaf0 Keep harfrust shape plans per face - f8e327b0 Merge pull request #3936 from benandez/fix/3907-section-marks - 50a8ebe3 Merge pull request #4387 from benandez/fix/3872-followup - f270dbd3 Merge pull request #4060 from benandez/fix/3995-thai-test-guard - 436d444e fix(ui): dropdown menus grow back after a search with no matches (#4577) - ffa127c6 Skip per-character table lookups for plain text in layout and PDF export - 8cdc1721 Lay out the paragraph after a kept heading once - 1b485e1f #3907: CodeRabbit — a kept paragraph is measured against the next page's body (a different first-page header) - 751eb4b2 #3907: CodeRabbit — a stacked mark past the page bottom draws no line number either - 5225569d #3907: review — an empty mark taking no room, or stacked past the page bottom, draws no list label; an empty mark after a text paragraph closing a section stays quiet - f2fe7654 #3907: review — a kept paragraph low in a continuous section moves to the next page; a page break before a stacked mark keeps the new page's bottom - 77578282 #3907: continuous sections running off a page go onto the next; empty marks in a row stack to the page bottom - 04ebc4ed #3995: Thai one-face fallback tests skip unless a Thai font with Latin is installed - cd683a9f #3872: review — privacy rewrite keeps attribute values as written, escaping only quotes
alf added 157 commits 2026-10-27 20:37:13 +00:00
#4392's tests used Page and Rgb, which other changes merged around it no longer
brought into scope, so main's CI gate fails with E0425/E0422 in tests_linear.rs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2
#3866: fix main's layout test build (tests_linear imports Page and Rgb)
Use the fixed release for GHSA-vc25-qg58-w57c.
ci: require nextest 0.9.150
refactor: shared module layout (craft-contrib#20)
- A package storing WORD/FONTTABLE.XML (part names are case-insensitive) loaded no
  embedded fonts and a save dropped the table and every font: lookups used the exact
  constant spelling. They now find the key case-insensitively.
- scrub_private re-pushed attribute values raw (quick-xml push_attribute does not
  escape), so a value read from single quotes became malformed XML. The value is now
  unescaped and escaped again.
- rel_targets matches _rels/ case-insensitively.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2
Unescaping and escaping again turned &#10; and &#9; into raw characters that read
back as spaces. The raw value of well-formed markup holds no `<` and every `&` starts
a reference, so only a `"` from a single-quoted value is replaced with &quot;.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2
Noto Sans Thai and its siblings have no Latin letters or digits, so on a
machine whose only Thai fonts are Noto no face covers the test run and
fallback_for_run rightly returns None. The guard now asks whether the Thai
substitute covers the whole run, which doesn't go through fallback_for_run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
A continuous section moves the column top down below the text above. at_top()
then held at every new section start, so a paragraph that did not fit was
placed anyway, as on an empty page. A run of one-line continuous sections ran
off the bottom of page 1 (100 of them reached 2,480 pt down a 792 pt page).
The overflow checks for paragraphs now use fresh(): at the top with nothing
above on this page. at_top() still drives the spacing rules, unchanged.

Empty paragraphs that close a continuous section right after another
section's mark took no room. Measured in Word on synthetic files ("Start", N
such marks, "End"): 10 put "End" about 9 cm down page 1; 50, 100 and 200 all
put it on the first line of page 2, the same with 24 pt marks or no paragraph
spacing. So each takes its line while it fits, then stays at the page's
bottom. A mark right after text stays quiet, as measured before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
CodeRabbit (local): keep-lines compared its height with the room below the
mid-page section start, so a paragraph that fits on a new page split instead.
It now compares with the next column, or the next page's body when this is the
last column. A stacked mark whose page break before starts a page no longer
gets the previous page's bottom back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
dpkruse's Genuine Steps Certificate: a bulleted text paragraph closes a
two-column continuous section, then an empty bulleted one closes another.
Word draws no bullet for the empty one; it is now quiet (takes no room) and
draws no label, still counted. A stacked mark that doesn't fit keeps its
line for the caret but draws nothing below the margin (CodeRabbit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A paragraph with keep with next measures the paragraph after it before it is
placed (next_first_line). That measurement called layout_para directly, so
every paragraph following a heading was laid out twice in each layout pass:
once to measure it and once, through the cache, when it was placed.

The measurement now goes through the layout cache under the key
para_labelled uses (Ctx::para_ahead) when its inputs are the same: no
proofing, no typed word, not inside a text box, no inline text boxes that
resize, the body's tracked-deletion view. Otherwise it is laid out on its
own as before. It counts nothing (list labels, equation numbers and the
page-total flag are restored), so pagination is unchanged.

Adds crates/engine/examples/export_bench.rs, which saves a long generated
document (the sample document 200 times, 259 pages) through io::save_bytes
and prints wall times:

  cargo run --release -p wordcraft-engine --example export_bench -- pdf 200 9

PDF export on that document, interleaved with main (Ryzen, 16 threads):
median 286 ms -> 256 ms (-10.6 %). The PDF bytes are identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shortcuts that give the same answers as the lookups they skip:

- is_rtl: nothing before U+0590 is right to left, so Latin, Greek and
  Cyrillic text skips the bidi class search.
- strong_rtl and is_mark: ASCII letters are the only strong ASCII
  characters, and no ASCII character is a mark.
- cluster_starts: in ASCII text every character starts a grapheme except LF
  after CR, and no ASCII character joins a cluster.
- display lines: a glyph run's vectors and text are sized up front, and the
  symbol-font check is made once per run instead of once per cluster.
- PDF glyph runs: the baseline (the y most glyphs share) is only worked
  out for italic runs, the only ones that use it, and a run on one baseline
  returns it without counting.

Tests check each shortcut against the full lookup (every code point for the
bidi classes, every ASCII pair for the clusters).

PDF export of the export_bench document, interleaved with main: median
293 ms -> 241 ms (-18 % with the previous commit). The PDF bytes are
identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ui: craft_ui::ComboBox everywhere and the combo arrow popup on craft_ui::combo::Menu

Repin craft-libs to aiongg/craft-libs 62bb0e1d (dropdown regrow). Ban egui::ComboBox in clippy.toml.

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 6af63481 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)
#3995: Thai one-face fallback tests skip unless a Thai font with Latin is installed
#3872 follow-up: font table found by its stored spelling; privacy scrub keeps attribute values well-formed
#3907: continuous sections running off a page go onto the next; empty section marks in a row stack to the page bottom
Each shaping call let harfrust compile a new shape plan (the face's
lookups for the run's script, direction, language and features), which
took about as long as shaping a short run. Each thread now keeps up to 64
plans (the oldest dropped to make room), found by face and harfrust's
ShapePlanKey::matches, and passes the plan to the shaper. A kept plan is
only used for the face it was made for: the face id (from one process-wide
counter, so no two faces share it) together with the font bytes' address,
length and face index. The plan is the one the shaper would have made for
the buffer, so the glyphs are the same; tests shape with kept and fresh
plans and compare, and check the per-thread bound.

PDF export of the export_bench document (259 pages), interleaved with main
(A/A within 1 %): median 421 ms -> 319 ms (-24.2 %), measured on a loaded
machine; on a quieter run earlier 294 ms -> 224 ms (-23.8 %). PNG export of
page 1 (which lays out the whole document): about -34 %. The PDF and PNG
bytes are identical to main's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge pull request #4602 from Silvertree2010/perf/export-speed
Some checks failed
sonarcloud.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (push) Failing after 0s
ci.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (pull_request) Failing after 0s
nix.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (pull_request) Failing after 0s
sonarcloud.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (pull_request) Failing after 0s
ci.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (push) Failing after 0s
nix.yml / Merge pull request #4602 from Silvertree2010/perf/export-speed (push) Failing after 0s
Printing / Print (macos-latest) (push) Has been cancelled
Printing / Print (ubuntu-24.04) (push) Has been cancelled
Printing / Print (windows-latest) (push) Has been cancelled
Printing / Print (macos-latest) (pull_request) Has been cancelled
Printing / Print (ubuntu-24.04) (pull_request) Has been cancelled
Printing / Print (windows-latest) (pull_request) Has been cancelled
4b8b06fe03
Speed up PDF export by about 24 %
alf merged commit 4b8b06fe03 into main 2026-10-27 20:37:15 +00:00
alf deleted branch chore/sync-upstream-20261027 2026-10-27 20:37:16 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/wordcraft!11
No description provided.