at 16.09-beta 12 kB view raw
1/* 2 3NixOS support 2 fontconfig versions, "support" and "latest". 4 5- "latest" refers to default fontconfig package (pkgs.fontconfig). 6 configuration files are linked to /etc/fonts/VERSION/conf.d/ 7- "support" refers to supportPkg (pkgs."fontconfig_${supportVersion}"). 8 configuration files are linked to /etc/fonts/conf.d/ 9 10This module generates a package containing configuration files and link it in /etc/fonts. 11 12Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing. 13Low number means high priority. 14 15*/ 16 17{ config, lib, pkgs, ... }: 18 19with lib; 20 21let cfg = config.fonts.fontconfig; 22 23 fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>"; 24 25 # back-supported fontconfig version and package 26 # version is used for font cache generation 27 supportVersion = "210"; 28 supportPkg = pkgs."fontconfig_${supportVersion}"; 29 30 # latest fontconfig version and package 31 # version is used for configuration folder name, /etc/fonts/VERSION/ 32 # note: format differs from supportVersion and can not be used with makeCacheConf 33 latestVersion = pkgs.fontconfig.configVersion; 34 latestPkg = pkgs.fontconfig; 35 36 # supported version fonts.conf 37 supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; }; 38 39 # configuration file to read fontconfig cache 40 # version dependent 41 # priority 0 42 cacheConfSupport = makeCacheConf { version = supportVersion; }; 43 cacheConfLatest = makeCacheConf {}; 44 45 # generate the font cache setting file for a fontconfig version 46 # use latest when no version is passed 47 makeCacheConf = { version ? null }: 48 let 49 fcPackage = if builtins.isNull version 50 then "fontconfig" 51 else "fontconfig_${version}"; 52 makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; }; 53 cache = makeCache pkgs."${fcPackage}"; 54 cache32 = makeCache pkgs.pkgsi686Linux."${fcPackage}"; 55 in 56 pkgs.writeText "fc-00-nixos-cache.conf" '' 57 <?xml version='1.0'?> 58 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> 59 <fontconfig> 60 <!-- Font directories --> 61 ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} 62 <!-- Pre-generated font caches --> 63 <cachedir>${cache}</cachedir> 64 ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) '' 65 <cachedir>${cache32}</cachedir> 66 ''} 67 </fontconfig> 68 ''; 69 70 # rendering settings configuration file 71 # priority 10 72 renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" '' 73 <?xml version='1.0'?> 74 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> 75 <fontconfig> 76 77 <!-- Default rendering settings --> 78 <match target="font"> 79 <edit mode="assign" name="hinting"> 80 ${fcBool cfg.hinting.enable} 81 </edit> 82 <edit mode="assign" name="autohint"> 83 ${fcBool cfg.hinting.autohint} 84 </edit> 85 <edit mode="assign" name="hintstyle"> 86 <const>hint${cfg.hinting.style}</const> 87 </edit> 88 <edit mode="assign" name="antialias"> 89 ${fcBool cfg.antialias} 90 </edit> 91 <edit mode="assign" name="rgba"> 92 <const>${cfg.subpixel.rgba}</const> 93 </edit> 94 <edit mode="assign" name="lcdfilter"> 95 <const>lcd${cfg.subpixel.lcdfilter}</const> 96 </edit> 97 </match> 98 99 ${optionalString (cfg.dpi != 0) '' 100 <match target="pattern"> 101 <edit name="dpi" mode="assign"> 102 <double>${toString cfg.dpi}</double> 103 </edit> 104 </match> 105 ''} 106 107 </fontconfig> 108 ''; 109 110 # local configuration file 111 # priority 51 112 localConf = pkgs.writeText "fc-local.conf" cfg.localConf; 113 114 # default fonts configuration file 115 # priority 52 116 defaultFontsConf = 117 let genDefault = fonts: name: 118 optionalString (fonts != []) '' 119 <alias> 120 <family>${name}</family> 121 <prefer> 122 ${concatStringsSep "" 123 (map (font: '' 124 <family>${font}</family> 125 '') fonts)} 126 </prefer> 127 </alias> 128 ''; 129 in 130 pkgs.writeText "fc-52-nixos-default-fonts.conf" '' 131 <?xml version='1.0'?> 132 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> 133 <fontconfig> 134 135 <!-- Default fonts --> 136 ${genDefault cfg.defaultFonts.sansSerif "sans-serif"} 137 138 ${genDefault cfg.defaultFonts.serif "serif"} 139 140 ${genDefault cfg.defaultFonts.monospace "monospace"} 141 142 </fontconfig> 143 ''; 144 145 # fontconfig configuration package 146 confPkg = pkgs.runCommand "fontconfig-conf" {} '' 147 support_folder=$out/etc/fonts 148 latest_folder=$out/etc/fonts/${latestVersion} 149 150 mkdir -p $support_folder/conf.d 151 mkdir -p $latest_folder/conf.d 152 153 # fonts.conf 154 ln -s ${supportFontsConf} $support_folder/fonts.conf 155 ln -s ${latestPkg.out}/etc/fonts/fonts.conf \ 156 $latest_folder/fonts.conf 157 158 # fontconfig default config files 159 ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \ 160 $support_folder/conf.d/ 161 ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \ 162 $latest_folder/conf.d/ 163 164 # update latest 51-local.conf path to look at the latest local.conf 165 rm $latest_folder/conf.d/51-local.conf 166 167 substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \ 168 $latest_folder/conf.d/51-local.conf \ 169 --replace local.conf /etc/fonts/${latestVersion}/local.conf 170 171 # 00-nixos-cache.conf 172 ln -s ${cacheConfSupport} \ 173 $support_folder/conf.d/00-nixos-cache.conf 174 ln -s ${cacheConfLatest} $latest_folder/conf.d/00-nixos-cache.conf 175 176 # 10-nixos-rendering.conf 177 ln -s ${renderConf} $support_folder/conf.d/10-nixos-rendering.conf 178 ln -s ${renderConf} $latest_folder/conf.d/10-nixos-rendering.conf 179 180 # 50-user.conf 181 ${optionalString (! cfg.includeUserConf) '' 182 rm $support_folder/conf.d/50-user.conf 183 rm $latest_folder/conf.d/50-user.conf 184 ''} 185 186 # local.conf (indirect priority 51) 187 ${optionalString (cfg.localConf != "") '' 188 ln -s ${localConf} $support_folder/local.conf 189 ln -s ${localConf} $latest_folder/local.conf 190 ''} 191 192 # 52-nixos-default-fonts.conf 193 ln -s ${defaultFontsConf} $support_folder/conf.d/52-nixos-default-fonts.conf 194 ln -s ${defaultFontsConf} $latest_folder/conf.d/52-nixos-default-fonts.conf 195 ''; 196 197 # Package with configuration files 198 # this merge all the packages in the fonts.fontconfig.confPackages list 199 fontconfigEtc = pkgs.buildEnv { 200 name = "fontconfig-etc"; 201 paths = cfg.confPackages; 202 ignoreCollisions = true; 203 }; 204in 205{ 206 207 options = { 208 209 fonts = { 210 211 fontconfig = { 212 enable = mkOption { 213 type = types.bool; 214 default = true; 215 description = '' 216 If enabled, a Fontconfig configuration file will be built 217 pointing to a set of default fonts. If you don't care about 218 running X11 applications or any other program that uses 219 Fontconfig, you can turn this option off and prevent a 220 dependency on all those fonts. 221 ''; 222 }; 223 224 confPackages = mkOption { 225 internal = true; 226 type = with types; listOf path; 227 default = [ ]; 228 description = '' 229 Fontconfig configuration packages. 230 ''; 231 }; 232 233 antialias = mkOption { 234 type = types.bool; 235 default = true; 236 description = "Enable font antialiasing."; 237 }; 238 239 dpi = mkOption { 240 type = types.int; 241 default = 0; 242 description = '' 243 Force DPI setting. Setting to <literal>0</literal> disables DPI 244 forcing; the DPI detected for the display will be used. 245 ''; 246 }; 247 248 localConf = mkOption { 249 type = types.lines; 250 default = ""; 251 description = '' 252 System-wide customization file contents, has higher priority than 253 <literal>defaultFonts</literal> settings. 254 ''; 255 }; 256 257 defaultFonts = { 258 monospace = mkOption { 259 type = types.listOf types.str; 260 default = ["DejaVu Sans Mono"]; 261 description = '' 262 System-wide default monospace font(s). Multiple fonts may be 263 listed in case multiple languages must be supported. 264 ''; 265 }; 266 267 sansSerif = mkOption { 268 type = types.listOf types.str; 269 default = ["DejaVu Sans"]; 270 description = '' 271 System-wide default sans serif font(s). Multiple fonts may be 272 listed in case multiple languages must be supported. 273 ''; 274 }; 275 276 serif = mkOption { 277 type = types.listOf types.str; 278 default = ["DejaVu Serif"]; 279 description = '' 280 System-wide default serif font(s). Multiple fonts may be listed 281 in case multiple languages must be supported. 282 ''; 283 }; 284 }; 285 286 hinting = { 287 enable = mkOption { 288 type = types.bool; 289 default = true; 290 description = "Enable TrueType hinting."; 291 }; 292 293 autohint = mkOption { 294 type = types.bool; 295 default = true; 296 description = '' 297 Enable the autohinter, which provides hinting for otherwise 298 un-hinted fonts. The results are usually lower quality than 299 correctly-hinted fonts. 300 ''; 301 }; 302 303 style = mkOption { 304 type = types.str // { 305 check = flip elem ["none" "slight" "medium" "full"]; 306 }; 307 default = "full"; 308 description = '' 309 TrueType hinting style, one of <literal>none</literal>, 310 <literal>slight</literal>, <literal>medium</literal>, or 311 <literal>full</literal>. 312 ''; 313 }; 314 }; 315 316 includeUserConf = mkOption { 317 type = types.bool; 318 default = true; 319 description = '' 320 Include the user configuration from 321 <filename>~/.config/fontconfig/fonts.conf</filename> or 322 <filename>~/.config/fontconfig/conf.d</filename>. 323 ''; 324 }; 325 326 subpixel = { 327 328 rgba = mkOption { 329 default = "rgb"; 330 type = types.enum ["rgb" "bgr" "vrgb" "vbgr" "none"]; 331 description = '' 332 Subpixel order, one of <literal>none</literal>, 333 <literal>rgb</literal>, <literal>bgr</literal>, 334 <literal>vrgb</literal>, or <literal>vbgr</literal>. 335 ''; 336 }; 337 338 lcdfilter = mkOption { 339 default = "default"; 340 type = types.enum ["none" "default" "light" "legacy"]; 341 description = '' 342 FreeType LCD filter, one of <literal>none</literal>, 343 <literal>default</literal>, <literal>light</literal>, or 344 <literal>legacy</literal>. 345 ''; 346 }; 347 348 }; 349 350 cache32Bit = mkOption { 351 default = false; 352 type = types.bool; 353 description = '' 354 Generate system fonts cache for 32-bit applications. 355 ''; 356 }; 357 358 }; 359 360 }; 361 362 }; 363 config = mkIf cfg.enable { 364 fonts.fontconfig.confPackages = [ confPkg ]; 365 366 environment.systemPackages = [ pkgs.fontconfig ]; 367 environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/"; 368 }; 369 370}