*** empty log message ***
[bpt/emacs.git] / src / xftfont.c
CommitLineData
c2f5bfd6
KH
1/* xftfont.c -- XFT font driver.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4613015e 3 Copyright (C) 2006, 2007
c2f5bfd6
KH
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
6
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
21the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22Boston, MA 02110-1301, USA. */
23
24#include <config.h>
25#include <stdio.h>
26#include <X11/Xlib.h>
27#include <X11/Xft/Xft.h>
28
29#include "lisp.h"
30#include "dispextern.h"
31#include "xterm.h"
32#include "frame.h"
33#include "blockinput.h"
34#include "character.h"
35#include "charset.h"
36#include "fontset.h"
37#include "font.h"
4613015e 38#include "ftfont.h"
c2f5bfd6
KH
39
40/* Xft font driver. */
41
42static Lisp_Object Qxft;
43
44/* The actual structure for Xft font that can be casted to struct
45 font. */
46
47struct xftfont_info
48{
49 struct font font;
50 Display *display;
51 int screen;
52 XftFont *xftfont;
4613015e
KH
53 FT_Face ft_face; /* Set to the value of XftLockFace (xftfont). */
54#ifdef HAVE_LIBOTF
55 int maybe_otf; /* Flag to tell if this may be OTF or not. */
56 OTF *otf;
794eba0f 57#endif /* HAVE_LIBOTF */
c2f5bfd6
KH
58};
59
60/* Structure pointed by (struct face *)->extra */
10aca0f7 61
c2f5bfd6
KH
62struct xftface_info
63{
10aca0f7
KH
64 XftColor xft_fg; /* color for face->foreground */
65 XftColor xft_bg; /* color for face->background */
c2f5bfd6
KH
66};
67
68static void xftfont_get_colors P_ ((FRAME_PTR, struct face *, GC gc,
69 struct xftface_info *,
70 XftColor *fg, XftColor *bg));
71static Font xftfont_default_fid P_ ((FRAME_PTR));
72
73
10aca0f7
KH
74/* Setup foreground and background colors of GC into FG and BG. If
75 XFTFACE_INFO is not NULL, reuse the colors in it if possible. BG
76 may be NULL. */
77
c2f5bfd6
KH
78static void
79xftfont_get_colors (f, face, gc, xftface_info, fg, bg)
80 FRAME_PTR f;
81 struct face *face;
82 GC gc;
83 struct xftface_info *xftface_info;
84 XftColor *fg, *bg;
85{
86 if (xftface_info && face->gc == gc)
87 {
88 *fg = xftface_info->xft_fg;
89 if (bg)
90 *bg = xftface_info->xft_bg;
91 }
92 else
93 {
94 XGCValues xgcv;
95 int fg_done = 0, bg_done = 0;
96
97 BLOCK_INPUT;
98 XGetGCValues (FRAME_X_DISPLAY (f), gc,
99 GCForeground | GCBackground, &xgcv);
100 if (xftface_info)
101 {
102 if (xgcv.foreground == face->foreground)
103 *fg = xftface_info->xft_fg, fg_done = 1;
104 else if (xgcv.foreground == face->background)
105 *fg = xftface_info->xft_bg, fg_done = 1;
106 if (! bg)
107 bg_done = 1;
108 else if (xgcv.background == face->background)
109 *bg = xftface_info->xft_bg, bg_done = 1;
110 else if (xgcv.background == face->foreground)
111 *bg = xftface_info->xft_fg, bg_done = 1;
112 }
113
114 if (fg_done + bg_done < 2)
115 {
116 XColor colors[2];
117
118 colors[0].pixel = fg->pixel = xgcv.foreground;
119 if (bg)
120 colors[1].pixel = bg->pixel = xgcv.background;
121 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors,
122 bg ? 2 : 1);
123 fg->color.alpha = 0xFFFF;
124 fg->color.red = colors[0].red;
125 fg->color.green = colors[0].green;
126 fg->color.blue = colors[0].blue;
127 if (bg)
128 {
129 bg->color.alpha = 0xFFFF;
130 bg->color.red = colors[1].red;
131 bg->color.green = colors[1].green;
132 bg->color.blue = colors[1].blue;
133 }
134 }
135 UNBLOCK_INPUT;
136 }
137}
138
10aca0f7
KH
139/* Return the default Font ID on frame F. The Returned Font ID is
140 stored in the GC of the frame F, but the font is never used. So,
141 any ID is ok as long as it is valid. */
c2f5bfd6
KH
142
143static Font
144xftfont_default_fid (f)
145 FRAME_PTR f;
146{
147 static int fid_known;
148 static Font fid;
149
150 if (! fid_known)
151 {
152 fid = XLoadFont (FRAME_X_DISPLAY (f), "fixed");
153 if (! fid)
154 {
155 fid = XLoadFont (FRAME_X_DISPLAY (f), "*");
156 if (! fid)
157 abort ();
158 }
322f8671 159 fid_known = 1;
c2f5bfd6
KH
160 }
161 return fid;
162}
163
164
165static Lisp_Object xftfont_list P_ ((Lisp_Object, Lisp_Object));
10aca0f7 166static Lisp_Object xftfont_match P_ ((Lisp_Object, Lisp_Object));
c2f5bfd6
KH
167static struct font *xftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
168static void xftfont_close P_ ((FRAME_PTR, struct font *));
169static int xftfont_prepare_face P_ ((FRAME_PTR, struct face *));
170static void xftfont_done_face P_ ((FRAME_PTR, struct face *));
171static unsigned xftfont_encode_char P_ ((struct font *, int));
172static int xftfont_text_extents P_ ((struct font *, unsigned *, int,
173 struct font_metrics *));
174static int xftfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
175
176static int xftfont_anchor_point P_ ((struct font *, unsigned, int,
177 int *, int *));
a92ee6bf
KH
178static int xftfont_start_for_frame P_ ((FRAME_PTR f));
179static int xftfont_end_for_frame P_ ((FRAME_PTR f));
c2f5bfd6
KH
180
181struct font_driver xftfont_driver;
182
183static Lisp_Object
184xftfont_list (frame, spec)
185 Lisp_Object frame;
186 Lisp_Object spec;
187{
188 Lisp_Object val = ftfont_driver.list (frame, spec);
10aca0f7 189 int i;
c2f5bfd6
KH
190
191 if (! NILP (val))
10aca0f7
KH
192 for (i = 0; i < ASIZE (val); i++)
193 ASET (AREF (val, i), FONT_TYPE_INDEX, Qxft);
c2f5bfd6
KH
194 return val;
195}
196
10aca0f7
KH
197static Lisp_Object
198xftfont_match (frame, spec)
199 Lisp_Object frame;
200 Lisp_Object spec;
201{
202 Lisp_Object entity = ftfont_driver.match (frame, spec);
203
204 if (VECTORP (entity))
205 ASET (entity, FONT_TYPE_INDEX, Qxft);
206 return entity;
207}
208
98d12656
KH
209extern Lisp_Object ftfont_font_format P_ ((FcPattern *));
210
c2f5bfd6
KH
211static FcChar8 ascii_printable[95];
212
213static struct font *
214xftfont_open (f, entity, pixel_size)
215 FRAME_PTR f;
216 Lisp_Object entity;
217 int pixel_size;
218{
219 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
220 Display *display = FRAME_X_DISPLAY (f);
221 Lisp_Object val;
2d93c6bd
KH
222 FcPattern *pattern, *pat = NULL;
223 FcChar8 *file;
224 struct xftfont_info *xftfont_info = NULL;
225 XFontStruct *xfont = NULL;
c2f5bfd6
KH
226 struct font *font;
227 double size = 0;
2d93c6bd 228 XftFont *xftfont = NULL;
c2f5bfd6 229 int spacing;
2d93c6bd 230 char *name;
dcce3c58 231 int len;
91c5bb27 232 XGlyphInfo extents;
c2f5bfd6
KH
233
234 val = AREF (entity, FONT_EXTRA_INDEX);
235 if (XTYPE (val) != Lisp_Misc
236 || XMISCTYPE (val) != Lisp_Misc_Save_Value)
237 return NULL;
238 pattern = XSAVE_VALUE (val)->pointer;
239 if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
240 return NULL;
241
242 size = XINT (AREF (entity, FONT_SIZE_INDEX));
243 if (size == 0)
244 size = pixel_size;
dcce3c58 245
c2f5bfd6
KH
246 pat = FcPatternCreate ();
247 FcPatternAddString (pat, FC_FILE, file);
248 FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
fa762662 249 /*FcPatternAddBool (pat, FC_ANTIALIAS, FcTrue);*/
3cc2aca0
KH
250 val = AREF (entity, FONT_FAMILY_INDEX);
251 if (! NILP (val))
252 FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
253 FcConfigSubstitute (NULL, pat, FcMatchPattern);
dcce3c58
KH
254
255 BLOCK_INPUT;
4f4426f9 256 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
c2f5bfd6
KH
257 xftfont = XftFontOpenPattern (display, pat);
258 /* We should not destroy PAT here because it is kept in XFTFONT and
259 destroyed automatically when XFTFONT is closed. */
260 if (! xftfont)
2d93c6bd 261 goto err;
c2f5bfd6
KH
262
263 xftfont_info = malloc (sizeof (struct xftfont_info));
264 if (! xftfont_info)
2d93c6bd 265 goto err;
c2f5bfd6 266 xfont = malloc (sizeof (XFontStruct));
2d93c6bd
KH
267 if (! xfont)
268 goto err;
c2f5bfd6
KH
269 xftfont_info->display = display;
270 xftfont_info->screen = FRAME_X_SCREEN_NUMBER (f);
271 xftfont_info->xftfont = xftfont;
272 xftfont_info->ft_face = XftLockFace (xftfont);
4613015e
KH
273#ifdef HAVE_LIBOTF
274 xftfont_info->maybe_otf = xftfont_info->ft_face->face_flags & FT_FACE_FLAG_SFNT;
275 xftfont_info->otf = NULL;
794eba0f 276#endif /* HAVE_LIBOTF */
c2f5bfd6
KH
277
278 font = (struct font *) xftfont_info;
b2e0f618 279 font->format = ftfont_font_format (xftfont->pattern);
c2f5bfd6
KH
280 font->entity = entity;
281 font->pixel_size = size;
282 font->driver = &xftfont_driver;
560fd3fa 283 len = 96;
2d93c6bd
KH
284 name = malloc (len);
285 while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0)
286 {
287 char *new = realloc (name, len += 32);
288
289 if (! new)
290 free (name);
291 name = new;
292 }
293 if (! name)
294 goto err;
295 font->font.full_name = font->font.name = name;
c2f5bfd6
KH
296 font->file_name = (char *) file;
297 font->font.size = xftfont->max_advance_width;
8bf90572 298 font->font.charset = font->encoding_charset = font->repertory_charset = -1;
c2f5bfd6
KH
299
300 if (FcPatternGetInteger (xftfont->pattern, FC_SPACING, 0, &spacing)
301 != FcResultMatch)
302 spacing = FC_PROPORTIONAL;
91c5bb27
KH
303 if (! ascii_printable[0])
304 {
305 int i;
306 for (i = 0; i < 95; i++)
307 ascii_printable[i] = ' ' + i;
308 }
c2f5bfd6 309 if (spacing != FC_PROPORTIONAL)
91c5bb27
KH
310 {
311 font->font.average_width = font->font.space_width
312 = xftfont->max_advance_width;
313 XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
314 }
c2f5bfd6
KH
315 else
316 {
c2f5bfd6
KH
317 XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents);
318 font->font.space_width = extents.xOff;
319 if (font->font.space_width <= 0)
320 /* dirty workaround */
321 font->font.space_width = pixel_size;
322 XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
323 font->font.average_width = (font->font.space_width + extents.xOff) / 95;
324 }
dcce3c58 325 UNBLOCK_INPUT;
c2f5bfd6 326
91c5bb27
KH
327 font->ascent = xftfont->ascent;
328 if (font->ascent < extents.y)
329 font->ascent = extents.y;
330 font->descent = xftfont->descent;
331 if (font->descent < extents.height - extents.y)
332 font->descent = extents.height - extents.y;
333 font->font.height = font->ascent + font->descent;
334
c2f5bfd6
KH
335 /* Unfortunately Xft doesn't provide a way to get minimum char
336 width. So, we use space_width instead. */
337 font->min_width = font->font.space_width;
338
339 font->font.baseline_offset = 0;
340 font->font.relative_compose = 0;
341 font->font.default_ascent = 0;
342 font->font.vertical_centering = 0;
343
344 /* Setup pseudo XFontStruct */
345 xfont->fid = xftfont_default_fid (f);
91c5bb27
KH
346 xfont->ascent = font->ascent;
347 xfont->descent = font->descent;
348 xfont->max_bounds.descent = font->descent;
c2f5bfd6
KH
349 xfont->max_bounds.width = xftfont->max_advance_width;
350 xfont->min_bounds.width = font->font.space_width;
351 font->font.font = xfont;
352
353 dpyinfo->n_fonts++;
354
355 /* Set global flag fonts_changed_p to non-zero if the font loaded
356 has a character with a smaller width than any other character
357 before, or if the font loaded has a smaller height than any other
358 font loaded before. If this happens, it will make a glyph matrix
359 reallocation necessary. */
360 if (dpyinfo->n_fonts == 1)
361 {
362 dpyinfo->smallest_font_height = font->font.height;
363 dpyinfo->smallest_char_width = font->min_width;
364 fonts_changed_p = 1;
365 }
366 else
367 {
368 if (dpyinfo->smallest_font_height > font->font.height)
369 dpyinfo->smallest_font_height = font->font.height,
370 fonts_changed_p |= 1;
371 if (dpyinfo->smallest_char_width > font->min_width)
372 dpyinfo->smallest_char_width = font->min_width,
373 fonts_changed_p |= 1;
374 }
375
376 return font;
2d93c6bd
KH
377
378 err:
379 if (xftfont) XftFontClose (display, xftfont);
380 UNBLOCK_INPUT;
381 if (xftfont_info) free (xftfont_info);
382 if (xfont) free (xfont);
383 return NULL;
c2f5bfd6
KH
384}
385
386static void
387xftfont_close (f, font)
388 FRAME_PTR f;
389 struct font *font;
390{
391 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
392
4613015e
KH
393#ifdef HAVE_LIBOTF
394 if (xftfont_info->otf)
395 OTF_close (xftfont_info->otf);
396#endif
c2f5bfd6
KH
397 XftUnlockFace (xftfont_info->xftfont);
398 XftFontClose (xftfont_info->display, xftfont_info->xftfont);
dcce3c58
KH
399 if (font->font.name)
400 free (font->font.name);
c2f5bfd6
KH
401 free (font);
402 FRAME_X_DISPLAY_INFO (f)->n_fonts--;
403}
404
c2f5bfd6
KH
405static int
406xftfont_prepare_face (f, face)
407 FRAME_PTR f;
408 struct face *face;
409{
e2d0c925 410 struct xftface_info *xftface_info;
c2f5bfd6 411
a703d27d
KH
412#if 0
413 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
e2d0c925
KH
414 if (face != face->ascii_face)
415 {
416 face->extra = face->ascii_face->extra;
417 return 0;
418 }
a703d27d 419#endif
e2d0c925
KH
420
421 xftface_info = malloc (sizeof (struct xftface_info));
c2f5bfd6
KH
422 if (! xftface_info)
423 return -1;
424
425 BLOCK_INPUT;
c2f5bfd6
KH
426 xftfont_get_colors (f, face, face->gc, NULL,
427 &xftface_info->xft_fg, &xftface_info->xft_bg);
428 UNBLOCK_INPUT;
429
430 face->extra = xftface_info;
431 return 0;
432}
433
434static void
435xftfont_done_face (f, face)
436 FRAME_PTR f;
437 struct face *face;
438{
e2d0c925
KH
439 struct xftface_info *xftface_info;
440
a703d27d
KH
441#if 0
442 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
e2d0c925
KH
443 if (face != face->ascii_face
444 || ! face->extra)
445 return;
a703d27d 446#endif
c2f5bfd6 447
e2d0c925 448 xftface_info = (struct xftface_info *) face->extra;
773039e8
JD
449 if (xftface_info)
450 {
773039e8 451 free (xftface_info);
a92ee6bf 452 face->extra = NULL;
773039e8 453 }
c2f5bfd6
KH
454}
455
456static unsigned
457xftfont_encode_char (font, c)
458 struct font *font;
459 int c;
460{
461 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
462 unsigned code = XftCharIndex (xftfont_info->display, xftfont_info->xftfont,
463 (FcChar32) c);
464
465 return (code ? code : 0xFFFFFFFF);
466}
467
468static int
469xftfont_text_extents (font, code, nglyphs, metrics)
470 struct font *font;
471 unsigned *code;
472 int nglyphs;
473 struct font_metrics *metrics;
474{
475 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
476 XGlyphInfo extents;
477
478 BLOCK_INPUT;
479 XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
480 &extents);
481 UNBLOCK_INPUT;
482 if (metrics)
483 {
484 metrics->lbearing = - extents.x;
485 metrics->rbearing = - extents.x + extents.width;
486 metrics->width = extents.xOff;
487 metrics->ascent = extents.y;
4b848612 488 metrics->descent = extents.height - extents.y;
c2f5bfd6
KH
489 }
490 return extents.xOff;
491}
492
a92ee6bf
KH
493static XftDraw *
494xftfont_get_xft_draw (f)
495 FRAME_PTR f;
496{
497 XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);;
498
499 if (! xft_draw)
500 {
501 BLOCK_INPUT;
502 xft_draw= XftDrawCreate (FRAME_X_DISPLAY (f),
503 FRAME_X_WINDOW (f),
504 FRAME_X_VISUAL (f),
505 FRAME_X_COLORMAP (f));
506 UNBLOCK_INPUT;
507 if (! xft_draw)
508 abort ();
509 font_put_frame_data (f, &xftfont_driver, xft_draw);
510 }
511 return xft_draw;
512}
513
c2f5bfd6
KH
514static int
515xftfont_draw (s, from, to, x, y, with_background)
516 struct glyph_string *s;
517 int from, to, x, y, with_background;
518{
519 FRAME_PTR f = s->f;
520 struct face *face = s->face;
c78c1659
KH
521 struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font_info;
522 struct xftface_info *xftface_info = NULL;
a92ee6bf 523 XftDraw *xft_draw = xftfont_get_xft_draw (f);
c2f5bfd6
KH
524 FT_UInt *code;
525 XftColor fg, bg;
526 XRectangle r;
527 int len = to - from;
528 int i;
529
c78c1659 530 if (s->font_info == face->font_info)
a92ee6bf 531 xftface_info = (struct xftface_info *) face->extra;
c2f5bfd6 532 xftfont_get_colors (f, face, s->gc, xftface_info,
322f8671 533 &fg, with_background ? &bg : NULL);
c2f5bfd6 534 BLOCK_INPUT;
03d198e8
KH
535 if (s->num_clips > 0)
536 XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips);
537 else
538 XftDrawSetClip (xft_draw, NULL);
539
c2f5bfd6
KH
540 if (with_background)
541 {
542 struct font *font = (struct font *) face->font_info;
543
c78c1659 544 XftDrawRect (xft_draw, &bg,
c2f5bfd6
KH
545 x, y - face->font->ascent, s->width, font->font.height);
546 }
547 code = alloca (sizeof (FT_UInt) * len);
548 for (i = 0; i < len; i++)
549 code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
550 | XCHAR2B_BYTE2 (s->char2b + from + i));
551
c78c1659 552 XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
c2f5bfd6 553 x, y, code, len);
c2f5bfd6
KH
554 UNBLOCK_INPUT;
555
556 return len;
557}
558
559static int
560xftfont_anchor_point (font, code, index, x, y)
561 struct font *font;
562 unsigned code;
563 int index;
564 int *x, *y;
565{
566 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
567 FT_Face ft_face = xftfont_info->ft_face;
568
569 if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0)
570 return -1;
571 if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
572 return -1;
573 if (index >= ft_face->glyph->outline.n_points)
574 return -1;
575 *x = ft_face->glyph->outline.points[index].x;
576 *y = ft_face->glyph->outline.points[index].y;
577 return 0;
578}
579
a92ee6bf
KH
580static int
581xftfont_end_for_frame (f)
582 FRAME_PTR f;
583{
584 XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);
585
586 if (xft_draw)
587 {
588 BLOCK_INPUT;
589 XftDrawDestroy (xft_draw);
590 UNBLOCK_INPUT;
591 font_put_frame_data (f, &xftfont_driver, NULL);
592 }
593 return 0;
594}
c2f5bfd6 595
4613015e
KH
596#ifdef HAVE_LIBOTF
597#ifdef HAVE_M17N_FLT
598static Lisp_Object
599xftfont_shape (lgstring)
600 Lisp_Object lgstring;
601{
602 struct font *font;
603 struct xftfont_info *xftfont_info;
604
605 CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font);
606 xftfont_info = (struct xftfont_info *) font;
607 if (! xftfont_info->maybe_otf)
608 return Qnil;
609 if (! xftfont_info->otf)
610 {
611 OTF *otf = OTF_open_ft_face (xftfont_info->ft_face);
612
613 if (! otf || OTF_get_table (otf, "head") < 0)
614 {
615 if (otf)
616 OTF_close (otf);
617 xftfont_info->maybe_otf = 0;
618 return 0;
619 }
620 xftfont_info->otf = otf;
621 }
622
623 return ftfont_shape_by_flt (lgstring, font, xftfont_info->ft_face,
624 xftfont_info->otf);
625}
626#endif /* HAVE_M17N_FLT */
627#endif /* HAVE_LIBOTF */
628
c2f5bfd6
KH
629void
630syms_of_xftfont ()
631{
632 DEFSYM (Qxft, "xft");
633
634 xftfont_driver = ftfont_driver;
635 xftfont_driver.type = Qxft;
636 xftfont_driver.get_cache = xfont_driver.get_cache;
637 xftfont_driver.list = xftfont_list;
10aca0f7 638 xftfont_driver.match = xftfont_match;
c2f5bfd6
KH
639 xftfont_driver.open = xftfont_open;
640 xftfont_driver.close = xftfont_close;
641 xftfont_driver.prepare_face = xftfont_prepare_face;
642 xftfont_driver.done_face = xftfont_done_face;
643 xftfont_driver.encode_char = xftfont_encode_char;
644 xftfont_driver.text_extents = xftfont_text_extents;
645 xftfont_driver.draw = xftfont_draw;
646 xftfont_driver.anchor_point = xftfont_anchor_point;
a92ee6bf 647 xftfont_driver.end_for_frame = xftfont_end_for_frame;
4613015e
KH
648#ifdef HAVE_LIBOTF
649#ifdef HAVE_M17N_FLT
650 xftfont_driver.shape = xftfont_shape;
651#endif /* HAVE_M17N_FLT */
652#endif /* HAVE_LIBOTF */
c2f5bfd6
KH
653
654 register_font_driver (&xftfont_driver, NULL);
655}
885b7d09
MB
656
657/* arch-tag: 64ec61bf-7c8e-4fe6-b953-c6a85d5e1605
658 (do not change this comment) */