sile-typesetter / sile

The SILE Typesetter — Simon’s Improved Layout Engine
https://sile-typesetter.org
MIT License
1.63k stars 96 forks source link

Alegreya font not found on NixOS - how to debug? #1624

Open akavel opened 1 year ago

akavel commented 1 year ago

I'm working on a NixOS (via flakes) machine and with a separate home-manager setup (also via flakes). I have the Alegreya font installed via nix profile install nixpkgs#alegreya, and sile installed via home-manager (sile --version shows SILE v0.14.5 (Lua 5.3)). Running fc-match shows:

$ fc-match 'Alegreya:weight=80:size=10.0:slant=roman'
Alegreya-Regular.otf: "Alegreya" "Regular"

$ fc-match -v 'Alegreya:weight=80:size=10.0:slant=roman' | grep file
        file: "/home/akavel/.nix-profile/share/fonts/otf/Alegreya-Regular.otf"(w)

However, the font seems not found by SILE - when I try to render the following tmp.sil file:

\begin[class=plain]{document}
\font[family=Alegreya]
Hello \strong{world}!
\begin{script}
    local opts = {
        family = 'Alegreya';
        weight = 80;
    }
    local f = SILE.fontManager:face(opts)
    print('MCDBG f=' .. tostring(f and f.filename))
\end{script}
\end{document}

I see output like below:

$ sile --debug fonts tmp.sil 
SILE v0.14.5 (Lua 5.3)
<tmp.sil> as sil

[fonts] Looking for Alegreya;10;400;;normal;;LTR
[fonts] Resolved font family 'Alegreya' -> /nix/store/y1hybm8h1kln0hg06c42m4g1wsblc0ig-freefont-ttf-20120503/share/fonts/truetype/FreeMono.ttf
[fonts] Looking for Alegreya;10;700;;normal;;LTR
[fonts] Resolved font family 'Alegreya' -> /nix/store/y1hybm8h1kln0hg06c42m4g1wsblc0ig-freefont-ttf-20120503/share/fonts/truetype/FreeSerifBold.ttf<...pia16jrk0zfc9n3jx6s-sile-0.14.5/share/sile/core/sile.lua:363> as lua
MCDBG f=/nix/store/8cf5drzf1gswmcz9hh6jnw2ffxxxwy06-dejavu-fonts-2.37/share/fonts/truetype/DejaVuSans-ExtraLight.ttf

! Font family 'Alegreya' not available, falling back to 'FreeMono' at tmp.sil: in \vfill
[1] 

Curiously, when I change Alegreya to Gentium Plus in the tmp.sil file, the font seems properly detected, with a path in my ~/.nix-profile:

$ sile --debug fonts tmp.sil 
SILE v0.14.5 (Lua 5.3)
<tmp.sil> as sil

[fonts] Looking for Gentium Plus;10;400;;normal;;LTR
[fonts] Resolved font family 'Gentium Plus' -> /home/akavel/.nix-profile/share/fonts/truetype/GentiumPlus-R.ttf
[fonts] Looking for Gentium Plus;10;700;;normal;;LTR
[fonts] Resolved font family 'Gentium Plus' -> /home/akavel/.nix-profile/share/fonts/truetype/GentiumPlus-R.ttf<...pia16jrk0zfc9n3jx6s-sile-0.14.5/share/sile/core/sile.lua:363> as lua
MCDBG f=/home/akavel/.nix-profile/share/fonts/truetype/GentiumPlus-R.ttf
[1] 

Is there some way how I could try to debug why fontconfig, as used by SILE, does not seem to find the Alegreya font in my ~/.nix-profile tree? (FWIW, a ~/.nix-profile/share/fonts/ttf/Alegreya-Regular.ttf seems to also exist on my machine, though apparently fc-match picks the *.otf file.) I'm stuck and don't have more ideas what I could investigate further, and how to find if the issue is on SILE side, or on Nix/NixOS side, and in what way - any help would be appreciated!

akavel commented 1 year ago

Hm; I found some hints for debugging the fontconfig library by setting an FC_DEBUG environment variable, apparently accepting flags with values from 1 to 4096. Seems to dump some info when set before running sile, so I will try investigating through this.

Also, feels like it may potentially be related/the same issue as #1552.

edit: Hm, it looks like only the opentype/ and truetype/ subdirs of ~/.nix-profile/share/fonts/ are searched, so neither ttf/ nor otf/ are. Sounds like I will need to further debug where this is configured.

