Skip to content

fix: render linked SVG badges completely - #63

Open
RichardCao wants to merge 4 commits into
aydiler:mainfrom
RichardCao:fix/svg-badge-rendering
Open

fix: render linked SVG badges completely#63
RichardCao wants to merge 4 commits into
aydiler:mainfrom
RichardCao:fix/svg-badge-rendering

Conversation

@RichardCao

@RichardCao RichardCao commented Aug 6, 2026

Copy link
Copy Markdown

Summary

  • keep egui's inline cursor after a linked image instead of rendering an empty link label that resets the wrapped row
  • add a MIME-aware SVG fallback loader for dynamic URLs that do not end in .svg, such as the GitHub stars Shields endpoint
  • validate the fontdb sans-serif alias for MIME-detected SVGs and, only when it is unavailable, resolve the concrete installed family through Fontconfig
  • cache MIME-decoded SVGs by URI and size hint, including the expected loader cache invalidation hooks

Problem

The badges at the top of this repository's own README expose three related rendering failures:

  1. ending an image-only link renders an empty Label, which moves egui's wrapped-row cursor back to the row start and makes subsequent badges overlap;
  2. egui_extras 0.33's SVG loader accepts only URIs ending in .svg, although Shields dynamic endpoints correctly return image/svg+xml;
  3. on a minimal Rocky Linux 9.5 installation, fontdb maps sans-serif to the unavailable FreeSans, while fc-match sans-serif resolves the installed DejaVu Sans. The GitHub badge therefore renders its shapes but drops Stars and the count.

The font issue is environment-triggered but not distro-specific: it can occur whenever the first parsed Fontconfig alias is not actually installed. A concrete reproduction and timing data were added to upstream fontdb issue #24.

The application-side resolver does not hard-code Rocky Linux font names. Existing valid aliases are preserved, fc-match is invoked only when the sans-serif mapping is unavailable on supported Unix targets, and its result must already exist in the loaded font database. Systems without the command retain their existing behavior.

Validation

  • cargo test --locked — 34 passed
  • cargo test --locked --manifest-path crates/egui_commonmark/egui_commonmark/Cargo.toml --features svg,svg_text,fetch --lib — 23 passed
  • cargo check --locked --manifest-path crates/egui_commonmark/egui_commonmark/Cargo.toml --no-default-features --features svg,fetch
  • cargo check --locked --manifest-path crates/egui_commonmark/egui_commonmark/Cargo.toml --no-default-features --features svg_text
  • cargo clippy --locked --bin md-viewer --no-deps -- -D warnings
  • manual README rendering on Rocky Linux 9.5: all five badges remain separate, and the extensionless GitHub badge displays both Stars and its count

@RichardCao

Copy link
Copy Markdown
Author

I simplified the font compatibility portion after reviewing its scope.

The implementation now repairs only the generic sans-serif mapping used by these SVG badges. It preserves an existing valid mapping, invokes fc-match --format=%{family[0]} sans-serif only when that mapping points to an unloaded font, and accepts the result only when the returned family is already loaded by fontdb. If Fontconfig is unavailable or returns no usable match, behavior is unchanged.

This removes the heuristic scan of arbitrary loaded fonts and the unnecessary serif/monospace handling (62 lines removed net from the previous revision), while retaining the locally verified fix without hardcoded distribution-specific font names. The loaded-family check follows fontdb's exact family-name matching semantics.

Revalidated with the full test suite, feature-specific checks, Clippy with warnings denied, and a manual Linux UI check of the README badges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant