From cd2948a72e3116a3a42f1f523fe2638db994362c Mon Sep 17 00:00:00 2001 From: Eric Sagnes <eric.sagnes@gmail.com> Date: Sun, 17 Jul 2016 05:11:42 +0900 Subject: [PATCH] fontconfig: fix etc priority --- .../config/fonts/fontconfig-ultimate.nix | 166 +++++---- nixos/modules/config/fonts/fontconfig.nix | 340 +++++++++++------- .../libraries/fontconfig/default.nix | 1 - .../libraries/fontconfig/make-fonts-conf.xsl | 2 - 4 files changed, 303 insertions(+), 206 deletions(-) diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix index 02568f9de51e..3ea6e1fa53bf 100644 --- a/nixos/modules/config/fonts/fontconfig-ultimate.nix +++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix @@ -3,6 +3,95 @@ with lib; let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>"; + + cfg = config.fonts.fontconfig.ultimate; + + latestVersion = pkgs.fontconfig.configVersion; + + # fontconfig ultimate main configuration file + # priority 52 + fontconfigUltimateConf = pkgs.writeText "fc-52-fontconfig-ultimate.conf" '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + + ${optionalString (!cfg.allowBitmaps) '' + <!-- Reject bitmap fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="scalable"><bool>false</bool></patelt> + </pattern> + </rejectfont> + </selectfont> + ''} + + ${optionalString cfg.allowType1 '' + <!-- Reject Type 1 fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="fontformat"> + <string>Type 1</string> + </patelt> + </pattern> + </rejectfont> + </selectfont> + ''} + + <!-- Use embedded bitmaps in fonts like Calibri? --> + <match target="font"> + <edit name="embeddedbitmap" mode="assign"> + ${fcBool cfg.useEmbeddedBitmaps} + </edit> + </match> + + <!-- Force autohint always --> + <match target="font"> + <edit name="force_autohint" mode="assign"> + ${fcBool cfg.forceAutohint} + </edit> + </match> + + <!-- Render some monospace TTF fonts as bitmaps --> + <match target="pattern"> + <edit name="bitmap_monospace" mode="assign"> + ${fcBool cfg.renderMonoTTFAsBitmap} + </edit> + </match> + + </fontconfig> + ''; + + # The configuration to be included in /etc/font/ + confPkg = pkgs.runCommand "font-ultimate-conf" {} '' + support_folder=$out/etc/fonts/conf.d + latest_folder=$out/etc/fonts/${latestVersion}/conf.d + + mkdir -p $support_folder + mkdir -p $latest_folder + + # 52-fontconfig-ultimate.conf + ln -s ${fontconfigUltimateConf} \ + $support_folder/52-fontconfig-ultimate.conf + ln -s ${fontconfigUltimateConf} \ + $latest_folder/52-fontconfig-ultimate.conf + + # fontconfig ultimate substitutions + ${optionalString (cfg.substitutions != "none") '' + ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${cfg.substitutions}/*.conf \ + $support_folder + ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${cfg.substitutions}/*.conf \ + $latest_folder + ''} + + # fontconfig ultimate various configuration files + ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d/*.conf \ + $support_folder + ln -s ${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d/*.conf \ + $latest_folder + ''; + in { @@ -114,80 +203,11 @@ in }; + config = mkIf (config.fonts.fontconfig.enable && cfg.enable) { - config = - let ultimate = config.fonts.fontconfig.ultimate; - fontconfigUltimateConf = '' - <?xml version="1.0"?> - <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> - <fontconfig> + fonts.fontconfig.confPackages = [ confPkg ]; + environment.variables = cfg.rendering; - ${optionalString (!ultimate.allowBitmaps) '' - <!-- Reject bitmap fonts --> - <selectfont> - <rejectfont> - <pattern> - <patelt name="scalable"><bool>false</bool></patelt> - </pattern> - </rejectfont> - </selectfont> - ''} - - ${optionalString ultimate.allowType1 '' - <!-- Reject Type 1 fonts --> - <selectfont> - <rejectfont> - <pattern> - <patelt name="fontformat"> - <string>Type 1</string> - </patelt> - </pattern> - </rejectfont> - </selectfont> - ''} - - <!-- Use embedded bitmaps in fonts like Calibri? --> - <match target="font"> - <edit name="embeddedbitmap" mode="assign"> - ${fcBool ultimate.useEmbeddedBitmaps} - </edit> - </match> - - <!-- Force autohint always --> - <match target="font"> - <edit name="force_autohint" mode="assign"> - ${fcBool ultimate.forceAutohint} - </edit> - </match> - - <!-- Render some monospace TTF fonts as bitmaps --> - <match target="pattern"> - <edit name="bitmap_monospace" mode="assign"> - ${fcBool ultimate.renderMonoTTFAsBitmap} - </edit> - </match> - - ${optionalString (ultimate.substitutions != "none") '' - <!-- Type 1 font substitutions --> - <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${ultimate.substitutions}</include> - ''} - - <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d</include> - - </fontconfig> - ''; - in mkIf (config.fonts.fontconfig.enable && ultimate.enable) { - - environment.etc."fonts/conf.d/52-fontconfig-ultimate.conf" = { - text = fontconfigUltimateConf; - }; - - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/52-fontconfig-ultimate.conf" = { - text = fontconfigUltimateConf; - }; - - environment.variables = ultimate.rendering; - - }; + }; } diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index 1eaebe4b2bbd..6494e09111d4 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -1,7 +1,203 @@ +/* + +NixOS support 2 fontconfig versions, "support" and "latest". + +- "latest" refers to default fontconfig package (pkgs.fontconfig). + configuration files are linked to /etc/fonts/VERSION/conf.d/ +- "support" refers to supportPkg (pkgs."fontconfig_${supportVersion}"). + configuration files are linked to /etc/fonts/conf.d/ + +This module generates a package containing configuration files and link it in /etc/fonts. + +Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing. +Low number means high priority. + +Default fonts should have a high priority (low number) to be at the head of the preferred fonts list, fontconfig advise the 30~40 range. + +*/ + { config, lib, pkgs, ... }: with lib; +let cfg = config.fonts.fontconfig; + + fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>"; + + # back-supported fontconfig version and package + # version is used for font cache generation + supportVersion = "210"; + supportPkg = pkgs."fontconfig_${supportVersion}"; + + # latest fontconfig version and package + # version is used for configuration folder name, /etc/fonts/VERSION/ + # note: format differs from supportVersion and can not be used with makeCacheConf + latestVersion = pkgs.fontconfig.configVersion; + latestPkg = pkgs.fontconfig; + + # supported version fonts.conf + supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; }; + + # configuration file to read fontconfig cache + # version dependent + # priority 0 + cacheConfSupport = makeCacheConf { version = supportVersion; }; + cacheConfLatest = makeCacheConf {}; + + # generate the font cache setting file for a fontconfig version + # use latest when no version is passed + makeCacheConf = { version ? null }: + let + fcPackage = if builtins.isNull version + then "fontconfig" + else "fontconfig_${version}"; + makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; }; + cache = makeCache pkgs."${fcPackage}"; + cache32 = makeCache pkgs.pkgsi686Linux."${fcPackage}"; + in + pkgs.writeText "fc-00-nixos-cache.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + <!-- Font directories --> + ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} + <!-- Pre-generated font caches --> + <cachedir>${cache}</cachedir> + ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) '' + <cachedir>${cache32}</cachedir> + ''} + </fontconfig> + ''; + + # rendering settings configuration file + # priority 10 + renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default rendering settings --> + <match target="font"> + <edit mode="assign" name="hinting"> + ${fcBool cfg.hinting.enable} + </edit> + <edit mode="assign" name="autohint"> + ${fcBool cfg.hinting.autohint} + </edit> + <edit mode="assign" name="hintstyle"> + <const>hint${cfg.hinting.style}</const> + </edit> + <edit mode="assign" name="antialias"> + ${fcBool cfg.antialias} + </edit> + <edit mode="assign" name="rgba"> + <const>${cfg.subpixel.rgba}</const> + </edit> + <edit mode="assign" name="lcdfilter"> + <const>lcd${cfg.subpixel.lcdfilter}</const> + </edit> + </match> + + ${optionalString (cfg.dpi != 0) '' + <match target="pattern"> + <edit name="dpi" mode="assign"> + <double>${toString cfg.dpi}</double> + </edit> + </match> + ''} + + </fontconfig> + ''; + + # prefered default fonts configuration file + # priority 30 + genericAliasConf = + let genDefault = fonts: name: + optionalString (fonts != []) '' + <alias> + <family>${name}</family> + <prefer> + ${concatStringsSep "" + (map (font: '' + <family>${font}</family> + '') fonts)} + </prefer> + </alias> + ''; + in + pkgs.writeText "fc-30-nixos-generic-alias.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default fonts --> + ${genDefault cfg.defaultFonts.sansSerif "sans-serif"} + + ${genDefault cfg.defaultFonts.serif "serif"} + + ${genDefault cfg.defaultFonts.monospace "monospace"} + + </fontconfig> + ''; + + # user settings configuration file + # priority 99 + userConf = pkgs.writeText "fc-99-user.conf" '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include> + <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include> + </fontconfig> + ''; + + # fontconfig configuration package + confPkg = pkgs.runCommand "fontconfig-conf" {} '' + support_folder=$out/etc/fonts + latest_folder=$out/etc/fonts/${latestVersion} + + mkdir -p $support_folder/conf.d + mkdir -p $latest_folder/conf.d + + # fonts.conf + ln -s ${supportFontsConf} $support_folder/fonts.conf + ln -s ${latestPkg.out}/etc/fonts/fonts.conf \ + $latest_folder/fonts.conf + + # fontconfig default config files + ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \ + $support_folder/conf.d/ + ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \ + $latest_folder/conf.d/ + + # 00-nixos-cache.conf + ln -s ${cacheConfSupport} \ + $support_folder/conf.d/00-nixos-cache.conf + ln -s ${cacheConfLatest} $latest_folder/conf.d/00-nixos-cache.conf + + # 10-nixos-rendering.conf + ln -s ${renderConf} $support_folder/conf.d/10-nixos-rendering.conf + ln -s ${renderConf} $latest_folder/conf.d/10-nixos-rendering.conf + + # 30-nixos-generic-alias.conf + ln -s ${genericAliasConf} $support_folder/conf.d/30-nixos-generic-alias.conf + ln -s ${genericAliasConf} $latest_folder/conf.d/30-nixos-generic-alias.conf + + # 99-user.conf + ${optionalString cfg.includeUserConf '' + ln -s ${userConf} $support_folder/conf.d/99-user.conf + ln -s ${userConf} $latest_folder/conf.d/99-user.conf + ''} + ''; + + # Package with configuration files + # this merge all the packages in the fonts.fontconfig.confPackages list + fontconfigEtc = pkgs.buildEnv { + name = "fontconfig-etc"; + paths = cfg.confPackages; + ignoreCollisions = true; + }; +in { options = { @@ -21,6 +217,15 @@ with lib; ''; }; + confPackages = mkOption { + internal = true; + type = with types; listOf path; + default = [ ]; + description = '' + Fontconfig configuration packages. + ''; + }; + antialias = mkOption { type = types.bool; default = true; @@ -142,136 +347,11 @@ with lib; }; }; + config = mkIf cfg.enable { + fonts.fontconfig.confPackages = [ confPkg ]; - config = - let fontconfig = config.fonts.fontconfig; - fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>"; - renderConf = '' - <?xml version='1.0'?> - <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> - <fontconfig> - - <!-- Default rendering settings --> - <match target="font"> - <edit mode="assign" name="hinting"> - ${fcBool fontconfig.hinting.enable} - </edit> - <edit mode="assign" name="autohint"> - ${fcBool fontconfig.hinting.autohint} - </edit> - <edit mode="assign" name="hintstyle"> - <const>hint${fontconfig.hinting.style}</const> - </edit> - <edit mode="assign" name="antialias"> - ${fcBool fontconfig.antialias} - </edit> - <edit mode="assign" name="rgba"> - <const>${fontconfig.subpixel.rgba}</const> - </edit> - <edit mode="assign" name="lcdfilter"> - <const>lcd${fontconfig.subpixel.lcdfilter}</const> - </edit> - </match> - - ${optionalString (fontconfig.dpi != 0) '' - <match target="pattern"> - <edit name="dpi" mode="assign"> - <double>${toString fontconfig.dpi}</double> - </edit> - </match> - ''} - - </fontconfig> - ''; - genericAliasConf = '' - <?xml version='1.0'?> - <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> - <fontconfig> - - <!-- Default fonts --> - ${optionalString (fontconfig.defaultFonts.sansSerif != []) '' - <alias> - <family>sans-serif</family> - <prefer> - ${concatStringsSep "\n" - (map (font: "<family>${font}</family>") - fontconfig.defaultFonts.sansSerif)} - </prefer> - </alias> - ''} - ${optionalString (fontconfig.defaultFonts.serif != []) '' - <alias> - <family>serif</family> - <prefer> - ${concatStringsSep "\n" - (map (font: "<family>${font}</family>") - fontconfig.defaultFonts.serif)} - </prefer> - </alias> - ''} - ${optionalString (fontconfig.defaultFonts.monospace != []) '' - <alias> - <family>monospace</family> - <prefer> - ${concatStringsSep "\n" - (map (font: "<family>${font}</family>") - fontconfig.defaultFonts.monospace)} - </prefer> - </alias> - ''} - - </fontconfig> - ''; - in mkIf fontconfig.enable { - - # Fontconfig 2.10 backward compatibility - - # Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10 - environment.etc."fonts/fonts.conf".source = - pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; }; - - environment.etc."fonts/conf.d/10-nixos-rendering.conf".text = renderConf; - environment.etc."fonts/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf; - - # Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig. - # Otherwise specify only font directories. - environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source = - "${pkgs.fontconfig.out}/etc/fonts/fonts.conf"; - - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text = - let - cache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; }; - in '' - <?xml version='1.0'?> - <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> - <fontconfig> - <!-- Font directories --> - ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} - <!-- Pre-generated font caches --> - <cachedir>${cache pkgs.fontconfig}</cachedir> - ${optionalString (pkgs.stdenv.isx86_64 && config.fonts.fontconfig.cache32Bit) '' - <cachedir>${cache pkgs.pkgsi686Linux.fontconfig}</cachedir> - ''} - </fontconfig> - ''; - - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/10-nixos-rendering.conf".text = renderConf; - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf; - - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/99-user.conf" = { - enable = fontconfig.includeUserConf; - text = '' - <?xml version="1.0"?> - <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> - <fontconfig> - <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include> - <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include> - </fontconfig> - ''; - }; - - environment.systemPackages = [ pkgs.fontconfig ]; - - }; + environment.systemPackages = [ pkgs.fontconfig ]; + environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/"; + }; } diff --git a/pkgs/development/libraries/fontconfig/default.nix b/pkgs/development/libraries/fontconfig/default.nix index 6acf1ebce29c..f18ea5948f15 100644 --- a/pkgs/development/libraries/fontconfig/default.nix +++ b/pkgs/development/libraries/fontconfig/default.nix @@ -68,7 +68,6 @@ stdenv.mkDerivation rec { cd "$out/etc/fonts" rm conf.d/{50-user,51-local}.conf "${libxslt.bin}/bin/xsltproc" --stringparam fontDirectories "${fontbhttf}" \ - --stringparam fontconfig "$out" \ --stringparam fontconfigConfigVersion "${configVersion}" \ --path $out/share/xml/fontconfig \ ${./make-fonts-conf.xsl} $out/etc/fonts/fonts.conf \ diff --git a/pkgs/development/libraries/fontconfig/make-fonts-conf.xsl b/pkgs/development/libraries/fontconfig/make-fonts-conf.xsl index b59fcd0187b8..dddbbe9e516b 100644 --- a/pkgs/development/libraries/fontconfig/make-fonts-conf.xsl +++ b/pkgs/development/libraries/fontconfig/make-fonts-conf.xsl @@ -28,8 +28,6 @@ <!-- /var/cache/fontconfig is useful for non-nixos systems --> <cachedir>/var/cache/fontconfig</cachedir> - <!-- fontconfig distribution conf.d --> - <include><xsl:value-of select="$fontconfig" />/etc/fonts/conf.d</include> <!-- versioned system-wide config --> <include ignore_missing="yes">/etc/fonts/<xsl:value-of select="$fontconfigConfigVersion" />/conf.d</include>