tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
82.21k stars 2.47k forks source link

[bug] `cargo tauri icon` cannot find font-family for SVG <text> on Linux (Ubuntu) #10022

Closed cornmonger closed 3 months ago

cornmonger commented 3 months ago

Describe the bug

cargo tauri icon is having problems applying the font-family attribute in SVG files. This appears to be the case regardless of whether the font-family is indicated inline in a <text> element or as a <style> definition. It warns that it can't find the font and then does not render text when generating icons. Everything else appears to render.

This run, for example, is just with no font-family specified at all:

$ cargo tauri icon test.svg
    Warn No match for 'sans-serif' font-family.
    Appx Creating StoreLogo.png
    Appx Creating Square30x30Logo.png
    Appx Creating Square44x44Logo.png
   [...]

So far, this is reproducible on a relatively fresh install of Ubuntu Desktop 24 as well as an older install of Ubuntu Desktop 23.

Reproduction

  1. Follow the beta guide to setup Tauri via Cargo on an Ubuntu Desktop 24 system.
  2. Create a new Tauri beta app using cargo.
  3. Run cargo tauri icon test.svg against any SVG with a <text> element.
  4. ...
  5. No profit.

Here is a test SVG that I can reproduce with (test.svg):

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<text x="0" y="50" fill="white">hello</text>
</svg>

System info:

$ sudo apt install [...]
libwebkit2gtk-4.1-dev is already the newest version (2.44.2-0ubuntu0.24.04.1).
build-essential is already the newest version (12.10ubuntu1).
curl is already the newest version (8.5.0-2ubuntu10.1).
wget is already the newest version (1.21.4-1ubuntu4).
file is already the newest version (1:5.45-3build1).
libxdo-dev is already the newest version (1:3.20160805.1-5build1).
libssl-dev is already the newest version (3.0.13-0ubuntu3.1).
libayatana-appindicator3-dev is already the newest version (0.5.93-1build3).
librsvg2-dev is already the newest version (2.58.0+dfsg-1build1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Expected behavior

No response

Full tauri info output

WARNING: no lock files found, defaulting to npm

[✔] Environment
    - OS: Ubuntu 24.4.0 X64
    ✔ webkit2gtk-4.1: 2.44.2
    ✔ rsvg2: 2.58.0
    ✔ rustc: 1.78.0 (9b00956e5 2024-04-29)
    ✔ cargo: 1.78.0 (54d8815d0 2024-03-26)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-unknown-linux-gnu (environment override by RUSTUP_TOOLCHAIN)

[-] Packages
    - tauri [RUST]: 2.0.0-beta.22
    - tauri-build [RUST]: 2.0.0-beta.17
    - wry [RUST]: 0.40.1
    - tao [RUST]: 0.28.0
    - tauri-cli [RUST]: 2.0.0-beta.20
    - @tauri-apps/api : not installed!
    - @tauri-apps/cli [NPM]: 2.0.0-beta.20

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/

Stack trace

None. No crash.

Additional context

No response

roylaurie commented 3 months ago

This is a problem in fontdb, which is used by resvg (and usvg). There are actually two problems here:

  1. All fonts not working in text nodes. (solvable)
  2. Generic font families not working in text nodes. (requires a workaround)

Problem 1 can be solved by bumping the version of the resvg dependency to 0.42.0, initializing a fontdb database object with load_system_fonts(), and then passing that to the existing usvg call.

This works for me by altering the command function in tooling/cli/src/icon.rs :

let rtree = {
        let mut fontdb = usvg::fontdb::Database::new();  //+
        fontdb.load_system_fonts();  //+

        let opt = usvg::Options {
          // Get file's absolute directory.
          resources_dir: std::fs::canonicalize(&input)
            .ok()
            .and_then(|p| p.parent().map(|p| p.to_path_buf())),
            fontdb: Arc::new(fontdb),  //+
            ..Default::default()
        };

        let svg_data = std::fs::read(&input).unwrap();
        usvg::Tree::from_data(&svg_data, &opt).unwrap()  //*
      };

Problem 2 is up to the resvg / fontdb team to solve permanently. A workaround would be to call the system's fc-match for the handful of generic family names (serif, sans-serif, cursive, fantasy, and monospace) and use the appropriate fontdb setters to pre-configure those, then pass it to usvg.

Happy to submit a PR for this if needed.

amrbashir commented 3 months ago

@roylaurie a PR sounds fantastic, thanks for investigating

roylaurie commented 3 months ago

Ready for review. This fixes the first problem that I mentioned. Details are in the PR.