Skip to content

feat: add disable_system_fonts option to ignore system typefaces#28

Open
lhoward wants to merge 1 commit into
masterfrom
lhoward/disable-system-fonts
Open

feat: add disable_system_fonts option to ignore system typefaces#28
lhoward wants to merge 1 commit into
masterfrom
lhoward/disable-system-fonts

Conversation

@lhoward
Copy link
Copy Markdown

@lhoward lhoward commented May 19, 2026

Summary

Adds a new disable_system_fonts boolean to FlutterDesktopEngineProperties. When set, the engine installs a private fontconfig configuration containing only the directories of fonts declared in the bundle's FontManifest.json, so Skia sees no system fonts and renders missing glyphs as tofu rather than falling back to a system typeface.

Useful on embedded targets where the host font set may be unpredictable, sparse, or visually inconsistent with the app's intended design.

How it works

  • Parse flutter_assets/FontManifest.json and collect the unique parent directories of each declared font asset.
  • Build a minimal fontconfig XML — only <dir> entries, no system paths, no <cachedir> (the bundle is small; in-memory rebuild on each startup is microseconds, and we avoid assuming any writable home directory exists on the target).
  • Materialize the XML in a memfd_create() anonymous file and expose it to the engine via FONTCONFIG_FILE=/proc/self/fd/N. Nothing is written to the on-disk filesystem; the kernel frees the memfd when the fd is closed at engine shutdown.

The embedder itself never #includes a fontconfig header or links a fontconfig symbol — the actual parsing happens inside libflutter_engine.so, which already has libfontconfig.so.1 as a runtime dependency. So no new build-time dependencies (no libfontconfig-dev, no CMake changes).

API surface

  • FlutterDesktopEngineProperties.disable_system_fonts (new trailing field, defaults to false via zero-init — source-compatible)
  • flutter::DartProject::set_disable_system_fonts(bool) / disable_system_fonts() in the C++ wrapper

Test plan

  • swift build of the FlutterSwift wrapper that consumes this embedder builds clean
  • Verified memfd_create() + /proc/self/fd/N semantics: opening the proc path gives a fresh open file description with offset 0, so fontconfig reads the full XML from byte 0 even though the writer's fd is at EOF
  • Runtime test on a target with --enable-fontconfig engine and a bundle containing only a custom font — confirm system Roboto/DejaVu is no longer reachable

🤖 Generated with Claude Code

@lhoward lhoward added the enhancement New feature or request label May 19, 2026
@lhoward lhoward self-assigned this May 19, 2026
Adds a new boolean engine property that installs a private, in-memory
fontconfig configuration containing only the directories of fonts
declared in the bundle's FontManifest.json. With no <dir> entries
pointing at /usr/share/fonts (or any other system path), Skia inside
the engine sees only bundled fonts and renders missing glyphs as tofu
rather than falling back to a system typeface. Useful for embedded
targets where the host font set may be unpredictable, sparse, or
visually inconsistent with the app's design.

The config is materialized via memfd_create() and exposed to the
engine through FONTCONFIG_FILE=/proc/self/fd/N, so nothing is written
to the on-disk filesystem and the anonymous file is freed by the
kernel when the engine fd is closed at shutdown. No new build-time
dependencies — fontconfig itself is reached transitively through
libflutter_engine.so's existing libfontconfig.so.1 runtime link, and
the embedder source never includes a fontconfig header.

The option is exposed on FlutterDesktopEngineProperties (defaults to
false, so existing callers are source- and behaviorally unchanged)
and threaded through DartProject in the C++ wrapper.

Fixes: flutter-elinux/flutter-elinux#14
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App startup delay caused by fontconfig scanning system fonts on embedded Linux

1 participant