I've installed Google golang go fonts as a user

  • I dropped go*.ttf in ~/.fonts
  • I ran fc-cache -fv

and now I can use the new fonts everywhere, except in xterm

$ fc-match gomono
GoMono-Regular.ttf: "GoMono" "Regular"
$ xterm -fa gomono

and I get

enter image description here

As you can see, xterm grabs the italic variant of the font... I have used gomono in other programs, e.g., emacs, and what I get is of course the regular, roman font...

There is something I missed or is it a quirk specific to xterm?

I'm using debian sid and xterm really is good, old xterm.

up vote 3 down vote accepted

Actually it's a quirk of fontconfig that xterm isn't working around. Some other applications which you may have in mind supplant the font family with additional parameters, so there may be some improvement possible.

If you run

xterm -report-fonts -fa 'gomono'

you would see exactly what was loaded:

Loaded XftFonts(gomono[normal])
                first char:    32
                last char:     64258
                missing-chars: 63567
                present-chars: 660
        Go Mono-8
        familylang=en
        style=Italic
        stylelang=en
        fullname=Go Mono Italic
        fullnamelang=en
        slant=100
        weight=80
        width=100
        pixelsize=10.6712
        spacing=100
        foundry=b&h
        antialias=True
        hintstyle=3
        hinting=True
        verticallayout=False
        autohint=False
        globaladvance=True
        file=/users/tom/.fonts/gomono/Go-Mono-Italic.ttf

and the fontconfig user manual says that 110 is oblique. fontconfig sees this list of files in gomono:

Go-Bold-Italic.ttf
Go-Bold.ttf
Go-Italic.ttf
Go-Medium-Italic.ttf
Go-Medium.ttf
Go-Mono-Bold-Italic.ttf
Go-Mono-Bold.ttf
Go-Mono-Italic.ttf
Go-Mono.ttf
Go-Regular.ttf

and prefers the italic font based on its internal scoring system. If you also set the environment variable FC_DEBUG to 127 (each bit means something), then you can see the scores. Here is an extract comparing the regular and italic fonts:

Regular:

 slant: 100001  0(i)(s),  100(i)(w)
 weight: 20001  100(i)(s),  80(i)(w)
 width: 1  100(i)(s),  100(i)(w)
 lang: 1001  "en-US"(s),  aa|af|av|ay|be|bg|bi|br|bs|ca|ce|ch|co|cs|cy|da|de|el|en|eo|es|et|eu|fi|fj|fo|fr|fur|fy|gd|gl|gv|ho|hr|hu|ia|id|ie|ik|io|is|it|ki|kl|kum|la|lb|lez|lt|lv|mg|mh|mk|mo|mt|nb|nds|nl|nn|no|nr|nso|ny|oc|om|os|pl|pt|rm|ro|ru|se|sel|sk|sl|sma|smj|smn|so|sq|sr|ss|st|sv|sw|tk|tl|tn|tr|ts|uk|uz|vo|vot|wa|wen|wo|xh|yap|zu|an|crh|csb|fil|hsb|ht|jv|kj|ku-tr|kwm|lg|li|ms|na|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(w)
 fontversion: 2.14735e+12  2147483647(i)(s),  131269(i)(w)
 decorative: 1  FcFalse(s),  FcFalse(w)
Score 0 0 1 1001 1002 0 0 0 100001 20001 1 1 0 0 0 2.14735e+12
Font 21 Pattern has 20 elts (size 20)
        family: "Go Mono"(w)
        familylang: "en"(w)
        style: "Regular"(w)
        stylelang: "en"(w)
        fullname: "Go Mono"(w)  
        fullnamelang: "en"(w)
        slant: 0(i)(w)
        weight: 80(i)(w)
        width: 100(i)(w)
        spacing: 100(i)(w)
        foundry: "b&h"(w)   
        file: "/users/tom/.fonts/gomono/Go-Mono.ttf"(w)   

