Subject: bug#8046: [PATCH] Incorrect font selection in fontconfig driver

From: Kostya Stopani <[email-masked]>
Date: Tue, 15 Feb 2011 21:40:10 +0300

Attached file in koi8-r encoding displays incorrectly on Linux with
default DejaVu (from fontset-startup) and some other fonts (on
emacs-24.0.50.12). Cyrillic characters are rendered in oblique style
instead of normal. Here's a part of M-x font-show-log showing this:

default fontset: font for: 1057
ftfont-list: -unknown-DejaVu Sans Mono-*-k-koi8-r
  -unknown-DejaVu Sans Mono-bold-oblique-normal-*-m-0-isoso6060646-1
  -unknown-DejaVu Sans Mono-normal-oblique-normal-*-m-0-iso10646-1
  -unknown-DejaVu Sans Mono-bold-normal-normal-*-0soso101064646-1
xfont-list: -unknown-DejaVu Sans Mono-*-*-*-*-*-*-*-*-*-*-koi8-r
list: -unknown-DejaVu Sans Mono-*-k-koi8-r
  -unknown-DejaVu Sans Mono-bold-oblique-normal-*-m-0-isoso6060646-1
  -unknown-DejaVu Sans Mono-normal-oblique-normal-*-m-0-iso10646-1
  -unknown-DejaVu Sans Mono-bold-normal-normal-*-0soso101064646-1
sort-by: -*-normal-normal-normal-*-13-*
  xft:-unknown-DejaVu Sans Mono-normal-oblique-normal-*-m-0-iso10646-1
open: -unknown-DejaVu Sans Mono-normal-oblique-normal-*-m-0-iso10646-1
  xft:-unknown-DejaVu Sans Mono-normal-oblique-normal-*-13-*-m-0-iso10646-1

The reason is that ftfont_list function filters out fonts when its
langname parameter doesn't match font's adstyle property. But adstyle
really most of the time has neutral values like "Book" or
"Semicondensed". As far as I know it can contain language codes only
for PCF japanese and korean fonts (respectively "ja" and "ko"). A
patch to fix this behaviour is below.

* src/ftfont.c (ftfont_list): reject fonts using langname only if
adstyle is "ja" or "ko".

=== modified file 'src/ftfont.c'
*** src/ftfont.c	2011-02-05 22:30:14 +0000
--- src/ftfont.c	2011-02-15 18:13:28 +0000
*************** ftfont_list (Lisp_Object frame, Lisp_Obj
*** 1026,1031 ****
--- 1026,1032 ----
  				  SSDATA (SYMBOL_NAME (this_adstyle))) != 0))
  	    continue;
  	  if (langname
+ 	      && (xstrcasecmp (langname, "ja") == 0 || xstrcasecmp (langname, "ko") == 0)
  	      && ! NILP (this_adstyle)
  	      && xstrcasecmp (langname, SSDATA (SYMBOL_NAME (this_adstyle))))
  	    continue;