Variable Font in Emacs


Variable fonts are an evolution of the OpenType font specification that enables many different variations of a typeface to be incorporated into a single file, rather than having a separate font file for every width, weight, or style. Please note that the fonts are designed for readability. These are not simple geometric transformations. Hence, the fonts may or may not support full range of variations specified by the standards.

Font weight ranges from 100 to 900 for variable fonts. For static fonts, this range is between 0 to 215. You can use FcWeightToOpenTypeDouble() for converting static font weight to variable font weight.

Font width ranges from 50 to 200. This is a percentage value. For example, ultra-expanded is 200% of normal width. This is same for static font.

In Emacs, use :weight and :width face attributes for setting the values.

cairo_font_options_set_variations() Cairo API can be used to render these variations in Emacs. Please note that the sequence of axes - wght is followed by wdth when both are available.

  cairo_font_options_t *options = cairo_font_options_create ();
  const char *variations = "wght=400,wdth=1";
  cairo_font_options_set_variations (options, variations);
 

 

Side note: 

- In the absence of init.el configuration, Emacs will start with font settings from the system settings. In Linux, this might mean your dconf settings will overrride gconf settings if you have both.

- buffer-face-mode is a minor mode for a buffer-specific default face. When enabled, the face specified by the variable ‘buffer-face-mode-face’ is used to display the buffer text.

- Pango 1.44 dropped support for Adobe Type 1 PFB fonts. This looks more like a freedesktop decision - meaning it affects Cairo and Harfbuzz too. Consequently, PFB fonts break in Emacs too.

 

Test Code

Code for printing text in varying widths and weights in "Noto Sans" Font.

(defvar facemenu--widths
  '(ultra-condensed extra-condensed condensed semi-condensed normal semi-expanded expanded extra-expanded ultra-expanded))

(defvar facemenu--weights
  '(thin extra-light light semi-light book normal medium semi-bold bold extra-bold heavy extra-black))
 
(defun test2 (prefix)
  (interactive "P")
  (let* ((items (if prefix facemenu--weights facemenu--widths))
         txt)
    (dolist (i items)
      (setq txt (propertize (symbol-name i) 'font-lock-face
                            (list :family "Noto Sans"
                                  (if prefix :weight :width) i)))
      (insert txt "\n"))
    ))
 

 

References

  1. Google Font type tester
  2. Harfbuzz API for Variable Fonts 
  3. Cairo Text rendering 
  4. State of Text Rendering 
     

 

Comments

Popular posts from this blog

GNU Emacs as a Comic Book Reader

Data Visualization with GNU Emacs

Mozilla Readability in GNU Emacs