* font-catalog: hand fontique only bounded font-store files
fontique 0.11 imports a collection by registering the whole file once
for each face in it, scanning every face again each time and rebuilding
the family's font list, so a downloaded collection whose header declares
many faces costs far more than its size. The store is now walked here
(bounded depth and file count, no symbolic links) and collections that
declare more than 64 faces are left to the catalog's own scan, which
reads each face once.
* font-catalog: load font-store files one at a time and keep fontique's walk
fontique 0.11 re-adds every font gathered in one load_fonts_from_paths
call to its family for each face it registers, so handing it the whole
store at once repeats the store's fonts quadratically in the file count
(126,230 family entries for 2,084 faces on a 400-file test store, 4 s;
one call per file gives the same families, fonts, order and default
fonts with 2,084 entries in 90 ms).
The store walk now matches what fontique did with the folder before:
links are followed (to regular files and folders, each folder once),
depth 16, read_dir order, with a 200,000-entry budget like the
catalog's scan. Pipes, devices and dangling links are skipped.
* font-catalog: bound name records before pairing legacy names
The scanner paired every legacy family record with every legacy style
record of the same language before removing duplicates, so a small name
table repeating those records allocated millions of strings (a million
pairs from 4,000 records). Name records are now read per ID up to a cap,
deduplicated as they are read and kept up to a cap, and the legacy pairs
have a budget of their own.
* font-catalog: count distinct legacy pairs against the pair budget
Collect the legacy (family, style) pairs into a sorted set and stop at
MAX_LEGACY_PAIRS distinct pairs, so the same pair repeated across
languages cannot use up the budget. Output order is unchanged (sorted,
deduplicated), and the test now expects exactly the full budget.
* address review: typographic family decided by name(), distinct-text cap for all-language names, document the legacy pair cap
* address review: keep selected full and PostScript names in lookup keys past the name cap
* craft-font-catalog: run the Unix font-folder tests only on Unix
Five tests build an Os::Unix FontEnv from Unix paths (/home/me, <dir>/sys/fonts</dir>).
Windows doesn't treat those paths as absolute, so the tests failed there. Production code
is unaffected: on Windows FontEnv::from_process picks Os::Windows, whose folders never go
through the Unix path logic. FontEnv's docs now say its paths follow the host's path rules.
The font-store workflow, which already triggers on crates/font-catalog, now also runs
craft-font-catalog's clippy and tests on Linux and Windows.
Refs #619
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* craft-font-catalog: keep the store override and no-store tests on Windows
These assertions don't depend on Unix path rules, so they now sit in their own
ungated test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* craft-font-catalog: verify store override precedence
Exercise the override with platform defaults present on every OS variant.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
An <include> naming a folder listed, collected and sorted the folder's
entries before any budget applied, and again for every repetition, so a
configuration repeating one include made a single discovery call walk
the same folder thousands of times. Include folders are now checked
against the depth and file budgets first, listed at most once (by
canonical path), and all listings share a cap on entries.