# HG changeset patch # User Kenichi Handa # Date 1213836108 0 # Node ID 3376493a3ad47e3e48db1e2ab49623ac6641ac49 # Parent 83c52d8906f5bc7590a02874f04bd7528336c349 (QChinting , QCautohint, QChintstyle, QCrgba) (QCembolden): New variables. (syms_of_xftfont): DEFSYM them. (xftfont_open): Call XftFontMatch. Don't trust the result of XftTextExtents8 if the pixel_size is less than 5. diff -r 83c52d8906f5 -r 3376493a3ad4 src/xftfont.c --- a/src/xftfont.c Wed Jun 18 21:14:07 2008 +0000 +++ b/src/xftfont.c Thu Jun 19 00:41:48 2008 +0000 @@ -38,6 +38,7 @@ /* Xft font driver. */ static Lisp_Object Qxft; +static Lisp_Object QChinting , QCautohint, QChintstyle, QCrgba, QCembolden; /* The actual structure for Xft font that can be casted to struct font. */ @@ -175,6 +176,7 @@ } extern Lisp_Object ftfont_font_format P_ ((FcPattern *)); +extern Lisp_Object QCantialias; static FcChar8 ascii_printable[95]; @@ -184,9 +186,10 @@ Lisp_Object entity; int pixel_size; { + FcResult result; Display *display = FRAME_X_DISPLAY (f); - Lisp_Object val, filename, font_object; - FcPattern *pat = NULL; + Lisp_Object val, filename, tail, font_object; + FcPattern *pat = NULL, *match; struct xftfont_info *xftfont_info = NULL; struct font *font; double size = 0; @@ -207,17 +210,48 @@ size = pixel_size; pat = FcPatternCreate (); FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename)); + FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity)); + i = FONT_SLANT_NUMERIC (entity) - 100; + if (i < 0) i = 0; + FcPatternAddInteger (pat, FC_SLANT, i); + FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity)); FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size); - /*FcPatternAddBool (pat, FC_ANTIALIAS, FcTrue);*/ val = AREF (entity, FONT_FAMILY_INDEX); if (! NILP (val)) FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); + for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) + { + Lisp_Object key, val; + + key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); + if (EQ (key, QCantialias)) + FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); + else if (EQ (key, QChinting)) + FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); + else if (EQ (key, QCautohint)) + FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue); + else if (EQ (key, QChintstyle)) + { + if (INTEGERP (val)) + FcPatternAddInteger (pat, FC_RGBA, XINT (val)); + } + else if (EQ (key, QCrgba)) + { + if (INTEGERP (val)) + FcPatternAddInteger (pat, FC_RGBA, XINT (val)); + } + else if (EQ (key, QCembolden)) + FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); + } FcConfigSubstitute (NULL, pat, FcMatchPattern); BLOCK_INPUT; XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); - xftfont = XftFontOpenPattern (display, pat); + match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result); + FcPatternDestroy (pat); + xftfont = XftFontOpenPattern (display, match); UNBLOCK_INPUT; + if (! xftfont) return Qnil; /* We should not destroy PAT here because it is kept in XFTFONT and @@ -280,11 +314,17 @@ UNBLOCK_INPUT; font->ascent = xftfont->ascent; - if (font->ascent < extents.y) - font->ascent = extents.y; font->descent = xftfont->descent; - if (font->descent < extents.height - extents.y) - font->descent = extents.height - extents.y; + if (pixel_size >= 5) + { + /* The above condition is a dirty workaround because + XftTextExtents8 behaves strangely for some fonts + (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */ + if (font->ascent < extents.y) + font->ascent = extents.y; + if (font->descent < extents.height - extents.y) + font->descent = extents.height - extents.y; + } font->height = font->ascent + font->descent; ft_face = XftLockFace (xftfont); @@ -570,6 +610,11 @@ syms_of_xftfont () { DEFSYM (Qxft, "xft"); + DEFSYM (QChinting, ":hinting"); + DEFSYM (QCautohint, ":autohing"); + DEFSYM (QChintstyle, ":hintstyle"); + DEFSYM (QCrgba, ":rgba"); + DEFSYM (QCembolden, ":embolden"); xftfont_driver = ftfont_driver; xftfont_driver.type = Qxft;