Commit Graph
83 Commits
Author SHA1 Message Date
Dylan M. Taylor e5cffe7641 Merge pull request #4233 from VoiceLessQ/fix/small-cleanups
Small fixes: MERGEFIELD in any case, 18 SonarCloud closures, one unused constructor
2026-10-25 16:45:39 -04:00
skylar taylor-barrick 5b46f9ba4d M-egui037: fix fontless tests and document migration behavior 2026-10-25 15:24:23 +01:00
VoiceLessQ 65a0dc8dc6 Method paths for 18 closures that only call a method (SonarCloud S1612)
SonarCloud's analysis of main at b4da59f0c lists 23 closures such as `|v| v.as_slice()` that hand their argument straight to one method. This passes the method itself: `Vec::as_slice`, `str::to_ascii_lowercase`, `f64::total_cmp` and the like, all forms the repo already uses elsewhere. Behaviour is unchanged.

Five stay. The four in crates/proof/src/es/mod.rs sit in code that #4191 replaces, and its replacement already uses `PoisonError::into_inner`. In crates/engine/src/io/safe_save.rs the path would be `<dyn std::error::Error + Send + Sync>::is::<Guided>`, which reads worse than `|inner| inner.is::<Guided>()`.
2026-10-25 01:19:28 -02:00
skylartaylor a605fa5ca7 M-EGUI037: reconcile WordCraft main and preserve IME editing 2026-10-25 02:19:38 +02:00
aiongg b78c37bd7e Fonts: the web build embeds only craft-fonts' Georgian interface face, not the 4.7 MB Japanese one (#3888) 2026-10-24 21:51:00 +00:00
skylartaylor c4974d9e8d egui037: reconcile current main, qualify dependency pins and preview accessibility 2026-10-24 23:22:06 +02:00
aiongg cbc8a23cb2 Merge PR #3888: Release: embed the current craft-fonts, with the Georgian face 2026-10-24 20:38:41 +00:00
Dylan M. TaylorandClaude Sonnet 5.5 ba7e7293e4 Sonar S1612: pass PoisonError::into_inner instead of a closure (#4102)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:33:12 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 01d0c63451 Sonar S1612: use fn paths for simple method closures (#4103)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:33:08 -04:00
47edcd2ff2 chore: resolve SonarCloud maintainability issues (#4083)
* chore: resolve SonarCloud maintainability issues

* fix: restore compiling refactors, revert behaviour changes, run cargo fmt

- fontdb::norm: keep the closure for filter (char::is_alphanumeric takes
  self, not &self, so it does not fit Iterator::filter).
- story.rs: write_mark_rpr needs &mut self (rev_attrs, rpr_change).
- Revert the viewport meta change and the return 0 added to
  workspace_version/sha256, which changed behaviour or masked failures.
- cargo fmt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Import Document in odt page_parts after dropping glob re-export

* fix: apply_kind_properties binds ContentControl; cell_ref keeps char closures

* fix(engine): pass case helpers by value (clippy needless borrows)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-24 03:54:19 -04:00
skylartaylor fd071202e7 E37: migrate WordCraft to egui 0.37 with guarded IME and capture lifecycle 2026-10-24 08:30:31 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 4081b5f285 fonts: expect the bundled Thai face from the embedded font list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-24 01:21:49 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 b7d07b1b13 fonts: check the bundled Thai face covers the run when craft-fonts embeds one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-24 01:04:14 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 a781f90fc0 Release: embed the current craft-fonts, with the Georgian face
Pin craft-fonts a71c20e3 in ci.yml, freebsd.yml and release.yml; web-craft-fonts so the web
build keeps the Geor face; the interface font definitions add it; the Thai run test
accepts the embedded Thai face that pin brings (#3561).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-23 02:27:22 +04:00
aiongg acfdc0cb5f Merge PR #2500: Resolve installed fonts by PostScript face name
Test-font pins: #3389's kept, #2500's dropped (layout tests.rs, tests_pages.rs, render lib.rs). crates/fonts/src/fontdb.rs: #2500's PostScript-name match moved into #3078's family_paths.
2026-10-22 01:50:29 +00:00
aiongg 3017804459 Integration: cargo fmt 2026-10-22 01:40:29 +00:00
aiongg 61addba013 Merge PR #3078: #1549: a Thai run with Latin finds one installed font covering it all
ROADMAP.md: status line once (this change first, then main's); progress-log and history rows union in date order
docs/layout-parity.md: status line once (this change first, then main's); history rows union in date order
2026-10-22 01:22:12 +00:00
aiongg 029945a313 Integration: #2673 Khmer substitutes return the (list, flag) pair after #3245 2026-10-22 01:21:47 +00:00
aiongg 13e33ad072 Merge PR #2681: Layout: a Symbol bullet's line keeps Symbol's height without the font
docs/layout-parity.md: one status line naming this change first, then main's; history rows union
2026-10-22 01:21:47 +00:00
aiongg cb8d365923 Merge PR #2673: Fonts: Times New Roman keeps Liberation Serif under the roman-font rule (#1613)
docs/file-format-parity.md: one status line naming this change first, then main's
2026-10-22 01:21:32 +00:00
aiongg 32fe53c0ac Merge PR #2136: Linux: scan the Flatpak host font folders (#1937)
crates/fonts/src/fontdb.rs: PR's new test added before main's renamed run_fallback_is_cached_per_char_set
2026-10-22 01:20:42 +00:00
aiongg 78f2ef78c6 Merge PR #3245: Substitute a system Khmer font for a missing Khmer document font 2026-10-22 01:19:49 +00:00
aiongg 23e1985189 Merge PR #2104: Fonts: emoji prefer a colour emoji font on Windows (#1754, #1874) 2026-10-22 01:19:49 +00:00
Магда М.Г. 7f2f45743a Layout: Apple's one-em Symbol takes Windows Symbol's line height, as in Word for Mac
Word for Mac spaces Symbol lines at 1.222 em (measured at 11 and 20 pt)
even with Apple's Symbol installed, whose own line is one em. Symbol's
metrics now apply when the resolved face is one em tall as well as when
the font is substituted (fonts::word::symbol_line).
2026-10-20 12:14:18 +03:00
Mikael Tollefsen 50a89f4fa5 #1549: a run fallback is cached under the face count it chose from
fallback_for_run cached its answer under the face count read after the
search. A face loaded in between by another thread (its own search, or a
family a document names) made a miss look current: later lookups at the
new count got the stale miss (review on #3078). The search now returns
the count of the loaded faces its last choice was made from, and the
answer is cached under that; anything loaded since makes the next lookup
search again. No lock is added, so cached lookups from parallel layout
stay contention-free.
2026-10-20 11:06:44 +02:00
In MeanandClaude Sonnet 5.5 8f30acf112 Substitute a system Khmer font for a missing Khmer document font
A missing Khmer OS font drew in whichever loaded Khmer font covered the text, usually a
wider Khmer OS face, so lines wrapped and fixed-height text boxes hid their last line.
Word uses the system Khmer font; so do we now.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:00:33 +07:00
Mikael Tollefsen 43335e7c0e #1549: the run search goes past a collection and loads a family whole
Two holes in the whole-run fallback search (review on #3078):

- The coverage index keeps one coverage per file, so a font collection
  whose faces only together map a run matched it; the search loaded that
  family and stopped, returning no face even when a later font covered
  the run. It now goes on to the next file that maps the run.
- A single-character fallback may have loaded one file of a family (its
  Italic, say). The run search then treated the family as loaded and
  added only the file it reached first, so a regular run could be drawn
  in Bold although the Regular file was installed. It now loads whatever
  of the family isn't loaded yet.

Files loaded by family name are now recorded in the index too, so no
search loads a file a second time.

Tests: a split-coverage collection before a covering font; a family
whose Italic a character fallback loaded, reached at its Bold file first.
Both fail without the change (no face; Bold).
2026-10-20 09:11:35 +02:00
Mikael Tollefsen 8d16b26630 #1549: a Thai run with Latin finds one installed font covering it all
On Linux the run fallback loaded the script's preferred family (Noto Sans
Thai, which has no Latin letters) and stopped: every character had a face,
so an installed font mapping the whole run (IBM Plex Sans Thai) was never
tried, and a Thai + Latin run was split across two faces. Three Thai tests
failed on machines with Noto Sans Thai installed.

When no loaded face covers the run, the search now looks through the
coverage index for the first installed file mapping the whole run. It
loads that file's whole family, since path order can reach the Bold
file before the Regular. It also looks at the loaded faces again even
when it loaded nothing itself: a concurrent search may just have
loaded the font and taken its files off the index, and the miss would
otherwise be cached.

Regression test: a_run_no_preferred_face_covers_whole_loads_an_installed_font_that_does
(synthetic fonts, independent of what is installed).
2026-10-20 09:11:29 +02:00
Магда М.Г. e6e007d018 Symbol (PCL6) keeps Symbol's line metrics; restore the STYLEREF row in layout-parity 2026-10-20 05:18:11 +03:00
Магда М.Г. af2eb4c6ad Merge remote-tracking branch 'up/main' into up-symbol-font-line-height
# Conflicts:
#	crates/layout/src/tests.rs
#	docs/layout-parity.md
2026-10-19 22:48:35 +03:00
Магда М.Г. bb4c579a4d Merge remote-tracking branch 'up/main' into up-fonts-roman-known-substitutes
# Conflicts:
#	crates/fonts/src/word.rs
#	crates/layout/src/para.rs
#	docs/file-format-parity.md
2026-10-19 22:46:07 +03:00
Fin Warman 7d80ba4caa M711: merge main and bind font geometry fixtures 2026-10-19 17:28:17 +01:00
492aceb960 Fonts Word embeds as subsets lay out the text set in them (#2240) (#2540)
* #2240: fonts Word embeds as subsets lay out the text set in them

Embedded fonts were registered under the family inside the font file. Word
embeds a subset ("embed only the characters used") under a made-up family
(___WRD_EMBED_SUB_46) and the text asks for it by the font table's name
(OBRBWW+Century Schoolbook), so it still fell back to a substitute. Each
embedded file now comes with its font table name, and its faces go by that
name when they don't already.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #2240: the black-circle fallback test passes its font's table name

main's new `circle_checks_face_coverage` test (#2582) called `add_document_fonts` with bare font
bytes; with this branch each embedded font comes with the name the document's font table gives
it, so the test passes "Times New Roman" alongside the face it renames to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 10:28:52 -04:00
69c2414615 Fonts: bold Arial Black is not emboldened again, as in Word (#1750)
Old releases of heavy faces (the core-fonts Arial Black) claim weight 400 in
OS/2, so bold text in them was drawn with synthetic bold. Current releases say
900 and Word draws bold Arial Black unchanged. A static face whose file says less
than semibold now takes the weight its family's last word names: Black/Heavy 900,
ExtraBold/UltraBold 800. Files that already declare a heavy weight keep it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 09:55:11 -04:00
Ian Holloway f8ffab72e2 Tests: keep font-cache misses independent of optional Thai fonts (#1981)
Assisted-by: GPT-6

Signed-off-by: IanHollow <72767437+IanHollow@users.noreply.github.com>
2026-10-18 09:38:06 -04:00
.CooCoo 438dec0d61 Fonts: the font scan leaves out faces with no outline or color bitmap tables (#1972)
The system font scan (file_face_names) also catalogs faces with none of
the tables skrifa reads glyph outlines from (glyf, CFF, CFF2, VARC) and
none of the color bitmap tables the renderer draws (sbix, CBDT). On
macOS 27.0.1 the scan of /System/Library/Fonts catalogs "GB18030 Bitmap"
(Supplemental/NISC18030.ttf), and the font list shows it. The face
stores its glyphs as bdat bitmaps and maps 27,544 characters.
FontDb::outline returns an empty path for each of them, and the face has
no color glyph tables. The renderer draws none of them.

file_face_names now leaves out a face whose table directory has none of
those six tables. It reuses OUTLINE_TABLES from the interface CJK
fallback (#1250). VectorCraft's font scan checks the four outline tables
(storytold/vectorcraft#781). WordCraft's renderer also draws sbix and
CBDT bitmaps (#1504). Noto Color Emoji has CBDT and none of the outline
tables, and the scan keeps listing it.
2026-10-18 09:37:50 -04:00
fa755e9de4 Fonts: restore missing strokes in hint-reliant Chinese fonts (#2389)
Co-authored-by: xyz9516 <19662679+xyz9516@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:54:20 -04:00
eff1444f08 Fonts: bounded family caches; math follows font changes (#1354) (#1929)
* WIP for #1354

* Fonts: bound the family caches and refresh math resolution on font changes (#1354)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fonts: test math font lookup against a really installed and removed font (#1354)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:41:10 -04:00
Antoine BoxhoandBrandon Thomas 1c8c352cf5 #1549: one Thai face for a run in a missing Thai font (#2175)
A paragraph in a Thai font that isn't installed (TH Sarabun New, Angsana
New, Cordia New, the UPC families…) drew its Thai letters in one fallback
face and the Latin letters, digits and baht sign in a Latin substitute at
a visibly different size. Word substitutes one font (Cordia New) for the
whole run.

Thai families now have their own substitute lists (Cordia New and
Leelawadee UI on Windows, Thonburi on macOS, Noto Sans Thai and the TLWG
fonts on Linux; serif families prefer Angsana New, Sathu or Noto Serif
Thai), and the first listed face with Latin letters and digits as well
as Thai wins. When the substitute still lacks some of the run's Thai or
Latin text, the run moves to one face covering it through
FontDb::fallback_for_run, the generalised East Asian run fallback. Only
Thai fonts get this: a missing Latin font keeps Latin text in its own
substitute, a run with its own complex-script font keeps it for the Thai
letters, and a missing roman-classed Thai font is no longer drawn in
Cambria.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:02:18 -04:00
Fin WarmanandBrandon Thomas a3fcb9ed47 Fonts: keep Arial Unicode MS fallbacks proportional (#2657)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 03:45:37 -04:00
Fin WarmanandBrandon Thomas bd0521d476 Prefer a covering text face for missing black-circle glyphs (#2582)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 03:23:05 -04:00
Fin WarmanandBrandon Thomas db0affc0d3 Recognize the Symbol PCL6 font alias (#2521)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 03:19:40 -04:00
Fin Warman 74c1f26c4e Resolve exact OpenType full font names (#2516) 2026-10-18 03:19:21 -04:00
Магда М.Г. e60c699775 Layout: a Symbol bullet's line keeps Symbol's height without the font
Word sizes a line by the fonts in it, and a bullet in Symbol (Word's
default, U+F0B7) has a taller ascent than Calibri or Times New Roman.
Without Symbol (Linux, macOS without Office, the web build) WordCraft
draws the bullet from another face and used that face's height, so every
bulleted line was shorter than Word's: 14.5 pt against 15.1 pt in
Calibri 11 pt at 1.08 spacing, 14.9 against 15.7 in Times New Roman 12 pt.

symbol_font_metrics gives Symbol's and Wingdings' ascent and descent as
Word's PDFs state them, and a run in one of them that isn't installed
takes them. The label's ascent now comes from its style, so the existing
rule (the label's extra ascent added unscaled) sees them.

Measured in Word 2016: Calibri 11 / Times 12 bullets 15.08 / 15.72 pt,
WordCraft now 15.07 / 15.75 pt. On 251 real documents against Word PDFs,
page breaks at the same word 45.4% -> 50.1%.
2026-10-17 12:31:01 +02:00
Магда М.Г. 6a60779105 Fonts: Times New Roman keeps Liberation Serif under the roman-font rule (#1613)
#1613 draws a missing font in Cambria when the font table classes it as
roman, as Word does. Times New Roman is roman in every font table, so
where it isn't installed (Linux, the web build) every Times document came
out in Caladea: lines 2.1 pt taller at 12 pt and different line breaks.
Word always has Times New Roman, so it never applies that rule to it.

The rule now leaves alone a font whose substitutes are chosen by its name
(a metric-compatible clone or the same design under another name: Times,
Arial, Courier New, Palatino, the symbol, Hebrew and Persian fonts).
Fonts with no clone of their own (Cambria, Georgia, brand fonts) still
follow it.

Checked on 251 real documents against PDFs from Word: exact page counts
201 -> 229, page breaks in the same place 45.4% -> 51.9%.
2026-10-17 11:50:57 +02:00
Fin Warman 09f065c11f 286: resolve installed PostScript font names 2026-10-16 13:48:31 +01:00
tydude001andClaude Opus 5.5 57a000e978 Linux: scan the Flatpak host font folders (#1937)
Inside a Flatpak, /usr/share/fonts and /usr/local/share/fonts are the runtime's and the home font
folders aren't exposed, so WordCraft listed only the runtime's fonts. Flatpak mounts the host's
system, local and user fonts at /run/host/fonts, /run/host/local-fonts and /run/host/user-fonts
for every app, and its main branch (after 1.19.2) also mounts ~/.fonts at
/run/host/user-fonts-legacy when the XDG user font folder exists too; scan those as well.
Folders that don't exist are skipped, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 11:11:34 -05:00
Kaan IlterandClaude Opus 5.5 624ce0bdc2 fix(fonts): emoji prefer a colour emoji font on Windows
Fallback put Segoe UI Symbol before Segoe UI Emoji, and Symbol has
monochrome glyphs for some emoji (✅), so they drew in black and white
and tests_color_glyphs failed on Windows. Characters with default emoji
presentation now rank the colour emoji fonts first, both when loading a
system fallback and when choosing among loaded faces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:44:48 +01:00
Brandon Thomasandheogun e5d9b3e7cf i18n: add Korean UI catalog and font fallback (#1216)
Korean interface catalog and Hangul font fallback by @heogun (#1216), merged with main.

Co-authored-by: heogun <mumal@MP.local>
2026-10-14 23:44:26 -04:00
60b9500347 Web: add option to load system installed fonts in dropdown (#1390)
* feat(web): add option to load system installed fonts in dropdown

Add explicit 'Load System Installed Fonts…' button in font dropdowns for web (Wasm).

- Dispatches font.loadSystem via transient user activation on click
- Calls window.queryLocalFonts() to enumerate and load installed fonts into FontDb
- Invalidates font family cache in FontPreviews upon new font installation
- Complete localization across all 18 languages
- Credit GhostMitra in contributors/people.toml

* fix(ui, engine): canvas focus after chrome click and checked file access in sniff

* Revert "fix(ui, engine): canvas focus after chrome click and checked file access in sniff"

This reverts commit b0c925bf79.

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 23:24:19 -04:00