From 7ee3cea875750be1c0338c64a23270e566e474ae Mon Sep 17 00:00:00 2001 From: Dmitrii Khlapov Date: Mon, 12 Oct 2026 16:46:24 +0200 Subject: [PATCH] Fonts: documents use the craft-fonts Simplified Chinese face too (#888) Builds with craft-fonts (releases, the FreeBSD job) put only its Japanese faces in the document font database; Noto Sans CJK SC served the interface alone. Simplified-only ideographs in a document then had no face unless the system had one, and the run-level CJK pick from #567 found no face covering a mixed run, which the FreeBSD job's east_asian_run_uses_one_face_covering_the_whole_run caught. The Chinese craft faces now follow the Japanese ones (Mincho stays first for Japanese text). fallback_reads_each_installed_font_file_once_however_many_characters_miss used U+30001.., part of which Noto Sans CJK SC maps (CJK Extension G); it now uses Supplementary Private Use Area-A, which no font here maps. Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 Co-authored-by: Brandon Thomas --- ROADMAP.md | 6 ++++-- crates/fonts/src/fontdb.rs | 5 +++-- crates/fonts/src/tests_sysfonts.rs | 6 ++++-- docs/parity-checklist.md | 8 +------- docs/target-app-parity.md | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 0d7ac42..c0acdd4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ **Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** trivial (table border drags with Ctrl and Alt, from the left edge and of selected cells, #711; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** trivial (documents use the craft-fonts Simplified Chinese face; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 WordCraft aims for complete parity with Microsoft Word, then goes further on speed, openness and agent control. This page is the summary; the assessment is @@ -14,7 +14,7 @@ agent control. This page is the summary; the assessment is | Number | Value | Kind | |---|---|---| -| Ribbon/menu catalog coverage | **485 / 500 (97.0%)** | measured (`cargo xtask parity` → [`docs/parity-checklist.md`](docs/parity-checklist.md)) | +| Ribbon/menu catalog coverage | **487 / 502 (97.0%)** | measured (`cargo xtask parity` → [`docs/parity-checklist.md`](docs/parity-checklist.md)) | | **Feature breadth** (weighted, incl. dialog options, styles, languages beyond the ribbon) | **~80%** | estimated | | **Ready for real work** (full target) | **~60%** (55–63%) | estimated, additive weighted sum over the dimensions | | **Mainstream practitioner** | **~55%** | estimated: weekly-work depth × discounts for interaction (×0.93), stability (×0.90), file exchange (×0.90) | @@ -171,6 +171,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm |---|---| | 2026-10-11 | Table border drags like Word's (#711): Ctrl shares a column border's change among the columns right of it (the table keeps its width), the table's left edge moves a left-aligned table's indent (a centred or right-aligned table keeps its alignment, as in Word), a border of cells selected across moves only in their rows, and Alt shows the column widths on the ruler | | 2026-10-11 | Tables on the rulers (#700): with the caret in a table the horizontal ruler marks its row's column borders and the vertical ruler its rows' bottoms; dragging a marker resizes the column (the columns right of it move along; with Shift the neighbour makes up the difference) or the row, one undo step, Escape cancels; in a cell the indents and tabs are measured from the cell | +| 2026-10-12 | Builds with craft-fonts draw simplified-Chinese characters in documents from the bundled Noto Sans CJK SC (it was only used by the interface), so a CJK run gets one face covering it; fixes the FreeBSD job's `east_asian_run_uses_one_face_covering_the_whole_run` failure after #567 | | 2026-10-12 | AutoCorrect capitals (#544): Correct TWo INitial CApitals (with exceptions), accidental cAPS LOCK, first letter of table cells; each undoable and switchable | | 2026-10-11 | Turkish (`tr`) interface completed (#774): 2,325 entries, every key of the Russian catalog (equation gallery, built-in style names, watermarks, paper sizes, preview tiles); the interface audit checks Turkish too | | 2026-10-12 | Navigation headings truncate within the resizable pane, with an ellipsis for long titles and full text on hover (#759) | @@ -269,6 +270,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm | 2026-10-12 | trivial | Progress log: Start screen at launch (#766) | | 2026-10-12 | trivial | Progress log: Alt+Q command search (#819); log table header fixed | | 2026-10-12 | trivial | Progress log: ribbon groups fit above their labels | +| 2026-10-12 | trivial | Progress log: craft-fonts Simplified Chinese in documents | | 2026-10-11 | trivial | Progress log and shipped languages: Turkish interface completed, 2,325 entries (#774) | | 2026-10-12 | trivial | Progress log: Navigation heading truncation (#759) | | 2026-10-11 | trivial | Progress log: Reading Mode implementation | diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index 02e3be1..1560158 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -855,11 +855,12 @@ fn style_italic(style: &str) -> bool { impl FontDb { /// A database holding the bundled fonts, then the craft-fonts Japanese faces (Mincho first, - /// so they are the fallback for Japanese text after the requested and bundled fonts; empty + /// so they are the fallback for Japanese text after the requested and bundled fonts), then the + /// craft-fonts Simplified Chinese faces, for the ideographs the Japanese fonts lack (both empty /// without `CRAFT_FONTS_DIR`), whose system font scan reads `font_dirs`. pub fn with_font_dirs(font_dirs: Vec) -> Self { let mut faces = Vec::new(); - let craft = crate::japanese_document_fonts().into_iter().map(|f| f.bytes); + let craft = crate::japanese_document_fonts().into_iter().chain(crate::chinese_fonts()).map(|f| f.bytes); for data in BUNDLED.iter().copied().chain(craft) { for f in enumerate_faces(data) { if let Some(mut face) = make_face(FontBytes::Static(data), f.index, f.family, f.style, f.legacy, f.coords) { diff --git a/crates/fonts/src/tests_sysfonts.rs b/crates/fonts/src/tests_sysfonts.rs index d51fd64..9082253 100644 --- a/crates/fonts/src/tests_sysfonts.rs +++ b/crates/fonts/src/tests_sysfonts.rs @@ -269,8 +269,10 @@ fn fallback_reads_each_installed_font_file_once_however_many_characters_miss() { let latin = db.face(FALLBACK_FAMILY, "Regular"); let found = db.fallback_for('\u{30000}', latin.id()).expect("the installed font maps it"); assert_eq!((found.family.as_str(), found.style.as_str()), (FAMILY, "Regular")); - // 2,000 distinct characters nothing maps: the index answers, no file is read again. - for cp in 0x30001..0x30001 + 2000 { + // 2,000 distinct characters nothing maps (Supplementary Private Use Area-A: no font here, + // bundled or craft-fonts, maps it; CJK Extension G after U+30000 is partly in Noto Sans CJK + // SC): the index answers, no file is read again. + for cp in 0xF_0001..0xF_0001 + 2000 { let c = char::from_u32(cp).unwrap(); assert!(db.fallback_for(c, latin.id()).is_none()); } diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 70fd819..0f22c6d 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -2,18 +2,12 @@ Generated by `cargo xtask parity` (`wordcraft-cli parity --markdown`): the word-processor feature catalog (`crates/engine/src/catalog.rs`) compared with the live command registry. -**485 of 500 catalog features have commands (97.0%).** +**487 of 502 catalog features have commands (97.0%).** | Tab | Live | Total | |---|---|---| | File | 22 | 22 | | Quick Access | 5 | 5 | -**484 of 499 catalog features have commands (97.0%).** - -| Tab | Live | Total | -|---|---|---| -| File | 21 | 21 | -| Quick Access | 4 | 4 | | Title Bar | 1 | 1 | | Home | 102 | 103 | | Insert | 47 | 53 | diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 10f3df6..2ff414d 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -13,7 +13,7 @@ The generated ribbon checklist is [`parity-checklist.md`](parity-checklist.md). | Number | Value | Kind | |---|---|---| -| Ribbon/menu catalog coverage | **485 / 500 (97.0%)** | **measured**: `cargo xtask parity` (re-derived this pass from `crates/engine/src/catalog.rs` against every `CommandSpec::new` id in the source; identical to the checked-in `parity-checklist.md`) | +| Ribbon/menu catalog coverage | **487 / 502 (97.0%)** | **measured**: `cargo xtask parity` (re-derived this pass from `crates/engine/src/catalog.rs` against every `CommandSpec::new` id in the source; identical to the checked-in `parity-checklist.md`) | | Feature breadth (weighted, beyond the ribbon: dialog options, citation styles, proofing languages, chart types, UI languages) | **~80%** | estimated | | Feature depth (weighted by use, table below) | **~68%** | estimated | | **Ready for real work** (full target) | **~60%** (range 55–63%) | estimated: weighted sum over the dimension table ([By dimension](#by-dimension)) |