Italic:

 slant: 1  0(i)(s),  0(i)(w)
 weight: 80001  100(i)(s),  180(i)(w)
 width: 1  100(i)(s),  100(i)(w)
 spacing: 1  100(i)(s),  100(i)(w)   
 lang: 1001  "en-US"(s),  aa|af|av|ay|be|bg|bi|br|bs|ca|ce|ch|co|cs|cy|da|de|el|en|eo|es|et|eu|fi|fj|fo|fr|fur|fy|gd|gl|gv|ho|hr|hu|ia|id|ie|ik|io|is|it|ki|kl|kum|la|lb|lez|lt|lv|mg|mh|mk|mo|mt|nb|nds|nl|nn|no|nr|nso|ny|oc|om|os|pl|pt|rm|ro|ru|se|sel|sk|sl|sma|smj|smn|so|sq|sr|ss|st|sv|sw|tk|tl|tn|tr|ts|uk|uz|vo|vot|wa|wen|wo|xh|yap|zu|an|crh|csb|fil|hsb|ht|jv|kj|ku-tr|kwm|lg|li|ms|na|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(w)
 fontversion: 2.14735e+12  2147483647(i)(s),  131269(i)(w)
 decorative: 1  FcFalse(s),  FcFalse(w)
Score 0 0 1 1001 1002 1 0 0 1 80001 1 1 0 0 0 2.14735e+12 
Font 20 Pattern has 19 elts (size 19)
        family: "Go Mono"(w)
        familylang: "en"(w)
        style: "Italic"(w)
        stylelang: "en"(w)
        fullname: "Go Mono Italic"(w)
        fullnamelang: "en"(w)
        slant: 100(i)(w)
        weight: 80(i)(w)
        width: 100(i)(w)
        foundry: "b&h"(w)
        file: "/users/tom/.fonts/gomono/Go-Mono-Italic.ttf"(w)

and finally

 slant: 1  0(i)(s),  0(i)(w)
 weight: 20001  100(i)(s),  80(i)(w)
 width: 1  100(i)(s),  100(i)(w)
 lang: 2001  "en-US"(s),  (w)
 fontversion: 2.14748e+12  2147483647(i)(s),  0(i)(w)
 decorative: 1  FcFalse(s),  FcFalse(w)
Score 0 0 1001 2001 1002 0 0 0 1 20001 1 1 0 0 0 2.14748e+12
Best score 0 0 1 1001 1002 0 0 0 100001 20001 1 1 0 0 0 2.14735e+12
Pattern has 19 elts (size 19)
        family: "Go Mono"(w)
        familylang: "en"(w)  
        style: "Italic"(w)  
        stylelang: "en"(w) 
        fullname: "Go Mono Italic"(w)
        fullnamelang: "en"(w)
        slant: 100(i)(w)
        weight: 80(i)(w)
        width: 100(i)(w)
        foundry: "b&h"(w)
        file: "/users/tom/.fonts/gomono/Go-Mono-Italic.ttf"(w)

Only items 8 and 9 (counting from 0) differ; fontconfig treats those numbers equally, and (see source for fcmatch.c) happens to choose the last font checked which improved (decreased) the score for any of those numbers:

        for (i = 0; i < PRI_END; i++)
        {   
            if (best && bestscore[i] < score[i])
                break;
            if (!best || score[i] < bestscore[i])
            {   
                for (i = 0; i < PRI_END; i++)
                    bestscore[i] = score[i];
                best = s->fonts[f];
                break;
            }
        }

In my trace, that happens to be the italic font, using spacing and width as the details which were the deciding factors. Looking at the current source, I can see that there are additional features checked (so your details may differ), but the basic algorithm is the same.

A little investigation shows that what triggers the quirk in fontconfig is that xterm asks for a monospaced font. The choices are (see the user manual):

  proportional    spacing         0
  dual            spacing         90
  mono            spacing         100
  charcell        spacing         110

or to leave it unconstrained. If you happened to choose a proportional font, that would not look good, but eliminating the restriction in xterm's source-code is the most obvious workaround. fontconfig lacks a way for you to override settings already in the pattern.

That's not a bug in xterm, but a workaround. The original change to use the spacing=mono property was added to xterm in November 2000 by Keith Packard (who also is the original author of Xft and fontconfig).

You can easily demonstrate the bug in fontconfig by doing this:

fc-match 'Go Mono:spacing=monospace'

which gives me

Go-Mono-Italic.ttf: "Go Mono" "Italic"
  • OK, so I've tried a more complete specification. xterm -fa 'Go Mono':style=Regular and, surprise, for xterm it's still an italic face... — OTOH fc-match 'Go Mono':style=Italic returns GoMono-Regular.ttf: "GoMono" "Regular" ! — am I confused? yes I am... – gboffi Nov 22 '16 at 19:02
  • I did that too, and saw that there is--as noted--some "quirk" of fontconfig needing a workaround, since fontconfig appears to ignore the style setting here. I think the key to it is the "choose the last font checked" aspect, which doesn't always give good results. – Thomas Dickey Nov 22 '16 at 22:26

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.