X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b2e6b10fe2d40020a75ab0025af98a4abf339cd2..b71ac3dd2a20488c5513df8a8c15d7ea34a9acd3:/src/xftfont.c diff --git a/src/xftfont.c b/src/xftfont.c index af03cc43ec..af0feb9b7e 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -1,15 +1,15 @@ /* xftfont.c -- XFT font driver. - Copyright (C) 2006 Free Software Foundation, Inc. - Copyright (C) 2006 + Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2009 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H13PRO009 This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,9 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ #include #include @@ -35,10 +33,12 @@ Boston, MA 02110-1301, USA. */ #include "charset.h" #include "fontset.h" #include "font.h" +#include "ftfont.h" /* 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. */ @@ -46,10 +46,17 @@ static Lisp_Object Qxft; struct xftfont_info { struct font font; + /* The following four members must be here in this order to be + compatible with struct ftfont_info (in ftfont.c). */ +#ifdef HAVE_LIBOTF + int maybe_otf; /* Flag to tell if this may be OTF or not. */ + OTF *otf; +#endif /* HAVE_LIBOTF */ + FT_Size ft_size; + int index; Display *display; int screen; XftFont *xftfont; - FT_Face ft_face; /* set to XftLockFace (xftfont) */ }; /* Structure pointed by (struct face *)->extra */ @@ -58,13 +65,11 @@ struct xftface_info { XftColor xft_fg; /* color for face->foreground */ XftColor xft_bg; /* color for face->background */ - XftDraw *xft_draw; }; static void xftfont_get_colors P_ ((FRAME_PTR, struct face *, GC gc, struct xftface_info *, XftColor *fg, XftColor *bg)); -static Font xftfont_default_fid P_ ((FRAME_PTR)); /* Setup foreground and background colors of GC into FG and BG. If @@ -132,45 +137,19 @@ xftfont_get_colors (f, face, gc, xftface_info, fg, bg) } } -/* Return the default Font ID on frame F. The Returned Font ID is - stored in the GC of the frame F, but the font is never used. So, - any ID is ok as long as it is valid. */ - -static Font -xftfont_default_fid (f) - FRAME_PTR f; -{ - static int fid_known; - static Font fid; - - if (! fid_known) - { - fid = XLoadFont (FRAME_X_DISPLAY (f), "fixed"); - if (! fid) - { - fid = XLoadFont (FRAME_X_DISPLAY (f), "*"); - if (! fid) - abort (); - } - fid_known = 1; - } - return fid; -} - static Lisp_Object xftfont_list P_ ((Lisp_Object, Lisp_Object)); static Lisp_Object xftfont_match P_ ((Lisp_Object, Lisp_Object)); -static struct font *xftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); +static Lisp_Object xftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); static void xftfont_close P_ ((FRAME_PTR, struct font *)); static int xftfont_prepare_face P_ ((FRAME_PTR, struct face *)); static void xftfont_done_face P_ ((FRAME_PTR, struct face *)); +static int xftfont_has_char P_ ((Lisp_Object, int)); static unsigned xftfont_encode_char P_ ((struct font *, int)); static int xftfont_text_extents P_ ((struct font *, unsigned *, int, struct font_metrics *)); static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int)); - -static int xftfont_anchor_point P_ ((struct font *, unsigned, int, - int *, int *)); +static int xftfont_end_for_frame P_ ((FRAME_PTR f)); struct font_driver xftfont_driver; @@ -179,13 +158,11 @@ xftfont_list (frame, spec) Lisp_Object frame; Lisp_Object spec; { - Lisp_Object val = ftfont_driver.list (frame, spec); - int i; - - if (! NILP (val)) - for (i = 0; i < ASIZE (val); i++) - ASET (AREF (val, i), FONT_TYPE_INDEX, Qxft); - return val; + Lisp_Object list = ftfont_driver.list (frame, spec), tail; + + for (tail = list; CONSP (tail); tail = XCDR (tail)) + ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft); + return list; } static Lisp_Object @@ -195,100 +172,149 @@ xftfont_match (frame, spec) { Lisp_Object entity = ftfont_driver.match (frame, spec); - if (VECTORP (entity)) + if (! NILP (entity)) ASET (entity, FONT_TYPE_INDEX, Qxft); return entity; } -extern Lisp_Object ftfont_font_format P_ ((FcPattern *)); +extern Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); +extern FcCharSet *ftfont_get_fc_charset P_ ((Lisp_Object)); +extern Lisp_Object QCantialias; static FcChar8 ascii_printable[95]; -static struct font * +static Lisp_Object xftfont_open (f, entity, pixel_size) FRAME_PTR f; Lisp_Object entity; int pixel_size; { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + FcResult result; Display *display = FRAME_X_DISPLAY (f); - Lisp_Object val; - FcPattern *pattern, *pat = NULL; - FcChar8 *file; + Lisp_Object val, filename, index, tail, font_object; + FcPattern *pat = NULL, *match; struct xftfont_info *xftfont_info = NULL; - XFontStruct *xfont = NULL; struct font *font; double size = 0; XftFont *xftfont = NULL; int spacing; - char *name; - int len; + char name[256]; + int len, i; XGlyphInfo extents; - - val = AREF (entity, FONT_EXTRA_INDEX); - if (XTYPE (val) != Lisp_Misc - || XMISCTYPE (val) != Lisp_Misc_Save_Value) - return NULL; - pattern = XSAVE_VALUE (val)->pointer; - if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) - return NULL; - + FT_Face ft_face; + + val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); + if (! CONSP (val)) + return Qnil; + val = XCDR (val); + filename = XCAR (val); + index = XCDR (val); size = XINT (AREF (entity, FONT_SIZE_INDEX)); if (size == 0) size = pixel_size; - pat = FcPatternCreate (); - FcPatternAddString (pat, FC_FILE, file); + 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))); - FcConfigSubstitute (NULL, pat, FcMatchPattern); + val = AREF (entity, FONT_FOUNDRY_INDEX); + if (! NILP (val)) + FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); + val = AREF (entity, FONT_SPACING_INDEX); + if (! NILP (val)) + FcPatternAddInteger (pat, FC_SPACING, XINT (val)); + val = AREF (entity, FONT_DPI_INDEX); + if (! NILP (val)) + { + double dbl = XINT (val); + + FcPatternAddDouble (pat, FC_DPI, dbl); + } + val = AREF (entity, FONT_AVGWIDTH_INDEX); + if (INTEGERP (val) && XINT (val) == 0) + FcPatternAddBool (pat, FC_SCALABLE, FcTrue); + /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz + over 10x20-ISO8859-1.pcf.gz). */ + FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); + + 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)); + } +#ifdef FC_EMBOLDEN + else if (EQ (key, QCembolden)) + FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); +#endif + } + + FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename)); + FcPatternAddInteger (pat, FC_INDEX, XINT (index)); + 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); + ft_face = XftLockFace (xftfont); + UNBLOCK_INPUT; + + if (! xftfont) + { + XftPatternDestroy (match); + return Qnil; + } /* We should not destroy PAT here because it is kept in XFTFONT and destroyed automatically when XFTFONT is closed. */ - if (! xftfont) - goto err; - - xftfont_info = malloc (sizeof (struct xftfont_info)); - if (! xftfont_info) - goto err; - xfont = malloc (sizeof (XFontStruct)); - if (! xfont) - goto err; + font_object = font_make_object (VECSIZE (struct xftfont_info), entity, size); + ASET (font_object, FONT_TYPE_INDEX, Qxft); + len = font_unparse_xlfd (entity, size, name, 256); + if (len > 0) + ASET (font_object, FONT_NAME_INDEX, make_string (name, len)); + len = font_unparse_fcname (entity, size, name, 256); + if (len > 0) + ASET (font_object, FONT_FULLNAME_INDEX, make_string (name, len)); + else + ASET (font_object, FONT_FULLNAME_INDEX, + AREF (font_object, FONT_NAME_INDEX)); + ASET (font_object, FONT_FILE_INDEX, filename); + ASET (font_object, FONT_FORMAT_INDEX, + ftfont_font_format (xftfont->pattern, filename)); + font = XFONT_OBJECT (font_object); + font->pixel_size = pixel_size; + font->driver = &xftfont_driver; + font->encoding_charset = font->repertory_charset = -1; + + xftfont_info = (struct xftfont_info *) font; xftfont_info->display = display; xftfont_info->screen = FRAME_X_SCREEN_NUMBER (f); xftfont_info->xftfont = xftfont; - xftfont_info->ft_face = XftLockFace (xftfont); - - font = (struct font *) xftfont_info; - font->format = ftfont_font_format (xftfont->pattern); - font->entity = entity; font->pixel_size = size; font->driver = &xftfont_driver; - len = 96; - name = malloc (len); - while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0) - { - char *new = realloc (name, len += 32); - - if (! new) - free (name); - name = new; - } - if (! name) - goto err; - font->font.full_name = font->font.name = name; - font->file_name = (char *) file; - font->font.size = xftfont->max_advance_width; - font->font.charset = font->encoding_charset = font->repertory_charset = -1; - - if (FcPatternGetInteger (xftfont->pattern, FC_SPACING, 0, &spacing) - != FcResultMatch) + if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))) + spacing = XINT (AREF (entity, FONT_SPACING_INDEX)); + else spacing = FC_PROPORTIONAL; if (! ascii_printable[0]) { @@ -296,81 +322,85 @@ xftfont_open (f, entity, pixel_size) for (i = 0; i < 95; i++) ascii_printable[i] = ' ' + i; } + BLOCK_INPUT; if (spacing != FC_PROPORTIONAL) { - font->font.average_width = font->font.space_width + font->min_width = font->average_width = font->space_width = xftfont->max_advance_width; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); } else { XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents); - font->font.space_width = extents.xOff; - if (font->font.space_width <= 0) + font->space_width = extents.xOff; + if (font->space_width <= 0) /* dirty workaround */ - font->font.space_width = pixel_size; + font->space_width = pixel_size; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); - font->font.average_width = (font->font.space_width + extents.xOff) / 95; + font->average_width = (font->space_width + extents.xOff) / 95; } 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; - font->font.height = font->ascent + font->descent; + 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; - /* Unfortunately Xft doesn't provide a way to get minimum char - width. So, we use space_width instead. */ - font->min_width = font->font.space_width; - - font->font.baseline_offset = 0; - font->font.relative_compose = 0; - font->font.default_ascent = 0; - font->font.vertical_centering = 0; - - /* Setup pseudo XFontStruct */ - xfont->fid = xftfont_default_fid (f); - xfont->ascent = font->ascent; - xfont->descent = font->descent; - xfont->max_bounds.descent = font->descent; - xfont->max_bounds.width = xftfont->max_advance_width; - xfont->min_bounds.width = font->font.space_width; - font->font.font = xfont; - - dpyinfo->n_fonts++; - - /* Set global flag fonts_changed_p to non-zero if the font loaded - has a character with a smaller width than any other character - before, or if the font loaded has a smaller height than any other - font loaded before. If this happens, it will make a glyph matrix - reallocation necessary. */ - if (dpyinfo->n_fonts == 1) + if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0) { - dpyinfo->smallest_font_height = font->font.height; - dpyinfo->smallest_char_width = font->min_width; - fonts_changed_p = 1; + int upEM = ft_face->units_per_EM; + + font->underline_position = -ft_face->underline_position * size / upEM; + font->underline_thickness = ft_face->underline_thickness * size / upEM; + if (font->underline_thickness > 2) + font->underline_position -= font->underline_thickness / 2; } else { - if (dpyinfo->smallest_font_height > font->font.height) - dpyinfo->smallest_font_height = font->font.height, - fonts_changed_p |= 1; - if (dpyinfo->smallest_char_width > font->min_width) - dpyinfo->smallest_char_width = font->min_width, - fonts_changed_p |= 1; + font->underline_position = -1; + font->underline_thickness = 0; } +#ifdef HAVE_LIBOTF + xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; + xftfont_info->otf = NULL; +#endif /* HAVE_LIBOTF */ + xftfont_info->ft_size = ft_face->size; - return font; + /* Unfortunately Xft doesn't provide a way to get minimum char + width. So, we use space_width instead. */ + font->min_width = font->space_width; + + font->baseline_offset = 0; + font->relative_compose = 0; + font->default_ascent = 0; + font->vertical_centering = 0; +#ifdef FT_BDF_H + if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT)) + { + BDF_PropertyRec rec; + + if (FT_Get_BDF_Property (ft_face, "_MULE_BASELINE_OFFSET", &rec) == 0 + && rec.type == BDF_PROPERTY_TYPE_INTEGER) + font->baseline_offset = rec.u.integer; + if (FT_Get_BDF_Property (ft_face, "_MULE_RELATIVE_COMPOSE", &rec) == 0 + && rec.type == BDF_PROPERTY_TYPE_INTEGER) + font->relative_compose = rec.u.integer; + if (FT_Get_BDF_Property (ft_face, "_MULE_DEFAULT_ASCENT", &rec) == 0 + && rec.type == BDF_PROPERTY_TYPE_INTEGER) + font->default_ascent = rec.u.integer; + } +#endif - err: - if (xftfont) XftFontClose (display, xftfont); - UNBLOCK_INPUT; - if (xftfont_info) free (xftfont_info); - if (xfont) free (xfont); - return NULL; + return font_object; } static void @@ -380,12 +410,14 @@ xftfont_close (f, font) { struct xftfont_info *xftfont_info = (struct xftfont_info *) font; +#ifdef HAVE_LIBOTF + if (xftfont_info->otf) + OTF_close (xftfont_info->otf); +#endif + BLOCK_INPUT; XftUnlockFace (xftfont_info->xftfont); XftFontClose (xftfont_info->display, xftfont_info->xftfont); - if (font->font.name) - free (font->font.name); - free (font); - FRAME_X_DISPLAY_INFO (f)->n_fonts--; + UNBLOCK_INPUT; } static int @@ -407,16 +439,8 @@ xftfont_prepare_face (f, face) xftface_info = malloc (sizeof (struct xftface_info)); if (! xftface_info) return -1; - - BLOCK_INPUT; - xftface_info->xft_draw = XftDrawCreate (FRAME_X_DISPLAY (f), - FRAME_X_WINDOW (f), - FRAME_X_VISUAL (f), - FRAME_X_COLORMAP (f)); xftfont_get_colors (f, face, face->gc, NULL, &xftface_info->xft_fg, &xftface_info->xft_bg); - UNBLOCK_INPUT; - face->extra = xftface_info; return 0; } @@ -427,7 +451,7 @@ xftfont_done_face (f, face) struct face *face; { struct xftface_info *xftface_info; - + #if 0 /* This doesn't work if face->ascii_face doesn't use an Xft font. */ if (face != face->ascii_face @@ -438,12 +462,36 @@ xftfont_done_face (f, face) xftface_info = (struct xftface_info *) face->extra; if (xftface_info) { - BLOCK_INPUT; - XftDrawDestroy (xftface_info->xft_draw); - UNBLOCK_INPUT; free (xftface_info); + face->extra = NULL; } - face->extra = NULL; +} + +extern Lisp_Object Qja, Qko; + +static int +xftfont_has_char (font, c) + Lisp_Object font; + int c; +{ + struct xftfont_info *xftfont_info; + struct charset *cs = NULL; + + if (FONT_ENTITY_P (font)) + return ftfont_driver.has_char (font, c); + + if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja) + && charset_jisx0208 >= 0) + cs = CHARSET_FROM_ID (charset_jisx0208); + else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko) + && charset_ksc5601 >= 0) + cs = CHARSET_FROM_ID (charset_ksc5601); + if (cs) + return (ENCODE_CHAR (cs, c) != CHARSET_INVALID_CODE (cs)); + + xftfont_info = (struct xftfont_info *) XFONT_OBJECT (font); + return (XftCharExists (xftfont_info->display, xftfont_info->xftfont, + (FcChar32) c) == FcTrue); } static unsigned @@ -454,8 +502,8 @@ xftfont_encode_char (font, c) struct xftfont_info *xftfont_info = (struct xftfont_info *) font; unsigned code = XftCharIndex (xftfont_info->display, xftfont_info->xftfont, (FcChar32) c); - - return (code ? code : 0xFFFFFFFF); + + return (code ? code : FONT_INVALID_CODE); } static int @@ -483,6 +531,27 @@ xftfont_text_extents (font, code, nglyphs, metrics) return extents.xOff; } +static XftDraw * +xftfont_get_xft_draw (f) + FRAME_PTR f; +{ + XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver); + + if (! xft_draw) + { + BLOCK_INPUT; + xft_draw= XftDrawCreate (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + FRAME_X_VISUAL (f), + FRAME_X_COLORMAP (f)); + UNBLOCK_INPUT; + if (! xft_draw) + abort (); + font_put_frame_data (f, &xftfont_driver, xft_draw); + } + return xft_draw; +} + static int xftfont_draw (s, from, to, x, y, with_background) struct glyph_string *s; @@ -490,70 +559,69 @@ xftfont_draw (s, from, to, x, y, with_background) { FRAME_PTR f = s->f; struct face *face = s->face; - struct xftfont_info *xftfont_info = (struct xftfont_info *) face->font_info; - struct xftface_info *xftface_info = (struct xftface_info *) face->extra; + struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font; + struct xftface_info *xftface_info = NULL; + XftDraw *xft_draw = xftfont_get_xft_draw (f); FT_UInt *code; XftColor fg, bg; - XRectangle r; int len = to - from; int i; + if (s->font == face->font) + xftface_info = (struct xftface_info *) face->extra; xftfont_get_colors (f, face, s->gc, xftface_info, &fg, with_background ? &bg : NULL); BLOCK_INPUT; - if (s->clip_width) - { - r.x = s->clip_x, r.width = s->clip_width; - r.y = s->clip_y, r.height = s->clip_height; - XftDrawSetClipRectangles (xftface_info->xft_draw, 0, 0, &r, 1); - } - if (with_background) - { - struct font *font = (struct font *) face->font_info; + if (s->num_clips > 0) + XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips); + else + XftDrawSetClip (xft_draw, NULL); - XftDrawRect (xftface_info->xft_draw, &bg, - x, y - face->font->ascent, s->width, font->font.height); - } + if (with_background) + XftDrawRect (xft_draw, &bg, + x, y - face->font->ascent, s->width, face->font->height); code = alloca (sizeof (FT_UInt) * len); for (i = 0; i < len; i++) code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) | XCHAR2B_BYTE2 (s->char2b + from + i)); - XftDrawGlyphs (xftface_info->xft_draw, &fg, xftfont_info->xftfont, - x, y, code, len); - if (s->clip_width) - XftDrawSetClip (xftface_info->xft_draw, NULL); + if (s->padding_p) + for (i = 0; i < len; i++) + XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, + x + i, y, code + i, 1); + else + XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, + x, y, code, len); UNBLOCK_INPUT; return len; } static int -xftfont_anchor_point (font, code, index, x, y) - struct font *font; - unsigned code; - int index; - int *x, *y; +xftfont_end_for_frame (f) + FRAME_PTR f; { - struct xftfont_info *xftfont_info = (struct xftfont_info *) font; - FT_Face ft_face = xftfont_info->ft_face; + XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver); - if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0) - return -1; - if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) - return -1; - if (index >= ft_face->glyph->outline.n_points) - return -1; - *x = ft_face->glyph->outline.points[index].x; - *y = ft_face->glyph->outline.points[index].y; + if (xft_draw) + { + BLOCK_INPUT; + XftDrawDestroy (xft_draw); + UNBLOCK_INPUT; + font_put_frame_data (f, &xftfont_driver, NULL); + } return 0; } - void syms_of_xftfont () { DEFSYM (Qxft, "xft"); + DEFSYM (QChinting, ":hinting"); + DEFSYM (QCautohint, ":autohint"); + DEFSYM (QChintstyle, ":hintstyle"); + DEFSYM (QCrgba, ":rgba"); + DEFSYM (QCembolden, ":embolden"); xftfont_driver = ftfont_driver; xftfont_driver.type = Qxft; @@ -564,10 +632,11 @@ syms_of_xftfont () xftfont_driver.close = xftfont_close; xftfont_driver.prepare_face = xftfont_prepare_face; xftfont_driver.done_face = xftfont_done_face; + xftfont_driver.has_char = xftfont_has_char; xftfont_driver.encode_char = xftfont_encode_char; xftfont_driver.text_extents = xftfont_text_extents; xftfont_driver.draw = xftfont_draw; - xftfont_driver.anchor_point = xftfont_anchor_point; + xftfont_driver.end_for_frame = xftfont_end_for_frame; register_font_driver (&xftfont_driver, NULL); }