{ config, lib, pkgs, ... }: with lib; let cfg = config.fonts.fontconfig; fcBool = x: "" + (if x then "true" else "false") + ""; renderConf = pkgs.writeText "render-conf" '' ${fcBool cfg.hinting.enable} ${fcBool cfg.hinting.autohint} hint${cfg.hinting.style} ${fcBool cfg.antialias} ${cfg.subpixel.rgba} lcd${cfg.subpixel.lcdfilter} ${optionalString (cfg.dpi != 0) '' ${toString cfg.dpi} ''} ''; genericAliasConf = let genDefault = fonts: name: optionalString (fonts != []) '' ${name} ${concatStringsSep "" (map (font: '' ${font} '') fonts)} ''; in pkgs.writeText "generic-alias-conf" '' ${genDefault cfg.defaultFonts.sansSerif "sans-serif"} ${genDefault cfg.defaultFonts.serif "serif"} ${genDefault cfg.defaultFonts.monospace "monospace"} ''; cacheConf = let cache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; }; in pkgs.writeText "cache-conf" '' ${concatStringsSep "\n" (map (font: "${font}") config.fonts.fonts)} ${cache pkgs.fontconfig} ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) '' ${cache pkgs.pkgsi686Linux.fontconfig} ''} ''; userConf = pkgs.writeText "user-conf" '' fontconfig/conf.d fontconfig/fonts.conf ''; fontsConf = pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; }; confPkg = let version = pkgs.fontconfig.configVersion; in pkgs.runCommand "fontconfig-conf" {} '' mkdir -p $out/etc/fonts/{,${version}/}conf.d ln -s ${fontsConf} $out/etc/fonts/fonts.conf ln -s ${pkgs.fontconfig.out}/etc/fonts/fonts.conf $out/etc/fonts/${version}/fonts.conf ln -s ${pkgs.fontconfig.out}/etc/fonts/conf.d/* $out/etc/fonts/${version}/conf.d/ ln -s ${renderConf} $out/etc/fonts/conf.d/10-nixos-rendering.conf ln -s ${genericAliasConf} $out/etc/fonts/conf.d/60-nixos-generic-alias.conf ln -s ${cacheConf} $out/etc/fonts/${version}/conf.d/00-nixos.conf ln -s ${renderConf} $out/etc/fonts/${version}/conf.d/10-nixos-rendering.conf ln -s ${genericAliasConf} $out/etc/fonts/${version}/conf.d/30-nixos-generic-alias.conf ${optionalString cfg.includeUserConf "ln -s ${userConf} $out/etc/fonts/${version}/conf.d/99-user.conf"} ''; in { options = { fonts = { fontconfig = { enable = mkOption { type = types.bool; default = true; description = '' If enabled, a Fontconfig configuration file will be built pointing to a set of default fonts. If you don't care about running X11 applications or any other program that uses Fontconfig, you can turn this option off and prevent a dependency on all those fonts. ''; }; confPkgs = mkOption { internal = true; type = with types; listOf path; default = [ ]; description = '' Fontconfig configuration packages. ''; }; antialias = mkOption { type = types.bool; default = true; description = "Enable font antialiasing."; }; dpi = mkOption { type = types.int; default = 0; description = '' Force DPI setting. Setting to 0 disables DPI forcing; the DPI detected for the display will be used. ''; }; defaultFonts = { monospace = mkOption { type = types.listOf types.str; default = ["DejaVu Sans Mono"]; description = '' System-wide default monospace font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; sansSerif = mkOption { type = types.listOf types.str; default = ["DejaVu Sans"]; description = '' System-wide default sans serif font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; serif = mkOption { type = types.listOf types.str; default = ["DejaVu Serif"]; description = '' System-wide default serif font(s). Multiple fonts may be listed in case multiple languages must be supported. ''; }; }; hinting = { enable = mkOption { type = types.bool; default = true; description = "Enable TrueType hinting."; }; autohint = mkOption { type = types.bool; default = true; description = '' Enable the autohinter, which provides hinting for otherwise un-hinted fonts. The results are usually lower quality than correctly-hinted fonts. ''; }; style = mkOption { type = types.str // { check = flip elem ["none" "slight" "medium" "full"]; }; default = "full"; description = '' TrueType hinting style, one of none, slight, medium, or full. ''; }; }; includeUserConf = mkOption { type = types.bool; default = true; description = '' Include the user configuration from ~/.config/fontconfig/fonts.conf or ~/.config/fontconfig/conf.d. ''; }; subpixel = { rgba = mkOption { default = "rgb"; type = types.enum ["rgb" "bgr" "vrgb" "vbgr" "none"]; description = '' Subpixel order, one of none, rgb, bgr, vrgb, or vbgr. ''; }; lcdfilter = mkOption { default = "default"; type = types.enum ["none" "default" "light" "legacy"]; description = '' FreeType LCD filter, one of none, default, light, or legacy. ''; }; }; cache32Bit = mkOption { default = false; type = types.bool; description = '' Generate system fonts cache for 32-bit applications. ''; }; }; }; }; config = mkIf cfg.enable { fonts.fontconfig.confPkgs = [ confPkg ]; environment.etc.fonts.source = let fontConf = pkgs.symlinkJoin { name = "fontconfig-etc"; paths = cfg.confPkgs; }; in "${fontConf}/etc/fonts/"; environment.systemPackages = [ pkgs.fontconfig ]; }; }