3 NixOS support 2 fontconfig versions, "support" and "latest".
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/
10 This module generates a package containing configuration files and link it in /etc/fonts.
12 Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing.
13 Low number means high priority.
17 { config, pkgs, lib, ... }:
22 cfg = config.fonts.fontconfig;
24 fcBool = x: "<bool>" + (boolToString x) + "</bool>";
26 # back-supported fontconfig version and package
27 # version is used for font cache generation
28 supportVersion = "210";
29 supportPkg = pkgs."fontconfig_${supportVersion}";
31 # latest fontconfig version and package
32 # version is used for configuration folder name, /etc/fonts/VERSION/
33 # note: format differs from supportVersion and can not be used with makeCacheConf
34 latestVersion = pkgs.fontconfig.configVersion;
35 latestPkg = pkgs.fontconfig;
37 # supported version fonts.conf
38 supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; };
40 # configuration file to read fontconfig cache
43 cacheConfSupport = makeCacheConf { version = supportVersion; };
44 cacheConfLatest = makeCacheConf { };
46 # generate the font cache setting file for a fontconfig version
47 # use latest when no version is passed
48 # When cross-compiling, we can’t generate the cache, so we skip the
49 # <cachedir> part. fontconfig still works but is a little slower in
51 makeCacheConf = { version ? null }:
56 else "fontconfig_${version}";
57 makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
58 cache = makeCache pkgs.${fcPackage};
59 cache32 = makeCache pkgs.pkgsi686Linux.${fcPackage};
61 pkgs.writeText "fc-00-nixos-cache.conf" ''
63 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
65 <!-- Font directories -->
66 ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
67 ${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
68 <!-- Pre-generated font caches -->
69 <cachedir>${cache}</cachedir>
70 ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
71 <cachedir>${cache32}</cachedir>
77 # rendering settings configuration file
79 renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" ''
81 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
84 <!-- Default rendering settings -->
85 <match target="pattern">
86 <edit mode="append" name="hinting">
87 ${fcBool cfg.hinting.enable}
89 <edit mode="append" name="autohint">
90 ${fcBool cfg.hinting.autohint}
92 <edit mode="append" name="hintstyle">
93 <const>hintslight</const>
95 <edit mode="append" name="antialias">
96 ${fcBool cfg.antialias}
98 <edit mode="append" name="rgba">
99 <const>${cfg.subpixel.rgba}</const>
101 <edit mode="append" name="lcdfilter">
102 <const>lcd${cfg.subpixel.lcdfilter}</const>
106 ${optionalString (cfg.dpi != 0) ''
107 <match target="pattern">
108 <edit name="dpi" mode="assign">
109 <double>${toString cfg.dpi}</double>
117 # local configuration file
118 localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
120 # default fonts configuration file
124 genDefault = fonts: name:
125 optionalString (fonts != [ ]) ''
126 <alias binding="same">
127 <family>${name}</family>
129 ${concatStringsSep ""
131 <family>${font}</family>
137 pkgs.writeText "fc-52-nixos-default-fonts.conf" ''
138 <?xml version='1.0'?>
139 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
142 <!-- Default fonts -->
143 ${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
145 ${genDefault cfg.defaultFonts.serif "serif"}
147 ${genDefault cfg.defaultFonts.monospace "monospace"}
149 ${genDefault cfg.defaultFonts.emoji "emoji"}
154 # bitmap font options
156 rejectBitmaps = pkgs.writeText "fc-53-no-bitmaps.conf" ''
157 <?xml version="1.0"?>
158 <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
161 ${optionalString (!cfg.allowBitmaps) ''
162 <!-- Reject bitmap fonts -->
166 <patelt name="scalable"><bool>false</bool></patelt>
172 <!-- Use embedded bitmaps in fonts like Calibri? -->
173 <match target="font">
174 <edit name="embeddedbitmap" mode="assign">
175 ${fcBool cfg.useEmbeddedBitmaps}
182 # reject Type 1 fonts
184 rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" ''
185 <?xml version="1.0"?>
186 <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
189 <!-- Reject Type 1 fonts -->
193 <patelt name="fontformat"><string>Type 1</string></patelt>
201 # fontconfig configuration package
202 confPkg = pkgs.runCommand "fontconfig-conf"
204 preferLocalBuild = true;
206 support_folder=$out/etc/fonts/conf.d
207 latest_folder=$out/etc/fonts/${latestVersion}/conf.d
209 mkdir -p $support_folder
210 mkdir -p $latest_folder
213 ln -s ${supportFontsConf} $support_folder/../fonts.conf
214 ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
215 $latest_folder/../fonts.conf
217 # fontconfig default config files
218 ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \
220 ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \
223 # update latest 51-local.conf path to look at the latest local.conf
224 rm $latest_folder/51-local.conf
226 substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
227 $latest_folder/51-local.conf \
228 --replace local.conf /etc/fonts/${latestVersion}/local.conf
230 # 00-nixos-cache.conf
231 ln -s ${cacheConfSupport} \
232 $support_folder/00-nixos-cache.conf
233 ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf
235 # 10-nixos-rendering.conf
236 ln -s ${renderConf} $support_folder/10-nixos-rendering.conf
237 ln -s ${renderConf} $latest_folder/10-nixos-rendering.conf
240 ${optionalString (!cfg.includeUserConf) ''
241 rm $support_folder/50-user.conf
242 rm $latest_folder/50-user.conf
245 # local.conf (indirect priority 51)
246 ${optionalString (cfg.localConf != "") ''
247 ln -s ${localConf} $support_folder/../local.conf
248 ln -s ${localConf} $latest_folder/../local.conf
251 # 52-nixos-default-fonts.conf
252 ln -s ${defaultFontsConf} $support_folder/52-nixos-default-fonts.conf
253 ln -s ${defaultFontsConf} $latest_folder/52-nixos-default-fonts.conf
256 ln -s ${rejectBitmaps} $support_folder/53-no-bitmaps.conf
257 ln -s ${rejectBitmaps} $latest_folder/53-no-bitmaps.conf
259 ${optionalString (!cfg.allowType1) ''
260 # 53-nixos-reject-type1.conf
261 ln -s ${rejectType1} $support_folder/53-nixos-reject-type1.conf
262 ln -s ${rejectType1} $latest_folder/53-nixos-reject-type1.conf
266 # Package with configuration files
267 # this merge all the packages in the fonts.fontconfig.confPackages list
268 fontconfigEtc = pkgs.buildEnv {
269 name = "fontconfig-etc";
270 paths = cfg.confPackages;
271 ignoreCollisions = true;
276 (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "allowBitmaps" ] [ "fonts" "fontconfig" "allowBitmaps" ])
277 (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "allowType1" ] [ "fonts" "fontconfig" "allowType1" ])
278 (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "useEmbeddedBitmaps" ] [ "fonts" "fontconfig" "useEmbeddedBitmaps" ])
279 (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "forceAutohint" ] [ "fonts" "fontconfig" "forceAutohint" ])
280 (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "renderMonoTTFAsBitmap" ] [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ])
281 (mkRemovedOptionModule [ "fonts" "fontconfig" "hinting" "style" ] "")
282 (mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
283 (mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
284 ] ++ lib.forEach [ "enable" "substitutions" "preset" ]
285 (opt: lib.mkRemovedOptionModule [ "fonts" "fontconfig" "ultimate" "${opt}" ] ''
286 The fonts.fontconfig.ultimate module and configuration is obsolete.
287 The repository has since been archived and activity has ceased.
288 https://github.com/bohoomil/fontconfig-ultimate/issues/171.
289 No action should be needed for font configuration, as the fonts.fontconfig
290 module is already used by default.
302 If enabled, a Fontconfig configuration file will be built
303 pointing to a set of default fonts. If you don't care about
304 running X11 applications or any other program that uses
305 Fontconfig, you can turn this option off and prevent a
306 dependency on all those fonts.
310 confPackages = mkOption {
312 type = with types; listOf path;
315 Fontconfig configuration packages.
319 antialias = mkOption {
323 Enable font antialiasing. At high resolution (> 200 DPI),
324 antialiasing has no visible effect; users of such displays may want
325 to disable this option.
333 Force DPI setting. Setting to <literal>0</literal> disables DPI
334 forcing; the DPI detected for the display will be used.
338 localConf = mkOption {
342 System-wide customization file contents, has higher priority than
343 <literal>defaultFonts</literal> settings.
348 monospace = mkOption {
349 type = types.listOf types.str;
350 default = [ "DejaVu Sans Mono" ];
352 System-wide default monospace font(s). Multiple fonts may be
353 listed in case multiple languages must be supported.
357 sansSerif = mkOption {
358 type = types.listOf types.str;
359 default = [ "DejaVu Sans" ];
361 System-wide default sans serif font(s). Multiple fonts may be
362 listed in case multiple languages must be supported.
367 type = types.listOf types.str;
368 default = [ "DejaVu Serif" ];
370 System-wide default serif font(s). Multiple fonts may be listed
371 in case multiple languages must be supported.
376 type = types.listOf types.str;
377 default = [ "Noto Color Emoji" ];
379 System-wide default emoji font(s). Multiple fonts may be listed
380 in case a font does not support all emoji.
382 Note that fontconfig matches color emoji fonts preferentially,
383 so if you want to use a black and white font while having
384 a color font installed (eg. Noto Color Emoji installed alongside
385 Noto Emoji), fontconfig will still choose the color font even
386 when it is later in the list.
396 Enable font hinting. Hinting aligns glyphs to pixel boundaries to
397 improve rendering sharpness at low resolution. At high resolution
398 (> 200 dpi) hinting will do nothing (at best); users of such
399 displays may want to disable this option.
403 autohint = mkOption {
407 Enable the autohinter in place of the default interpreter.
408 The results are usually lower quality than correctly-hinted
409 fonts, but better than unhinted fonts.
414 includeUserConf = mkOption {
418 Include the user configuration from
419 <filename>~/.config/fontconfig/fonts.conf</filename> or
420 <filename>~/.config/fontconfig/conf.d</filename>.
428 type = types.enum [ "rgb" "bgr" "vrgb" "vbgr" "none" ];
430 Subpixel order. The overwhelming majority of displays are
431 <literal>rgb</literal> in their normal orientation. Select
432 <literal>vrgb</literal> for mounting such a display 90 degrees
433 clockwise from its normal orientation or <literal>vbgr</literal>
434 for mounting 90 degrees counter-clockwise. Select
435 <literal>bgr</literal> in the unlikely event of mounting 180
436 degrees from the normal orientation. Reverse these directions in
437 the improbable event that the display's native subpixel order is
438 <literal>bgr</literal>.
442 lcdfilter = mkOption {
444 type = types.enum [ "none" "default" "light" "legacy" ];
446 FreeType LCD filter. At high resolution (> 200 DPI), LCD filtering
447 has no visible effect; users of such displays may want to select
448 <literal>none</literal>.
454 cache32Bit = mkOption {
458 Generate system fonts cache for 32-bit applications.
462 allowBitmaps = mkOption {
466 Allow bitmap fonts. Set to <literal>false</literal> to ban all
471 allowType1 = mkOption {
475 Allow Type-1 fonts. Default is <literal>false</literal> because of
480 useEmbeddedBitmaps = mkOption {
483 description = ''Use embedded bitmaps in fonts like Calibri.'';
493 environment.systemPackages = [ pkgs.fontconfig ];
494 environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/";
495 security.apparmor.includes."abstractions/fonts" = ''
497 r ${supportFontsConf}
498 r ${latestPkg.out}/etc/fonts/fonts.conf
500 # fontconfig default config files
501 r ${supportPkg.out}/etc/fonts/conf.d/*.conf,
502 r ${latestPkg.out}/etc/fonts/conf.d/*.conf,
504 substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
505 $latest_folder/51-local.conf \
506 --replace local.conf /etc/fonts/${latestVersion}/local.conf
508 # 00-nixos-cache.conf
509 r ${cacheConfSupport},
510 r ${cacheConfLatest},
512 # 10-nixos-rendering.conf
515 # local.conf (indirect priority 51)
516 ${optionalString (cfg.localConf != "") ''
520 # 52-nixos-default-fonts.conf
521 r ${defaultFontsConf},
526 ${optionalString (!cfg.allowType1) ''
527 # 53-nixos-reject-type1.conf
532 (mkIf (cfg.enable && !cfg.penultimate.enable) {
533 fonts.fontconfig.confPackages = [ confPkg ];