Repository navigation
rust-fontconfig 3.0.0
Breaking Changes
FcPatternhas a new field:render_config: FcFontRenderConfigwas added. Code
using struct literal construction (FcPattern { name: ..., family: ... }) must add
render_config: FcFontRenderConfig::default()or use..Default::default().UnicodeRangeis now#[repr(C)]: Layout is guaranteed to match C{ uint32_t start; uint32_t end; }.
This was already the case in practice but is now an explicit contract.ffifeature now impliesasync-registry: The C bindings include the full
registry (background thread) API. Previouslyffionly impliedparsing+std.
New Features
Per-font rendering config from fonts.conf (#16)
On Linux, fonts.conf <match target="font"> rules are now parsed and exposed via
FcFontRenderConfig on each FcPattern. Supported properties:
| Field | Type | Description |
|---|---|---|
antialias |
Option<bool> |
Enable/disable antialiasing |
hinting |
Option<bool> |
Enable/disable hinting |
hintstyle |
Option<FcHintStyle> |
None, Slight, Medium, Full |
autohint |
Option<bool> |
Use autohinter |
rgba |
Option<FcRgba> |
Subpixel order (Rgb, Bgr, Vrgb, Vbgr) |
lcdfilter |
Option<FcLcdFilter> |
LCD filter mode |
embeddedbitmap |
Option<bool> |
Use embedded bitmaps |
embolden |
Option<bool> |
Synthetic bold |
dpi |
Option<f64> |
Per-font DPI override |
scale |
Option<f64> |
Scale factor |
minspace |
Option<bool> |
Minimum spacing |
All fields are None on macOS/Windows (use system defaults). New enums:
FcHintStyle, FcRgba, FcLcdFilter.
Async font registry C API
12 new C FFI functions expose the background-thread font loading API:
// Lifecycle
FcFontRegistry fc_registry_new(void);
void fc_registry_spawn(FcFontRegistry registry);
void fc_registry_shutdown(FcFontRegistry registry);
void fc_registry_free(FcFontRegistry registry);
// Priority-based font loading (blocks only for requested fonts)
FcFontChain* fc_registry_request_fonts(registry, stacks, counts, num, &out);
void fc_registry_chains_free(FcFontChain* chains, size_t count);
// Status
bool fc_registry_is_scan_complete(FcFontRegistry registry);
bool fc_registry_is_build_complete(FcFontRegistry registry);
// Query
FcFontMatch* fc_registry_query(FcFontRegistry registry, const FcPattern* pattern);
FcFontInfo* fc_registry_list_fonts(FcFontRegistry registry, size_t* count);
FcFontChain fc_registry_resolve_font_chain(registry, families, count, weight, italic, oblique);
FcFontPath* fc_registry_get_font_path(FcFontRegistry registry, const FcFontId* id);
FcFontMetadata* fc_registry_get_metadata(FcFontRegistry registry, const FcFontId* id);
FcFontRenderConfig fc_registry_get_render_config(FcFontRegistry registry, const FcFontId* id);
FcFontCache fc_registry_snapshot(FcFontRegistry registry);Unicode script detection helpers
New public functions for checking Unicode block coverage:
pub fn has_cjk_ranges(ranges: &[UnicodeRange]) -> bool;
pub fn has_arabic_ranges(ranges: &[UnicodeRange]) -> bool;
pub fn has_cyrillic_ranges(ranges: &[UnicodeRange]) -> bool;
pub fn has_hebrew_ranges(ranges: &[UnicodeRange]) -> bool;
pub fn has_thai_ranges(ranges: &[UnicodeRange]) -> bool;New public modules
Internal code has been restructured into public modules for better organization:
config-- OS-specific font directories, generic family expansion, tokenizationscoring-- Priority queue types and scoring heuristics for background loadingmultithread-- Scout and builder thread implementationsdisk_cache-- Disk cache serialization (behindcachefeature)utils-- Font file detection, family name normalization
Improvements
- 14% code reduction (8018 -> 6905 lines) through systematic deduplication
- FFI safety: Fixed
Vec::from_raw_partscapacity mismatch UB infc_registry_request_fonts - Code style: Flattened deeply nested
if letpatterns withlet-elseand functional chaining - CI: Added cross-compilation checks for WASM, iOS, iOS Simulator, Android targets;
fixed Windows MSVC example execution; removedcontinue-on-errorthat hid failures
C Example
New ffi/example_registry.c with 3 demos showcasing the azul-style fast startup pattern:
- Azul-style fast startup: spawn threads -> request only needed fonts -> render first frame
with 67/806 fonts loaded, remaining parse in background - Incremental loading: request UI fonts (69 loaded) -> monospace for code editor (90) ->
CJK for pasted Japanese text (116) - Old vs new API comparison: blocking
fc_cache_build()(806 fonts) vs async
fc_registry_request_fonts()(67 fonts, rest in background)
Migration from 2.0.0
// Before (2.0.0)
let pattern = FcPattern {
name: Some("Arial".into()),
family: Some("Arial".into()),
..Default::default()
};
// After (3.0.0) -- add render_config or use ..Default::default()
let pattern = FcPattern {
name: Some("Arial".into()),
family: Some("Arial".into()),
..Default::default() // render_config defaults to all-None
};If you were constructing FcPattern with all fields explicitly, add:
render_config: FcFontRenderConfig::default(),