Fonts: Difference between revisions
Artoria2e5 (talk | contribs) →Use custom font substitutions: it's nicer, true, but it's also more similar/correct. |
m fix link |
||
| (33 intermediate revisions by 24 users not shown) | |||
| Line 1: | Line 1: | ||
NixOS handles fonts like it handles many different parts of the system: they are not in | NixOS handles fonts like it handles many different parts of the system: they are not in an environment unless explicitly marked to be part of it. This guide covers the installation, configuration and troubleshooting of fonts. | ||
== Installing fonts on NixOS == | == Installing fonts on NixOS == | ||
NixOS has many font packages available, and you can easily search for your | NixOS has many font packages available, and you can easily search for your favorites on the [https://search.nixos.org/packages NixOS packages site]. | ||
Despite looking like normal packages, simply adding these font packages to your <code>environment.systemPackages</code> won't make the fonts accessible to applications. To achieve that, put these packages in the <code>[https://search.nixos.org/options?channel=unstable&show=fonts.packages&from=0&size=50&sort=relevance&type=packages&query=fonts.packages fonts.packages]</code> NixOS options list instead. | Despite looking like normal packages, simply adding these font packages to your <code>environment.systemPackages</code> won't make the fonts accessible to applications. To achieve that, put these packages in the <code>[https://search.nixos.org/options?channel=unstable&show=fonts.packages&from=0&size=50&sort=relevance&type=packages&query=fonts.packages fonts.packages]</code> NixOS options list instead. | ||
'' | ''For example:'' | ||
{{File|3=fonts.packages = with pkgs; [ | |||
fonts.packages = with pkgs; [ | |||
noto-fonts | noto-fonts | ||
noto-fonts-cjk | noto-fonts-cjk-sans | ||
noto-fonts-emoji | noto-fonts-color-emoji | ||
liberation_ttf | liberation_ttf | ||
fira-code | fira-code | ||
| Line 22: | Line 19: | ||
dina-font | dina-font | ||
proggyfonts | proggyfonts | ||
]; | ];|name=/etc/nixos/configuration.nix|lang=nix}}{{Note|Be aware that sometimes font names and packages name differ and there is no universal convention in NixOS. </br>See: [https://discourse.nixos.org/t/guidelines-on-packaging-fonts/7683/2| Guidelines for font packaging]}} | ||
Be aware that sometimes font names and packages name differ and there is no universal convention in NixOS. See [https://discourse.nixos.org/t/guidelines-on-packaging-fonts/7683/2 Guidelines for font packaging] | |||
=== Shorthands for fonts === | === Shorthands for fonts === | ||
| Line 31: | Line 25: | ||
* <code>fonts.enableGhostscriptFonts</code>: affects the <code>ghostscript</code> package. Ghostscript packages some URW fonts for the standard PostScript typefaces. If <code>true</code>, these fonts will be visible to GUI applications. You could set it to <code>true</code> if you want these fonts, but <code>gyre-fonts</code> (part of <code>fonts.enableDefaultPackages</code>) might be higher-quality depending on your judgement. | * <code>fonts.enableGhostscriptFonts</code>: affects the <code>ghostscript</code> package. Ghostscript packages some URW fonts for the standard PostScript typefaces. If <code>true</code>, these fonts will be visible to GUI applications. You could set it to <code>true</code> if you want these fonts, but <code>gyre-fonts</code> (part of <code>fonts.enableDefaultPackages</code>) might be higher-quality depending on your judgement. | ||
=== | === Using fonts from TexLive === | ||
You can make use of all TeX/LaTeX fonts from CTAN and [[TexLive]] by passing | |||
the <code>fonts</code> attribute of your TexLive package to <code>fonts.package</code>: | |||
{{File|3={ pkgs, ... }: | |||
let | |||
mytex = | |||
pkgs.texliveConTeXt.withPackages | |||
(ps: with ps; [ | |||
fandol | |||
libertinus-fonts | |||
]); | |||
in { | |||
fonts.packages = builtins.attrValues { | |||
inherit (pkgs) | |||
dejavu_fonts | |||
noto-fonts-cjk-serif | |||
noto-fonts-cjk-sans | |||
julia-mono; | |||
} ++ [ mytex.fonts ]; | |||
}|name=/etc/nixos/configuration.nix|lang=nix}} | |||
=== Installing <code>nerdfonts</code> === | |||
Individual Nerd Fonts can be installed like so: | |||
<syntaxhighlight lang="nix"> | {{File|3=fonts.packages = with pkgs; [ | ||
fonts.packages = | nerd-fonts.fira-code | ||
(nerdfonts. | nerd-fonts.droid-sans-mono | ||
];|name=/etc/nixos/configuration.nix|lang=nix}} | |||
The available Nerd Font subpackages can be listed by searching for {{nixos:package|nerd-fonts.*}} on the [[Searching packages|NixOS Package Search]] or by running the following command: <syntaxhighlight lang="console"> | |||
$ nix-instantiate --eval --expr "with (import <nixpkgs> {}); lib.attrNames (lib.filterAttrs (_: lib.isDerivation) nerd-fonts)" | |||
</syntaxhighlight> | |||
==== Installing all <code>nerdfonts</code> ==== | |||
Installing all fonts from the [https://www.nerdfonts.com/ Nerd Fonts repository] is as simple as adding all of the individual packages to the NixOS configuration. The following line will do exactly that, by searching for all derivations under the <code>nerd-font</code> attribute:{{file|||<nowiki> | |||
{ | |||
fonts.packages = builtins.filter lib.attrsets.isDerivation (builtins.attrValues pkgs.nerd-fonts); | |||
} | |||
# or if you already have fonts.packages set | |||
{ | |||
fonts.packages = [ | |||
# ... some fonts | |||
] | |||
++ builtins.filter lib.attrsets.isDerivation (builtins.attrValues pkgs.nerd-fonts); | |||
} | |||
</nowiki>|name=/etc/nixos/configuration.nix|lang=nix}} | |||
=== Patching nerdfonts into fonts === | |||
Not all fonts have Nerd Fonts variants, thankfully you can easily patch them in yourself. | |||
{{File|3=(pkgs.scientifica.overrideAttrs (o: { | |||
nativeBuildInputs = [ pkgs.nerd-font-patcher ]; | |||
postInstall = '' | |||
mkdir -p $out/share/fonts/truetype/{scientifica,scientifica-nerd} | |||
mv $out/share/fonts/truetype/*.ttf $out/share/fonts/truetype/scientifica/ | |||
for f in $out/share/fonts/truetype/scientifica/*.ttf; do | |||
nerd-font-patcher --complete --outputdir $out/share/fonts/truetype/scientifica-nerd/ $f | |||
done | |||
''; | |||
}))|name=/etc/nixos/configuration.nix|lang=nix}} | |||
=== Let Fontconfig know the fonts within your Nix profile === | |||
Nix inserts its user profile path into <code>$XDG_DATA_DIRS</code>, which Fontconfig by default doesn't look in. This cause graphical applications like KDE Plasma not able to recognize the fonts installed via <code>nix-env</code> or <code>nix profile</code>. | |||
To solve this, add the file <code>100-nix.conf</code> to your Fontconfig user configuration directory (usually <code>$XDG_CONFIG_HOME/fontconfig/conf.d</code>): | |||
<syntaxhighlight lang="xml"> | |||
<?xml version="1.0"?> | |||
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> | |||
<fontconfig> | |||
<!-- NIX_PROFILE is the path to your Nix profile. See Nix Reference Manual for details. --> | |||
<dir>NIX_PROFILE/lib/X11/fonts</dir> | |||
<dir>NIX_PROFILE/share/fonts</dir> | |||
</fontconfig> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
and run <code>fc-cache</code>. | |||
Alternatively, [https://nix-community.github.io/home-manager/options.xhtml#opt-fonts.fontconfig.enable enable Fontconfig configuration] in your Home Manager configuration. | |||
=== Imperative installation of user fonts === | === Imperative installation of user fonts === | ||
This is useful for quick font experiments. | This is useful for quick font experiments. | ||
Example: Install <code>SourceCodePro-Regular</code>. | ''Example'': Install <code>SourceCodePro-Regular</code>. | ||
<syntaxhighlight lang="bash">font=$(nix-build --no-out-link '<nixpkgs>' -A source-code-pro)/share/fonts/opentype/SourceCodePro-Regular.otf | <syntaxhighlight lang="bash">font=$(nix-build --no-out-link '<nixpkgs>' -A source-code-pro)/share/fonts/opentype/SourceCodePro-Regular.otf | ||
cp $font ~/.local/share/fonts | cp $font ~/.local/share/fonts | ||
| Line 52: | Line 119: | ||
fc-list -v | grep -i source | fc-list -v | grep -i source | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Install fonts in nix-shells === | |||
<code>fonts</code> is not available as set-valued option in <code>mkshell</code> (gives you an error because it tries to coerce an attribute set into a string). Instead, insert the following:<ref>https://programming.dev/post/32484220</ref> | |||
<syntaxhighlight lang="nix"> | |||
{pkgs ? import <nixpkgs> {} }: | |||
let | |||
fontsConf = pkgs.makeFontsConf { | |||
fontDirectories = [ | |||
# your needed fonts here, e.g.: | |||
pkgs.font-awesome | |||
pkgs.atkinson-hyperlegible-next | |||
]; | |||
}; | |||
in | |||
pkgs.mkShell { | |||
packages = with pkgs; [ | |||
# your font-dependent packages, e.g.: | |||
typst | |||
]; | |||
shellHook = '' | |||
export FONTCONFIG_FILE="${fontsConf}" | |||
''; | |||
} | |||
</syntaxhighlight> | |||
Then <code>typst fonts</code> finds the installed fonts in the nix-shell. | |||
== Configuring fonts == | == Configuring fonts == | ||
The nixos key [https://search.nixos.org/options?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=fonts.fontconfig <code>fonts.fontconfig</code>] handles the fontconfig options. Some options are nicely wrapped in nix; there's always <code>localConf</code> to go straight to the XML. | The nixos key [https://search.nixos.org/options?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=fonts.fontconfig <code>fonts.fontconfig</code>] (click to see the full list!) handles the fontconfig options. Some options are nicely wrapped in nix; there's always <code>localConf</code> to go straight to the XML. | ||
=== Set multiple fonts for different languages === | === Set multiple fonts for different languages === | ||
If you want to use other languages alongside English, you may want to set appropriate fonts for each language in your whole OS. For example, a Persian speaker might want to use the [https://rastikerdar.github.io/vazirmatn/ Vazirmatn] font for Persian texts, but [https://design.ubuntu.com/font/ Ubuntu] and Liberation Serif fonts for English texts. Just put these lines into your <code>configuration.nix</code>: | If you want to use other languages alongside English, you may want to set appropriate fonts for each language in your whole OS. For example, a Persian speaker might want to use the [https://rastikerdar.github.io/vazirmatn/ Vazirmatn] font for Persian texts, but [https://design.ubuntu.com/font/ Ubuntu] and Liberation Serif fonts for English texts. Just put these lines into your <code>configuration.nix</code>: | ||
{{File|3=#----=[ Fonts ]=----# | |||
#----=[ Fonts ]=----# | |||
fonts = { | fonts = { | ||
enableDefaultPackages = true; | enableDefaultPackages = true; | ||
| Line 78: | Line 173: | ||
}; | }; | ||
}; | }; | ||
}; | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
NB: | NB: | ||
| Line 93: | Line 187: | ||
Adding this to your <code>/etc/nixos/configuration.nix</code> should prompt it to use the more similar (and nicer) serif ''Schola'' font instead: | Adding this to your <code>/etc/nixos/configuration.nix</code> should prompt it to use the more similar (and nicer) serif ''Schola'' font instead: | ||
{{File|3=fonts = { | |||
fonts = { | |||
packages = with pkgs; [ gyre-fonts ]; | packages = with pkgs; [ gyre-fonts ]; | ||
fontconfig = { | fontconfig = { | ||
| Line 105: | Line 198: | ||
''; | ''; | ||
}; | }; | ||
}; | };|name=/etc/nixos/configuration.nix|lang=nix}} | ||
For more information and examples on the xml configuration language: | For more information and examples on the xml configuration language: | ||
| Line 138: | Line 230: | ||
=== Flatpak applications can't find system fonts === | === Flatpak applications can't find system fonts === | ||
To expose available fonts under <code>/run/current-system/sw/share/X11/fonts</code>, enable <code>fontDir</code> in your NixOS configuration. | |||
fonts.fontDir.enable = true; | {{File|3=fonts.fontDir.enable = true;|name=/etc/nixos/configuration.nix|lang=nix}} | ||
You will then need to link/copy this folder to one of the Flatpak-supported locations - see below. | |||
==== | ==== Solution 1: Copy fonts to <code>$HOME/.local/share/fonts</code> ==== | ||
Create fonts directory <code>$HOME/.local/share/fonts</code> and copy system fonts with option <code>-L, --dereference</code> | Create fonts directory <code>$HOME/.local/share/fonts</code> and copy system fonts with option <code>-L, --dereference</code>. You will need to repeat this step whenever the fonts change.<syntaxhighlight lang="console"> | ||
mkdir $HOME/.local/share/fonts && cp -L /run/current-system/sw/share/X11/fonts/* $HOME/.local/share/fonts/ | $ mkdir $HOME/.local/share/fonts && cp -L /run/current-system/sw/share/X11/fonts/* $HOME/.local/share/fonts/ | ||
</syntaxhighlight>Note: There is | </syntaxhighlight>Note: There is no need to grant flatpak applications access to <code>$HOME/.local/share/fonts</code>. | ||
Instead, if you do that, some applications (for example, steam) won't work.<blockquote>Internals: How it works? | Instead, if you do that, some applications (for example, steam) won't work.<blockquote>Internals: How it works? | ||
| Line 163: | Line 256: | ||
</syntaxhighlight>Then flatpak application can read fonts from that to display contents correctly.</blockquote> | </syntaxhighlight>Then flatpak application can read fonts from that to display contents correctly.</blockquote> | ||
==== | ==== Solution 2: Symlink to system fonts at <code>$HOME/.local/share/fonts</code> ==== | ||
<blockquote>'''Note:''' this method doesn't work for some flatpak applications (for example, steam)! | <blockquote>'''Note:''' this method doesn't work for some flatpak applications (for example, steam)! | ||
Error: <syntaxhighlight lang="console"> | Error: <syntaxhighlight lang="console"> | ||
$ flatpak | $ flatpak run com.valvesoftware.Steam | ||
bwrap: Can't make symlink at /home/username/.local/share/fonts: File exists | bwrap: Can't make symlink at /home/username/.local/share/fonts: File exists | ||
</syntaxhighlight></blockquote>Create a symlink in <code>XDG_DATA_HOME/fonts</code> pointing to <code>/run/current-system/sw/share/X11/fonts</code>, e. g. | </syntaxhighlight></blockquote>Create a symlink in <code>XDG_DATA_HOME/fonts</code> pointing to <code>/run/current-system/sw/share/X11/fonts</code>, e. g. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
ln -s /run/current-system/sw/share/X11/fonts ~/.local/share/fonts | mkdir $HOME/.local/share/fonts && ln -s /run/current-system/sw/share/X11/fonts ~/.local/share/fonts/ | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Now you have two options. | Now you have two options. | ||
===== Option 1: | ===== Option 1: Allow access to the fonts folder and <code>/nix/store</code> ===== | ||
By using the Flatpak CLI or the Flatseal Flatpak make the following directory available to all Flatpaks <code>$HOME/.local/share/fonts</code> and <code>$HOME/.icons</code> the appropriate commands for this are: | By using the Flatpak CLI or the Flatseal Flatpak make the following directory available to all Flatpaks <code>$HOME/.local/share/fonts</code> and <code>$HOME/.icons</code> the appropriate commands for this are: | ||
| Line 183: | Line 276: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
And, because <code>~/.local/share/fonts</code> is linked to <code>/run/current-system/sw/share/X11/fonts</code>, which in turn is linked to content in <code>/nix/store</code>. | And, because <code>~/.local/share/fonts</code> is linked to <code>/run/current-system/sw/share/X11/fonts</code>, which in turn is linked to content in <code>/nix/store</code>. You need to grant flatpak applications access to the <code>/nix/store</code> directory, so that they can load fonts correctly. You may need to reboot for this to fully take effect. | ||
You need to grant flatpak applications access to the <code>/nix/store</code> directory, | |||
so that they can load fonts correctly. | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
flatpak --user override --filesystem=/nix/store:ro | flatpak --user override --filesystem=/nix/store:ro | ||
flatpak --user override --filesystem=/run/current-system/sw/share/X11/fonts:ro | |||
</syntaxhighlight> | </syntaxhighlight> | ||
===== Option 2: | ===== Option 2: Allow access to the WHOLE filesystem ===== | ||
Allow them access the WHOLE filesystem of yours: <code>All system files</code> in Flatseal or equivalently <code>filesystem=host</code> available to your application, the command for this is: | Allow them access the WHOLE filesystem of yours: <code>All system files</code> in Flatseal or equivalently <code>filesystem=host</code> available to your application, the command for this is: | ||
| Line 200: | Line 292: | ||
It is important to keep in mind that some flatpak apps may refuse to launch if given certain permissions, such as the Steam flatpak. | It is important to keep in mind that some flatpak apps may refuse to launch if given certain permissions, such as the Steam flatpak. | ||
=== | ==== Solution 3: Configure bindfs for fonts/cursors/icons support ==== | ||
Alternatively, you can expose relevant packages directly under <code>/usr/share/...</code> paths. This will also enable Flatpak to use a custom cursor theme if you have one. This solution doesn't require <code>fonts.fontDir.enable</code> to be enabled.<syntaxhighlight lang="nix"> | |||
<syntaxhighlight lang="nix"> | |||
system.fsPackages = [ pkgs.bindfs ]; | system.fsPackages = [ pkgs.bindfs ]; | ||
fileSystems = let | fileSystems = let | ||
| Line 210: | Line 301: | ||
options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ]; | options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ]; | ||
}; | }; | ||
fontsPkgs = config.fonts.packages ++ (with pkgs; [ | |||
# Add your cursor themes and icon packages here | |||
bibata-cursors | |||
gnome.gnome-themes-extra | |||
# etc. | |||
]); | |||
x11Fonts = pkgs.runCommand "X11-fonts" | |||
{ | |||
preferLocalBuild = true; | |||
nativeBuildInputs = with pkgs; [ | |||
gzip | |||
xorg.mkfontscale | |||
xorg.mkfontdir | |||
]; | |||
} | |||
('' | |||
mkdir -p "$out/share/fonts" | |||
font_regexp='.*\.\(ttf\|ttc\|otb\|otf\|pcf\|pfa\|pfb\|bdf\)\(\.gz\)?' | |||
'' | |||
+ (builtins.concatStringsSep "\n" (builtins.map (pkg: '' | |||
find ${toString pkg} -regex "$font_regexp" \ | |||
-exec ln -sf -t "$out/share/fonts" '{}' \; | |||
'') fontsPkgs | |||
)) | |||
+ '' | |||
cd "$out/share/fonts" | |||
mkfontscale | |||
mkfontdir | |||
cat $(find ${pkgs.xorg.fontalias}/ -name fonts.alias) >fonts.alias | |||
''); | |||
aggregatedIcons = pkgs.buildEnv { | aggregatedIcons = pkgs.buildEnv { | ||
name = "system-icons"; | name = "system-icons"; | ||
paths = | paths = fontsPkgs; | ||
pathsToLink = [ | |||
"/share/icons" | |||
]; | ]; | ||
}; | }; | ||
in { | in { | ||
"/usr/share/icons" = mkRoSymBind " | "/usr/share/icons" = mkRoSymBind (aggregatedIcons + "/share/icons"); | ||
"/usr | "/usr/share/fonts" = mkRoSymBind (x11Fonts + "/share/fonts"); | ||
}; | }; | ||
fonts | fonts.packages = with pkgs; [ | ||
noto-fonts | |||
noto-fonts-emoji | |||
noto-fonts-cjk | |||
]; | |||
</syntaxhighlight>Note that font cache inside flatpak container may not be recreated after changes to fonts in <code>/usr/share/fonts</code>, because font cache seem to be relying on file timestamps that are missing in <code>/nix/store</code>. | |||
You can make sure that font directory is bind-mounted properly inside flatpak container by running <code>flatpak enter <instance> findmnt | grep /run/host/fonts</code>, or by running <code>flatpak enter <instance> ls -alh /run/host/fonts</code> and compare it to <code>ls -alh /usr/share/fonts</code>. | |||
If everything is mounted properly, but you still do not see fonts in flatpak app - force font cache recreation inside flatpak container: <code>flatpak run --command=fc-cache <application id> -f -v</code> | |||
=== Noto Color Emoji doesn't render on Firefox === | |||
Enable <code>useEmbeddedBitmaps</code> in your NixOS configuration. | |||
<syntaxhighlight lang="nix"> | |||
fonts.fontconfig.useEmbeddedBitmaps = true; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 241: | Line 364: | ||
[[Category:Configuration]] | [[Category:Configuration]] | ||
[[Category:Desktop]] | [[Category:Desktop]] | ||
[[Category:Fonts]] | |||