$ FC_DEBUG=8 sile --debug fonts tmp.sil 2>&1 | grep .nix-profile
adding fonts from /home/akavel/.nix-profile/lib/X11/fonts
cache scan dir /home/akavel/.nix-profile/lib/X11/fonts
adding fonts from /home/akavel/.nix-profile/share/fonts
adding fonts from /home/akavel/.nix-profile/share/fonts/opentype
adding fonts from /home/akavel/.nix-profile/share/fonts/truetype
[...]

edit 2: Not verified yet, but looks like a packaging bug in the alegreya font package in Nixpkgs/NixOS: it seems that practically all other font packages move stuff to the opentype/ and truetype/ dirs, with alegreya, alegreya-sans, and montserrat being the only exceptions I noticed. Will try to verify this locally and if confirmed, submit a PR to Nixpkgs. Still, in that case it would actually not seem related to #1552 (or is it?); also, I haven't found a place in Nixpkgs where those dir names would be configured (so maybe it is a builtin fontconfig thing?).

edit 3: Just tweaking the installPhase of the alegreya package to put the files in truetype/ & opentype/ did not, to my surprise, seem to have any influence on the sile outcome. Notably, files are there, but FC_DEBUG=8 still does not seem to show them being loaded. (Even after running fc-cache -r.) Seems I'm stuck, again :(

edit 4: Wooow, but running sile using its own flake.nix worked! Now that's weird to me, and would seem even more to suggest that's maybe some NixOS packaging issue:

$ nix run github:sile-typesetter/sile/v0.14.5 -- --debug fonts tmp.sil
SILE v0.14.5-1a86520-flake (Lua 5.3)
<tmp.sil> as sil

[fonts] Looking for Alegreya;10;400;;normal;;LTR
[fonts] Resolved font family 'Alegreya' -> /nix/store/5dz0bix2mwdvwl7gnw7iy1l7f7qib4zq-home-manager-path/share/fonts/opentype/Alegreya-Regular.otf
[fonts] Looking for Alegreya;10;700;;normal;;LTR
[fonts] Resolved font family 'Alegreya' -> /nix/store/5dz0bix2mwdvwl7gnw7iy1l7f7qib4zq-home-manager-path/share/fonts/opentype/Alegreya-Bold.otf<...wms6r-sile-0.14.5-1a86520-flake/share/sile/core/sile.lua:363> as lua
MCDBG f=/nix/store/5dz0bix2mwdvwl7gnw7iy1l7f7qib4zq-home-manager-path/share/fonts/opentype/Alegreya-Regular.otf
[1] 
alerque commented 1 year ago

@doronbehar Does the difference in behavior observed in SILE's calls to fontconfig when used directly as a Flake vs. home-manager make any sense to you at all?

Is it possible we're looking at a bug it Nix itself (not just packaging) where it is not allowing the original SILE build to pick up on the new paths in the updated font package?

alerque commented 1 year ago

Tentatively marking this as not our bug, but I'm going to keep it open for tracking until we're certain it's a Nix issue and get a fix in the works.

alerque commented 1 year ago

I'm pretty sure I understand what #1552 is about and that it has no relation to this.

Question: Are you running your tests in a SILE source directory or some other workspace? There are some known issues with trying to run SILE from your system while you happen to have PWD of a copy of the SILE sources because it prioritizes ./ over other paths to load resources from. That leads to really confusing mismatches.

akavel commented 1 year ago

Are you running your tests in a SILE source directory or some other workspace?

Other workspace - a directory containing a small personal git repository with my custom *.sil file[s].

alerque commented 1 year ago

Does that other workspace by chance have a nix devel environment or shell of its own that might be excluding your home manager supplied environment and using only its local dependencies?

doronbehar commented 1 year ago

@doronbehar Does the difference in behavior observed in SILE's calls to fontconfig when used directly as a Flake vs. home-manager make any sense to you at all?

Is it possible we're looking at a bug it Nix itself (not just packaging) where it is not allowing the original SILE build to pick up on the new paths in the updated font package?

I've never encountered such issue before.. From what I know font-config related issues are complicated, and I'm not experienced in debugging them... I too would suggest to look for differences in the environment of these two sile executions - try to override the wrapper in the flake version and in home-manager's version such that it will write the environment in which it runs sile to a text file (env > ~/sile-{HomeManager,flake}.env or alike).

alerque commented 1 year ago

Good idea. You don't have to override the wrapper anywhere, as long as you can execute SILE itself you can just ask it to dump the environment. You can just shell out from Lua like this:

$ sile -e 'os.execute("env > vars.env");os.exit()'

Do that for both ways of executing and hopefully that will give us something worth diffing.