1 /* xftfont.c -- XFT font driver.
2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 #include <X11/Xft/Xft.h>
28 #include "dispextern.h"
31 #include "blockinput.h"
32 #include "character.h"
34 #include "composite.h"
39 /* Xft font driver. */
42 static Lisp_Object QChinting
, QCautohint
, QChintstyle
, QCrgba
, QCembolden
,
45 /* The actual structure for Xft font that can be cast to struct
51 /* The following five members must be here in this order to be
52 compatible with struct ftfont_info (in ftfont.c). */
54 bool maybe_otf
; /* Flag to tell if this may be OTF or not. */
56 #endif /* HAVE_LIBOTF */
62 unsigned x_display_id
;
65 /* Structure pointed by (struct face *)->extra */
69 XftColor xft_fg
; /* color for face->foreground */
70 XftColor xft_bg
; /* color for face->background */
73 /* Setup foreground and background colors of GC into FG and BG. If
74 XFTFACE_INFO is not NULL, reuse the colors in it if possible. BG
78 xftfont_get_colors (struct frame
*f
, struct face
*face
, GC gc
,
79 struct xftface_info
*xftface_info
,
80 XftColor
*fg
, XftColor
*bg
)
82 if (xftface_info
&& face
->gc
== gc
)
84 *fg
= xftface_info
->xft_fg
;
86 *bg
= xftface_info
->xft_bg
;
91 bool fg_done
= 0, bg_done
= 0;
94 XGetGCValues (FRAME_X_DISPLAY (f
), gc
,
95 GCForeground
| GCBackground
, &xgcv
);
98 if (xgcv
.foreground
== face
->foreground
)
99 *fg
= xftface_info
->xft_fg
, fg_done
= 1;
100 else if (xgcv
.foreground
== face
->background
)
101 *fg
= xftface_info
->xft_bg
, fg_done
= 1;
104 else if (xgcv
.background
== face
->background
)
105 *bg
= xftface_info
->xft_bg
, bg_done
= 1;
106 else if (xgcv
.background
== face
->foreground
)
107 *bg
= xftface_info
->xft_fg
, bg_done
= 1;
110 if (! (fg_done
& bg_done
))
114 colors
[0].pixel
= fg
->pixel
= xgcv
.foreground
;
116 colors
[1].pixel
= bg
->pixel
= xgcv
.background
;
117 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
,
119 fg
->color
.alpha
= 0xFFFF;
120 fg
->color
.red
= colors
[0].red
;
121 fg
->color
.green
= colors
[0].green
;
122 fg
->color
.blue
= colors
[0].blue
;
125 bg
->color
.alpha
= 0xFFFF;
126 bg
->color
.red
= colors
[1].red
;
127 bg
->color
.green
= colors
[1].green
;
128 bg
->color
.blue
= colors
[1].blue
;
136 struct font_driver xftfont_driver
;
139 xftfont_list (struct frame
*f
, Lisp_Object spec
)
141 Lisp_Object list
= ftfont_driver
.list (f
, spec
), tail
;
143 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
144 ASET (XCAR (tail
), FONT_TYPE_INDEX
, Qxft
);
149 xftfont_match (struct frame
*f
, Lisp_Object spec
)
151 Lisp_Object entity
= ftfont_driver
.match (f
, spec
);
154 ASET (entity
, FONT_TYPE_INDEX
, Qxft
);
158 static FcChar8 ascii_printable
[95];
161 xftfont_fix_match (FcPattern
*pat
, FcPattern
*match
)
163 /* These values are not used for matching (except antialias), but for
164 rendering, so make sure they are carried over to the match.
165 We also put antialias here because most fonts are antialiased, so
166 the match will have antialias true. */
172 FcPatternGetBool (pat
, FC_ANTIALIAS
, 0, &b
);
175 FcPatternDel (match
, FC_ANTIALIAS
);
176 FcPatternAddBool (match
, FC_ANTIALIAS
, FcFalse
);
178 FcPatternGetBool (pat
, FC_HINTING
, 0, &b
);
181 FcPatternDel (match
, FC_HINTING
);
182 FcPatternAddBool (match
, FC_HINTING
, FcFalse
);
184 #ifndef FC_HINT_STYLE
185 # define FC_HINT_STYLE "hintstyle"
187 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_HINT_STYLE
, 0, &i
))
189 FcPatternDel (match
, FC_HINT_STYLE
);
190 FcPatternAddInteger (match
, FC_HINT_STYLE
, i
);
192 #ifndef FC_LCD_FILTER
193 /* Older fontconfig versions don't have FC_LCD_FILTER. */
194 #define FC_LCD_FILTER "lcdfilter"
196 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_LCD_FILTER
, 0, &i
))
198 FcPatternDel (match
, FC_LCD_FILTER
);
199 FcPatternAddInteger (match
, FC_LCD_FILTER
, i
);
201 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_RGBA
, 0, &i
))
203 FcPatternDel (match
, FC_RGBA
);
204 FcPatternAddInteger (match
, FC_RGBA
, i
);
206 if (FcResultMatch
== FcPatternGetDouble (pat
, FC_DPI
, 0, &dpi
))
208 FcPatternDel (match
, FC_DPI
);
209 FcPatternAddDouble (match
, FC_DPI
, dpi
);
214 xftfont_add_rendering_parameters (FcPattern
*pat
, Lisp_Object entity
)
219 for (tail
= AREF (entity
, FONT_EXTRA_INDEX
); CONSP (tail
); tail
= XCDR (tail
))
221 Lisp_Object key
= XCAR (XCAR (tail
));
222 Lisp_Object val
= XCDR (XCAR (tail
));
224 if (EQ (key
, QCantialias
))
225 FcPatternAddBool (pat
, FC_ANTIALIAS
, NILP (val
) ? FcFalse
: FcTrue
);
226 else if (EQ (key
, QChinting
))
227 FcPatternAddBool (pat
, FC_HINTING
, NILP (val
) ? FcFalse
: FcTrue
);
228 else if (EQ (key
, QCautohint
))
229 FcPatternAddBool (pat
, FC_AUTOHINT
, NILP (val
) ? FcFalse
: FcTrue
);
230 else if (EQ (key
, QChintstyle
))
233 FcPatternAddInteger (pat
, FC_HINT_STYLE
, XINT (val
));
234 else if (SYMBOLP (val
)
235 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
236 FcPatternAddInteger (pat
, FC_HINT_STYLE
, ival
);
238 else if (EQ (key
, QCrgba
))
241 FcPatternAddInteger (pat
, FC_RGBA
, XINT (val
));
242 else if (SYMBOLP (val
)
243 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
244 FcPatternAddInteger (pat
, FC_RGBA
, ival
);
246 else if (EQ (key
, QClcdfilter
))
249 FcPatternAddInteger (pat
, FC_LCD_FILTER
, ival
= XINT (val
));
250 else if (SYMBOLP (val
)
251 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
252 FcPatternAddInteger (pat
, FC_LCD_FILTER
, ival
);
255 else if (EQ (key
, QCembolden
))
256 FcPatternAddBool (pat
, FC_EMBOLDEN
, NILP (val
) ? FcFalse
: FcTrue
);
262 xftfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
265 Display
*display
= FRAME_X_DISPLAY (f
);
266 Lisp_Object val
, filename
, idx
, font_object
;
267 FcPattern
*pat
= NULL
, *match
;
268 struct xftfont_info
*xftfont_info
= NULL
;
271 XftFont
*xftfont
= NULL
;
279 val
= assq_no_quit (QCfont_entity
, AREF (entity
, FONT_EXTRA_INDEX
));
283 filename
= XCAR (val
);
285 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
288 pat
= FcPatternCreate ();
289 FcPatternAddInteger (pat
, FC_WEIGHT
, FONT_WEIGHT_NUMERIC (entity
));
290 i
= FONT_SLANT_NUMERIC (entity
) - 100;
292 FcPatternAddInteger (pat
, FC_SLANT
, i
);
293 FcPatternAddInteger (pat
, FC_WIDTH
, FONT_WIDTH_NUMERIC (entity
));
294 FcPatternAddDouble (pat
, FC_PIXEL_SIZE
, pixel_size
);
295 val
= AREF (entity
, FONT_FAMILY_INDEX
);
297 FcPatternAddString (pat
, FC_FAMILY
, (FcChar8
*) SDATA (SYMBOL_NAME (val
)));
298 val
= AREF (entity
, FONT_FOUNDRY_INDEX
);
300 FcPatternAddString (pat
, FC_FOUNDRY
, (FcChar8
*) SDATA (SYMBOL_NAME (val
)));
301 val
= AREF (entity
, FONT_SPACING_INDEX
);
303 FcPatternAddInteger (pat
, FC_SPACING
, XINT (val
));
304 val
= AREF (entity
, FONT_DPI_INDEX
);
307 double dbl
= XINT (val
);
309 FcPatternAddDouble (pat
, FC_DPI
, dbl
);
311 val
= AREF (entity
, FONT_AVGWIDTH_INDEX
);
312 if (INTEGERP (val
) && XINT (val
) == 0)
313 FcPatternAddBool (pat
, FC_SCALABLE
, FcTrue
);
314 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
315 over 10x20-ISO8859-1.pcf.gz). */
316 FcPatternAddCharSet (pat
, FC_CHARSET
, ftfont_get_fc_charset (entity
));
318 xftfont_add_rendering_parameters (pat
, entity
);
320 FcPatternAddString (pat
, FC_FILE
, (FcChar8
*) SDATA (filename
));
321 FcPatternAddInteger (pat
, FC_INDEX
, XINT (idx
));
326 /* Substitute in values from X resources and XftDefaultSet. */
327 XftDefaultSubstitute (display
, FRAME_X_SCREEN_NUMBER (f
), pat
);
328 match
= XftFontMatch (display
, FRAME_X_SCREEN_NUMBER (f
), pat
, &result
);
329 xftfont_fix_match (pat
, match
);
331 FcPatternDestroy (pat
);
332 xftfont
= XftFontOpenPattern (display
, match
);
336 XftPatternDestroy (match
);
339 ft_face
= XftLockFace (xftfont
);
342 /* We should not destroy PAT here because it is kept in XFTFONT and
343 destroyed automatically when XFTFONT is closed. */
344 font_object
= font_make_object (VECSIZE (struct xftfont_info
), entity
, size
);
345 ASET (font_object
, FONT_TYPE_INDEX
, Qxft
);
346 len
= font_unparse_xlfd (entity
, size
, name
, 256);
348 ASET (font_object
, FONT_NAME_INDEX
, make_string (name
, len
));
349 len
= font_unparse_fcname (entity
, size
, name
, 256);
351 ASET (font_object
, FONT_FULLNAME_INDEX
, make_string (name
, len
));
353 ASET (font_object
, FONT_FULLNAME_INDEX
,
354 AREF (font_object
, FONT_NAME_INDEX
));
355 ASET (font_object
, FONT_FILE_INDEX
, filename
);
356 ASET (font_object
, FONT_FORMAT_INDEX
,
357 ftfont_font_format (xftfont
->pattern
, filename
));
358 font
= XFONT_OBJECT (font_object
);
359 font
->pixel_size
= size
;
360 font
->driver
= &xftfont_driver
;
361 font
->encoding_charset
= font
->repertory_charset
= -1;
363 xftfont_info
= (struct xftfont_info
*) font
;
364 xftfont_info
->display
= display
;
365 xftfont_info
->xftfont
= xftfont
;
366 xftfont_info
->x_display_id
= FRAME_DISPLAY_INFO (f
)->x_id
;
367 /* This means that there's no need of transformation. */
368 xftfont_info
->matrix
.xx
= 0;
369 if (FcPatternGetMatrix (xftfont
->pattern
, FC_MATRIX
, 0, &matrix
)
372 xftfont_info
->matrix
.xx
= 0x10000L
* matrix
->xx
;
373 xftfont_info
->matrix
.yy
= 0x10000L
* matrix
->yy
;
374 xftfont_info
->matrix
.xy
= 0x10000L
* matrix
->xy
;
375 xftfont_info
->matrix
.yx
= 0x10000L
* matrix
->yx
;
377 if (INTEGERP (AREF (entity
, FONT_SPACING_INDEX
)))
378 spacing
= XINT (AREF (entity
, FONT_SPACING_INDEX
));
380 spacing
= FC_PROPORTIONAL
;
381 if (! ascii_printable
[0])
384 for (ch
= 0; ch
< 95; ch
++)
385 ascii_printable
[ch
] = ' ' + ch
;
389 /* Unfortunately Xft doesn't provide a way to get minimum char
390 width. So, we set min_width to space_width. */
392 if (spacing
!= FC_PROPORTIONAL
394 && spacing
!= FC_DUAL
398 font
->min_width
= font
->max_width
= font
->average_width
399 = font
->space_width
= xftfont
->max_advance_width
;
400 XftTextExtents8 (display
, xftfont
, ascii_printable
+ 1, 94, &extents
);
404 XftTextExtents8 (display
, xftfont
, ascii_printable
, 1, &extents
);
405 font
->min_width
= font
->max_width
= font
->space_width
407 if (font
->space_width
<= 0)
408 /* dirty workaround */
409 font
->space_width
= pixel_size
;
410 XftTextExtents8 (display
, xftfont
, ascii_printable
+ 1, 94, &extents
);
411 font
->average_width
= (font
->space_width
+ extents
.xOff
) / 95;
415 font
->ascent
= xftfont
->ascent
;
416 font
->descent
= xftfont
->descent
;
419 /* The above condition is a dirty workaround because
420 XftTextExtents8 behaves strangely for some fonts
421 (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */
422 if (font
->ascent
< extents
.y
)
423 font
->ascent
= extents
.y
;
424 if (font
->descent
< extents
.height
- extents
.y
)
425 font
->descent
= extents
.height
- extents
.y
;
427 font
->height
= font
->ascent
+ font
->descent
;
429 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) == 0)
431 int upEM
= ft_face
->units_per_EM
;
433 font
->underline_position
= -ft_face
->underline_position
* size
/ upEM
;
434 font
->underline_thickness
= ft_face
->underline_thickness
* size
/ upEM
;
435 if (font
->underline_thickness
> 2)
436 font
->underline_position
-= font
->underline_thickness
/ 2;
440 font
->underline_position
= -1;
441 font
->underline_thickness
= 0;
444 xftfont_info
->maybe_otf
= (ft_face
->face_flags
& FT_FACE_FLAG_SFNT
) != 0;
445 xftfont_info
->otf
= NULL
;
446 #endif /* HAVE_LIBOTF */
447 xftfont_info
->ft_size
= ft_face
->size
;
449 font
->baseline_offset
= 0;
450 font
->relative_compose
= 0;
451 font
->default_ascent
= 0;
452 font
->vertical_centering
= 0;
454 if (! (ft_face
->face_flags
& FT_FACE_FLAG_SFNT
))
458 if (FT_Get_BDF_Property (ft_face
, "_MULE_BASELINE_OFFSET", &rec
) == 0
459 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
460 font
->baseline_offset
= rec
.u
.integer
;
461 if (FT_Get_BDF_Property (ft_face
, "_MULE_RELATIVE_COMPOSE", &rec
) == 0
462 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
463 font
->relative_compose
= rec
.u
.integer
;
464 if (FT_Get_BDF_Property (ft_face
, "_MULE_DEFAULT_ASCENT", &rec
) == 0
465 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
466 font
->default_ascent
= rec
.u
.integer
;
474 xftfont_close (struct font
*font
)
476 struct x_display_info
*xdi
;
477 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
480 if (xftfont_info
->otf
)
482 OTF_close (xftfont_info
->otf
);
483 xftfont_info
->otf
= NULL
;
487 /* See comment in xfont_close. */
488 if (xftfont_info
->xftfont
489 && ((xdi
= x_display_info_for_display (xftfont_info
->display
))
490 && xftfont_info
->x_display_id
== xdi
->x_id
))
493 XftUnlockFace (xftfont_info
->xftfont
);
494 XftFontClose (xftfont_info
->display
, xftfont_info
->xftfont
);
496 xftfont_info
->xftfont
= NULL
;
501 xftfont_prepare_face (struct frame
*f
, struct face
*face
)
503 struct xftface_info
*xftface_info
;
506 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
507 if (face
!= face
->ascii_face
)
509 face
->extra
= face
->ascii_face
->extra
;
514 xftface_info
= xmalloc (sizeof *xftface_info
);
515 xftfont_get_colors (f
, face
, face
->gc
, NULL
,
516 &xftface_info
->xft_fg
, &xftface_info
->xft_bg
);
517 face
->extra
= xftface_info
;
521 xftfont_done_face (struct frame
*f
, struct face
*face
)
523 struct xftface_info
*xftface_info
;
526 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
527 if (face
!= face
->ascii_face
532 xftface_info
= (struct xftface_info
*) face
->extra
;
535 xfree (xftface_info
);
541 xftfont_has_char (Lisp_Object font
, int c
)
543 struct xftfont_info
*xftfont_info
;
544 struct charset
*cs
= NULL
;
546 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
547 && charset_jisx0208
>= 0)
548 cs
= CHARSET_FROM_ID (charset_jisx0208
);
549 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
550 && charset_ksc5601
>= 0)
551 cs
= CHARSET_FROM_ID (charset_ksc5601
);
553 return (ENCODE_CHAR (cs
, c
) != CHARSET_INVALID_CODE (cs
));
555 if (FONT_ENTITY_P (font
))
556 return ftfont_driver
.has_char (font
, c
);
557 xftfont_info
= (struct xftfont_info
*) XFONT_OBJECT (font
);
558 return (XftCharExists (xftfont_info
->display
, xftfont_info
->xftfont
,
559 (FcChar32
) c
) == FcTrue
);
563 xftfont_encode_char (struct font
*font
, int c
)
565 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
566 unsigned code
= XftCharIndex (xftfont_info
->display
, xftfont_info
->xftfont
,
569 return (code
? code
: FONT_INVALID_CODE
);
573 xftfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
575 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
579 XftGlyphExtents (xftfont_info
->display
, xftfont_info
->xftfont
, code
, nglyphs
,
584 metrics
->lbearing
= - extents
.x
;
585 metrics
->rbearing
= - extents
.x
+ extents
.width
;
586 metrics
->width
= extents
.xOff
;
587 metrics
->ascent
= extents
.y
;
588 metrics
->descent
= extents
.height
- extents
.y
;
594 xftfont_get_xft_draw (struct frame
*f
)
596 XftDraw
*xft_draw
= font_get_frame_data (f
, &xftfont_driver
);
601 xft_draw
= XftDrawCreate (FRAME_X_DISPLAY (f
),
604 FRAME_X_COLORMAP (f
));
606 eassert (xft_draw
!= NULL
);
607 font_put_frame_data (f
, &xftfont_driver
, xft_draw
);
613 xftfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
614 bool with_background
)
616 struct frame
*f
= s
->f
;
617 struct face
*face
= s
->face
;
618 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) s
->font
;
619 struct xftface_info
*xftface_info
= NULL
;
620 XftDraw
*xft_draw
= xftfont_get_xft_draw (f
);
626 if (s
->font
== face
->font
)
627 xftface_info
= (struct xftface_info
*) face
->extra
;
628 xftfont_get_colors (f
, face
, s
->gc
, xftface_info
,
629 &fg
, with_background
? &bg
: NULL
);
631 if (s
->num_clips
> 0)
632 XftDrawSetClipRectangles (xft_draw
, 0, 0, s
->clip
, s
->num_clips
);
634 XftDrawSetClip (xft_draw
, NULL
);
637 XftDrawRect (xft_draw
, &bg
,
638 x
, y
- s
->font
->ascent
, s
->width
, s
->font
->height
);
639 code
= alloca (sizeof (FT_UInt
) * len
);
640 for (i
= 0; i
< len
; i
++)
641 code
[i
] = ((XCHAR2B_BYTE1 (s
->char2b
+ from
+ i
) << 8)
642 | XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
));
645 for (i
= 0; i
< len
; i
++)
646 XftDrawGlyphs (xft_draw
, &fg
, xftfont_info
->xftfont
,
647 x
+ i
, y
, code
+ i
, 1);
649 XftDrawGlyphs (xft_draw
, &fg
, xftfont_info
->xftfont
,
656 #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
658 xftfont_shape (Lisp_Object lgstring
)
661 struct xftfont_info
*xftfont_info
;
665 CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring
), font
);
666 xftfont_info
= (struct xftfont_info
*) font
;
667 ft_face
= XftLockFace (xftfont_info
->xftfont
);
668 xftfont_info
->ft_size
= ft_face
->size
;
669 val
= ftfont_driver
.shape (lgstring
);
670 XftUnlockFace (xftfont_info
->xftfont
);
676 xftfont_end_for_frame (struct frame
*f
)
680 /* Don't do anything if display is dead */
681 if (FRAME_X_DISPLAY (f
) == NULL
) return 0;
683 xft_draw
= font_get_frame_data (f
, &xftfont_driver
);
688 XftDrawDestroy (xft_draw
);
690 font_put_frame_data (f
, &xftfont_driver
, NULL
);
696 xftfont_cached_font_ok (struct frame
*f
, Lisp_Object font_object
,
699 struct xftfont_info
*info
= (struct xftfont_info
*) XFONT_OBJECT (font_object
);
700 FcPattern
*oldpat
= info
->xftfont
->pattern
;
701 Display
*display
= FRAME_X_DISPLAY (f
);
702 FcPattern
*pat
= FcPatternCreate ();
707 xftfont_add_rendering_parameters (pat
, entity
);
708 XftDefaultSubstitute (display
, FRAME_X_SCREEN_NUMBER (f
), pat
);
710 r1
= FcPatternGetBool (pat
, FC_ANTIALIAS
, 0, &b1
);
711 r2
= FcPatternGetBool (oldpat
, FC_ANTIALIAS
, 0, &b2
);
712 if (r1
!= r2
|| b1
!= b2
) goto out
;
713 r1
= FcPatternGetBool (pat
, FC_HINTING
, 0, &b1
);
714 r2
= FcPatternGetBool (oldpat
, FC_HINTING
, 0, &b2
);
715 if (r1
!= r2
|| b1
!= b2
) goto out
;
716 r1
= FcPatternGetBool (pat
, FC_AUTOHINT
, 0, &b1
);
717 r2
= FcPatternGetBool (oldpat
, FC_AUTOHINT
, 0, &b2
);
718 if (r1
!= r2
|| b1
!= b2
) goto out
;
720 r1
= FcPatternGetBool (pat
, FC_EMBOLDEN
, 0, &b1
);
721 r2
= FcPatternGetBool (oldpat
, FC_EMBOLDEN
, 0, &b2
);
722 if (r1
!= r2
|| b1
!= b2
) goto out
;
724 r1
= FcPatternGetInteger (pat
, FC_HINT_STYLE
, 0, &i1
);
725 r2
= FcPatternGetInteger (oldpat
, FC_HINT_STYLE
, 0, &i2
);
726 if (r1
!= r2
|| i1
!= i2
) goto out
;
727 r1
= FcPatternGetInteger (pat
, FC_LCD_FILTER
, 0, &i1
);
728 r2
= FcPatternGetInteger (oldpat
, FC_LCD_FILTER
, 0, &i2
);
729 if (r1
!= r2
|| i1
!= i2
) goto out
;
730 r1
= FcPatternGetInteger (pat
, FC_RGBA
, 0, &i1
);
731 r2
= FcPatternGetInteger (oldpat
, FC_RGBA
, 0, &i2
);
732 if (r1
!= r2
|| i1
!= i2
) goto out
;
736 FcPatternDestroy (pat
);
741 syms_of_xftfont (void)
743 DEFSYM (Qxft
, "xft");
744 DEFSYM (QChinting
, ":hinting");
745 DEFSYM (QCautohint
, ":autohint");
746 DEFSYM (QChintstyle
, ":hintstyle");
747 DEFSYM (QCrgba
, ":rgba");
748 DEFSYM (QCembolden
, ":embolden");
749 DEFSYM (QClcdfilter
, ":lcdfilter");
751 ascii_printable
[0] = 0;
753 xftfont_driver
= ftfont_driver
;
754 xftfont_driver
.type
= Qxft
;
755 xftfont_driver
.get_cache
= xfont_driver
.get_cache
;
756 xftfont_driver
.list
= xftfont_list
;
757 xftfont_driver
.match
= xftfont_match
;
758 xftfont_driver
.open
= xftfont_open
;
759 xftfont_driver
.close
= xftfont_close
;
760 xftfont_driver
.prepare_face
= xftfont_prepare_face
;
761 xftfont_driver
.done_face
= xftfont_done_face
;
762 xftfont_driver
.has_char
= xftfont_has_char
;
763 xftfont_driver
.encode_char
= xftfont_encode_char
;
764 xftfont_driver
.text_extents
= xftfont_text_extents
;
765 xftfont_driver
.draw
= xftfont_draw
;
766 xftfont_driver
.end_for_frame
= xftfont_end_for_frame
;
767 xftfont_driver
.cached_font_ok
= xftfont_cached_font_ok
;
768 #if defined (HAVE_M17N_FLT) && defined (HAVE_LIBOTF)
769 xftfont_driver
.shape
= xftfont_shape
;
772 register_font_driver (&xftfont_driver
, NULL
);