1 /* xftfont.c -- XFT font driver.
2 Copyright (C) 2006-2013 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 casted 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 */
65 /* Structure pointed by (struct face *)->extra */
69 XftColor xft_fg
; /* color for face->foreground */
70 XftColor xft_bg
; /* color for face->background */
73 static void xftfont_get_colors (struct frame
*, struct face
*, GC gc
,
74 struct xftface_info
*,
75 XftColor
*fg
, XftColor
*bg
);
78 /* Setup foreground and background colors of GC into FG and BG. If
79 XFTFACE_INFO is not NULL, reuse the colors in it if possible. BG
83 xftfont_get_colors (struct frame
*f
, struct face
*face
, GC gc
,
84 struct xftface_info
*xftface_info
,
85 XftColor
*fg
, XftColor
*bg
)
87 if (xftface_info
&& face
->gc
== gc
)
89 *fg
= xftface_info
->xft_fg
;
91 *bg
= xftface_info
->xft_bg
;
96 bool fg_done
= 0, bg_done
= 0;
99 XGetGCValues (FRAME_X_DISPLAY (f
), gc
,
100 GCForeground
| GCBackground
, &xgcv
);
103 if (xgcv
.foreground
== face
->foreground
)
104 *fg
= xftface_info
->xft_fg
, fg_done
= 1;
105 else if (xgcv
.foreground
== face
->background
)
106 *fg
= xftface_info
->xft_bg
, fg_done
= 1;
109 else if (xgcv
.background
== face
->background
)
110 *bg
= xftface_info
->xft_bg
, bg_done
= 1;
111 else if (xgcv
.background
== face
->foreground
)
112 *bg
= xftface_info
->xft_fg
, bg_done
= 1;
115 if (! (fg_done
& bg_done
))
119 colors
[0].pixel
= fg
->pixel
= xgcv
.foreground
;
121 colors
[1].pixel
= bg
->pixel
= xgcv
.background
;
122 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
,
124 fg
->color
.alpha
= 0xFFFF;
125 fg
->color
.red
= colors
[0].red
;
126 fg
->color
.green
= colors
[0].green
;
127 fg
->color
.blue
= colors
[0].blue
;
130 bg
->color
.alpha
= 0xFFFF;
131 bg
->color
.red
= colors
[1].red
;
132 bg
->color
.green
= colors
[1].green
;
133 bg
->color
.blue
= colors
[1].blue
;
141 struct font_driver xftfont_driver
;
144 xftfont_list (struct frame
*f
, Lisp_Object spec
)
146 Lisp_Object list
= ftfont_driver
.list (f
, spec
), tail
;
148 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
149 ASET (XCAR (tail
), FONT_TYPE_INDEX
, Qxft
);
154 xftfont_match (struct frame
*f
, Lisp_Object spec
)
156 Lisp_Object entity
= ftfont_driver
.match (f
, spec
);
159 ASET (entity
, FONT_TYPE_INDEX
, Qxft
);
163 static FcChar8 ascii_printable
[95];
166 xftfont_fix_match (FcPattern
*pat
, FcPattern
*match
)
168 /* These values are not used for matching (except antialias), but for
169 rendering, so make sure they are carried over to the match.
170 We also put antialias here because most fonts are antialiased, so
171 the match will have antialias true. */
177 FcPatternGetBool (pat
, FC_ANTIALIAS
, 0, &b
);
180 FcPatternDel (match
, FC_ANTIALIAS
);
181 FcPatternAddBool (match
, FC_ANTIALIAS
, FcFalse
);
183 FcPatternGetBool (pat
, FC_HINTING
, 0, &b
);
186 FcPatternDel (match
, FC_HINTING
);
187 FcPatternAddBool (match
, FC_HINTING
, FcFalse
);
189 #ifndef FC_HINT_STYLE
190 # define FC_HINT_STYLE "hintstyle"
192 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_HINT_STYLE
, 0, &i
))
194 FcPatternDel (match
, FC_HINT_STYLE
);
195 FcPatternAddInteger (match
, FC_HINT_STYLE
, i
);
197 #ifndef FC_LCD_FILTER
198 /* Older fontconfig versions don't have FC_LCD_FILTER. */
199 #define FC_LCD_FILTER "lcdfilter"
201 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_LCD_FILTER
, 0, &i
))
203 FcPatternDel (match
, FC_LCD_FILTER
);
204 FcPatternAddInteger (match
, FC_LCD_FILTER
, i
);
206 if (FcResultMatch
== FcPatternGetInteger (pat
, FC_RGBA
, 0, &i
))
208 FcPatternDel (match
, FC_RGBA
);
209 FcPatternAddInteger (match
, FC_RGBA
, i
);
211 if (FcResultMatch
== FcPatternGetDouble (pat
, FC_DPI
, 0, &dpi
))
213 FcPatternDel (match
, FC_DPI
);
214 FcPatternAddDouble (match
, FC_DPI
, dpi
);
219 xftfont_add_rendering_parameters (FcPattern
*pat
, Lisp_Object entity
)
224 for (tail
= AREF (entity
, FONT_EXTRA_INDEX
); CONSP (tail
); tail
= XCDR (tail
))
226 Lisp_Object key
= XCAR (XCAR (tail
));
227 Lisp_Object val
= XCDR (XCAR (tail
));
229 if (EQ (key
, QCantialias
))
230 FcPatternAddBool (pat
, FC_ANTIALIAS
, NILP (val
) ? FcFalse
: FcTrue
);
231 else if (EQ (key
, QChinting
))
232 FcPatternAddBool (pat
, FC_HINTING
, NILP (val
) ? FcFalse
: FcTrue
);
233 else if (EQ (key
, QCautohint
))
234 FcPatternAddBool (pat
, FC_AUTOHINT
, NILP (val
) ? FcFalse
: FcTrue
);
235 else if (EQ (key
, QChintstyle
))
238 FcPatternAddInteger (pat
, FC_HINT_STYLE
, XINT (val
));
239 else if (SYMBOLP (val
)
240 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
241 FcPatternAddInteger (pat
, FC_HINT_STYLE
, ival
);
243 else if (EQ (key
, QCrgba
))
246 FcPatternAddInteger (pat
, FC_RGBA
, XINT (val
));
247 else if (SYMBOLP (val
)
248 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
249 FcPatternAddInteger (pat
, FC_RGBA
, ival
);
251 else if (EQ (key
, QClcdfilter
))
254 FcPatternAddInteger (pat
, FC_LCD_FILTER
, ival
= XINT (val
));
255 else if (SYMBOLP (val
)
256 && FcNameConstant (SDATA (SYMBOL_NAME (val
)), &ival
))
257 FcPatternAddInteger (pat
, FC_LCD_FILTER
, ival
);
260 else if (EQ (key
, QCembolden
))
261 FcPatternAddBool (pat
, FC_EMBOLDEN
, NILP (val
) ? FcFalse
: FcTrue
);
267 xftfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
270 Display
*display
= FRAME_X_DISPLAY (f
);
271 Lisp_Object val
, filename
, idx
, font_object
;
272 FcPattern
*pat
= NULL
, *match
;
273 struct xftfont_info
*xftfont_info
= NULL
;
276 XftFont
*xftfont
= NULL
;
284 val
= assq_no_quit (QCfont_entity
, AREF (entity
, FONT_EXTRA_INDEX
));
288 filename
= XCAR (val
);
290 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
293 pat
= FcPatternCreate ();
294 FcPatternAddInteger (pat
, FC_WEIGHT
, FONT_WEIGHT_NUMERIC (entity
));
295 i
= FONT_SLANT_NUMERIC (entity
) - 100;
297 FcPatternAddInteger (pat
, FC_SLANT
, i
);
298 FcPatternAddInteger (pat
, FC_WIDTH
, FONT_WIDTH_NUMERIC (entity
));
299 FcPatternAddDouble (pat
, FC_PIXEL_SIZE
, pixel_size
);
300 val
= AREF (entity
, FONT_FAMILY_INDEX
);
302 FcPatternAddString (pat
, FC_FAMILY
, (FcChar8
*) SDATA (SYMBOL_NAME (val
)));
303 val
= AREF (entity
, FONT_FOUNDRY_INDEX
);
305 FcPatternAddString (pat
, FC_FOUNDRY
, (FcChar8
*) SDATA (SYMBOL_NAME (val
)));
306 val
= AREF (entity
, FONT_SPACING_INDEX
);
308 FcPatternAddInteger (pat
, FC_SPACING
, XINT (val
));
309 val
= AREF (entity
, FONT_DPI_INDEX
);
312 double dbl
= XINT (val
);
314 FcPatternAddDouble (pat
, FC_DPI
, dbl
);
316 val
= AREF (entity
, FONT_AVGWIDTH_INDEX
);
317 if (INTEGERP (val
) && XINT (val
) == 0)
318 FcPatternAddBool (pat
, FC_SCALABLE
, FcTrue
);
319 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
320 over 10x20-ISO8859-1.pcf.gz). */
321 FcPatternAddCharSet (pat
, FC_CHARSET
, ftfont_get_fc_charset (entity
));
323 xftfont_add_rendering_parameters (pat
, entity
);
325 FcPatternAddString (pat
, FC_FILE
, (FcChar8
*) SDATA (filename
));
326 FcPatternAddInteger (pat
, FC_INDEX
, XINT (idx
));
330 /* Make sure that the Xrender extension is added before the Xft one.
331 Otherwise, the close-display hook set by Xft is called after the
332 one for Xrender, and the former tries to re-add the latter. This
333 results in inconsistency of internal states and leads to X
334 protocol error when one reconnects to the same X server.
337 int event_base
, error_base
;
338 XRenderQueryExtension (display
, &event_base
, &error_base
);
341 /* Substitute in values from X resources and XftDefaultSet. */
342 XftDefaultSubstitute (display
, FRAME_X_SCREEN_NUMBER (f
), pat
);
343 match
= XftFontMatch (display
, FRAME_X_SCREEN_NUMBER (f
), pat
, &result
);
344 xftfont_fix_match (pat
, match
);
346 FcPatternDestroy (pat
);
347 xftfont
= XftFontOpenPattern (display
, match
);
351 XftPatternDestroy (match
);
354 ft_face
= XftLockFace (xftfont
);
357 /* We should not destroy PAT here because it is kept in XFTFONT and
358 destroyed automatically when XFTFONT is closed. */
359 font_object
= font_make_object (VECSIZE (struct xftfont_info
), entity
, size
);
360 ASET (font_object
, FONT_TYPE_INDEX
, Qxft
);
361 len
= font_unparse_xlfd (entity
, size
, name
, 256);
363 ASET (font_object
, FONT_NAME_INDEX
, make_string (name
, len
));
364 len
= font_unparse_fcname (entity
, size
, name
, 256);
366 ASET (font_object
, FONT_FULLNAME_INDEX
, make_string (name
, len
));
368 ASET (font_object
, FONT_FULLNAME_INDEX
,
369 AREF (font_object
, FONT_NAME_INDEX
));
370 ASET (font_object
, FONT_FILE_INDEX
, filename
);
371 ASET (font_object
, FONT_FORMAT_INDEX
,
372 ftfont_font_format (xftfont
->pattern
, filename
));
373 font
= XFONT_OBJECT (font_object
);
374 font
->pixel_size
= size
;
375 font
->driver
= &xftfont_driver
;
376 font
->encoding_charset
= font
->repertory_charset
= -1;
378 xftfont_info
= (struct xftfont_info
*) font
;
379 xftfont_info
->display
= display
;
380 xftfont_info
->screen
= FRAME_X_SCREEN_NUMBER (f
);
381 xftfont_info
->xftfont
= xftfont
;
382 /* This means that there's no need of transformation. */
383 xftfont_info
->matrix
.xx
= 0;
384 if (FcPatternGetMatrix (xftfont
->pattern
, FC_MATRIX
, 0, &matrix
)
387 xftfont_info
->matrix
.xx
= 0x10000L
* matrix
->xx
;
388 xftfont_info
->matrix
.yy
= 0x10000L
* matrix
->yy
;
389 xftfont_info
->matrix
.xy
= 0x10000L
* matrix
->xy
;
390 xftfont_info
->matrix
.yx
= 0x10000L
* matrix
->yx
;
392 if (INTEGERP (AREF (entity
, FONT_SPACING_INDEX
)))
393 spacing
= XINT (AREF (entity
, FONT_SPACING_INDEX
));
395 spacing
= FC_PROPORTIONAL
;
396 if (! ascii_printable
[0])
399 for (ch
= 0; ch
< 95; ch
++)
400 ascii_printable
[ch
] = ' ' + ch
;
404 /* Unfortunately Xft doesn't provide a way to get minimum char
405 width. So, we set min_width to space_width. */
407 if (spacing
!= FC_PROPORTIONAL
409 && spacing
!= FC_DUAL
413 font
->min_width
= font
->max_width
= font
->average_width
414 = font
->space_width
= xftfont
->max_advance_width
;
415 XftTextExtents8 (display
, xftfont
, ascii_printable
+ 1, 94, &extents
);
419 XftTextExtents8 (display
, xftfont
, ascii_printable
, 1, &extents
);
420 font
->min_width
= font
->max_width
= font
->space_width
422 if (font
->space_width
<= 0)
423 /* dirty workaround */
424 font
->space_width
= pixel_size
;
425 XftTextExtents8 (display
, xftfont
, ascii_printable
+ 1, 94, &extents
);
426 font
->average_width
= (font
->space_width
+ extents
.xOff
) / 95;
430 font
->ascent
= xftfont
->ascent
;
431 font
->descent
= xftfont
->descent
;
434 /* The above condition is a dirty workaround because
435 XftTextExtents8 behaves strangely for some fonts
436 (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */
437 if (font
->ascent
< extents
.y
)
438 font
->ascent
= extents
.y
;
439 if (font
->descent
< extents
.height
- extents
.y
)
440 font
->descent
= extents
.height
- extents
.y
;
442 font
->height
= font
->ascent
+ font
->descent
;
444 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) == 0)
446 int upEM
= ft_face
->units_per_EM
;
448 font
->underline_position
= -ft_face
->underline_position
* size
/ upEM
;
449 font
->underline_thickness
= ft_face
->underline_thickness
* size
/ upEM
;
450 if (font
->underline_thickness
> 2)
451 font
->underline_position
-= font
->underline_thickness
/ 2;
455 font
->underline_position
= -1;
456 font
->underline_thickness
= 0;
459 xftfont_info
->maybe_otf
= (ft_face
->face_flags
& FT_FACE_FLAG_SFNT
) != 0;
460 xftfont_info
->otf
= NULL
;
461 #endif /* HAVE_LIBOTF */
462 xftfont_info
->ft_size
= ft_face
->size
;
464 font
->baseline_offset
= 0;
465 font
->relative_compose
= 0;
466 font
->default_ascent
= 0;
467 font
->vertical_centering
= 0;
469 if (! (ft_face
->face_flags
& FT_FACE_FLAG_SFNT
))
473 if (FT_Get_BDF_Property (ft_face
, "_MULE_BASELINE_OFFSET", &rec
) == 0
474 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
475 font
->baseline_offset
= rec
.u
.integer
;
476 if (FT_Get_BDF_Property (ft_face
, "_MULE_RELATIVE_COMPOSE", &rec
) == 0
477 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
478 font
->relative_compose
= rec
.u
.integer
;
479 if (FT_Get_BDF_Property (ft_face
, "_MULE_DEFAULT_ASCENT", &rec
) == 0
480 && rec
.type
== BDF_PROPERTY_TYPE_INTEGER
)
481 font
->default_ascent
= rec
.u
.integer
;
489 xftfont_close (struct frame
*f
, struct font
*font
)
491 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
494 if (xftfont_info
->otf
)
495 OTF_close (xftfont_info
->otf
);
498 XftUnlockFace (xftfont_info
->xftfont
);
499 XftFontClose (xftfont_info
->display
, xftfont_info
->xftfont
);
504 xftfont_prepare_face (struct frame
*f
, struct face
*face
)
506 struct xftface_info
*xftface_info
;
509 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
510 if (face
!= face
->ascii_face
)
512 face
->extra
= face
->ascii_face
->extra
;
517 xftface_info
= malloc (sizeof *xftface_info
);
520 xftfont_get_colors (f
, face
, face
->gc
, NULL
,
521 &xftface_info
->xft_fg
, &xftface_info
->xft_bg
);
522 face
->extra
= xftface_info
;
527 xftfont_done_face (struct frame
*f
, struct face
*face
)
529 struct xftface_info
*xftface_info
;
532 /* This doesn't work if face->ascii_face doesn't use an Xft font. */
533 if (face
!= face
->ascii_face
538 xftface_info
= (struct xftface_info
*) face
->extra
;
547 xftfont_has_char (Lisp_Object font
, int c
)
549 struct xftfont_info
*xftfont_info
;
550 struct charset
*cs
= NULL
;
552 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
553 && charset_jisx0208
>= 0)
554 cs
= CHARSET_FROM_ID (charset_jisx0208
);
555 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
556 && charset_ksc5601
>= 0)
557 cs
= CHARSET_FROM_ID (charset_ksc5601
);
559 return (ENCODE_CHAR (cs
, c
) != CHARSET_INVALID_CODE (cs
));
561 if (FONT_ENTITY_P (font
))
562 return ftfont_driver
.has_char (font
, c
);
563 xftfont_info
= (struct xftfont_info
*) XFONT_OBJECT (font
);
564 return (XftCharExists (xftfont_info
->display
, xftfont_info
->xftfont
,
565 (FcChar32
) c
) == FcTrue
);
569 xftfont_encode_char (struct font
*font
, int c
)
571 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
572 unsigned code
= XftCharIndex (xftfont_info
->display
, xftfont_info
->xftfont
,
575 return (code
? code
: FONT_INVALID_CODE
);
579 xftfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
581 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) font
;
585 XftGlyphExtents (xftfont_info
->display
, xftfont_info
->xftfont
, code
, nglyphs
,
590 metrics
->lbearing
= - extents
.x
;
591 metrics
->rbearing
= - extents
.x
+ extents
.width
;
592 metrics
->width
= extents
.xOff
;
593 metrics
->ascent
= extents
.y
;
594 metrics
->descent
= extents
.height
- extents
.y
;
600 xftfont_get_xft_draw (struct frame
*f
)
602 XftDraw
*xft_draw
= font_get_frame_data (f
, &xftfont_driver
);
607 xft_draw
= XftDrawCreate (FRAME_X_DISPLAY (f
),
610 FRAME_X_COLORMAP (f
));
612 eassert (xft_draw
!= NULL
);
613 font_put_frame_data (f
, &xftfont_driver
, xft_draw
);
619 xftfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
620 bool with_background
)
622 struct frame
*f
= s
->f
;
623 struct face
*face
= s
->face
;
624 struct xftfont_info
*xftfont_info
= (struct xftfont_info
*) s
->font
;
625 struct xftface_info
*xftface_info
= NULL
;
626 XftDraw
*xft_draw
= xftfont_get_xft_draw (f
);
632 if (s
->font
== face
->font
)
633 xftface_info
= (struct xftface_info
*) face
->extra
;
634 xftfont_get_colors (f
, face
, s
->gc
, xftface_info
,
635 &fg
, with_background
? &bg
: NULL
);
637 if (s
->num_clips
> 0)
638 XftDrawSetClipRectangles (xft_draw
, 0, 0, s
->clip
, s
->num_clips
);
640 XftDrawSetClip (xft_draw
, NULL
);
643 XftDrawRect (xft_draw
, &bg
,
644 x
, y
- s
->font
->ascent
, s
->width
, s
->font
->height
);
645 code
= alloca (sizeof (FT_UInt
) * len
);
646 for (i
= 0; i
< len
; i
++)
647 code
[i
] = ((XCHAR2B_BYTE1 (s
->char2b
+ from
+ i
) << 8)
648 | XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
));
651 for (i
= 0; i
< len
; i
++)
652 XftDrawGlyphs (xft_draw
, &fg
, xftfont_info
->xftfont
,
653 x
+ i
, y
, code
+ i
, 1);
655 XftDrawGlyphs (xft_draw
, &fg
, xftfont_info
->xftfont
,
662 #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
664 xftfont_shape (Lisp_Object lgstring
)
667 struct xftfont_info
*xftfont_info
;
671 CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring
), font
);
672 xftfont_info
= (struct xftfont_info
*) font
;
673 ft_face
= XftLockFace (xftfont_info
->xftfont
);
674 xftfont_info
->ft_size
= ft_face
->size
;
675 val
= ftfont_driver
.shape (lgstring
);
676 XftUnlockFace (xftfont_info
->xftfont
);
682 xftfont_end_for_frame (struct frame
*f
)
686 /* Don't do anything if display is dead */
687 if (FRAME_X_DISPLAY (f
) == NULL
) return 0;
689 xft_draw
= font_get_frame_data (f
, &xftfont_driver
);
694 XftDrawDestroy (xft_draw
);
696 font_put_frame_data (f
, &xftfont_driver
, NULL
);
702 xftfont_cached_font_ok (struct frame
*f
, Lisp_Object font_object
,
705 struct xftfont_info
*info
= (struct xftfont_info
*) XFONT_OBJECT (font_object
);
706 FcPattern
*oldpat
= info
->xftfont
->pattern
;
707 Display
*display
= FRAME_X_DISPLAY (f
);
708 FcPattern
*pat
= FcPatternCreate ();
713 xftfont_add_rendering_parameters (pat
, entity
);
714 XftDefaultSubstitute (display
, FRAME_X_SCREEN_NUMBER (f
), pat
);
716 r1
= FcPatternGetBool (pat
, FC_ANTIALIAS
, 0, &b1
);
717 r2
= FcPatternGetBool (oldpat
, FC_ANTIALIAS
, 0, &b2
);
718 if (r1
!= r2
|| b1
!= b2
) goto out
;
719 r1
= FcPatternGetBool (pat
, FC_HINTING
, 0, &b1
);
720 r2
= FcPatternGetBool (oldpat
, FC_HINTING
, 0, &b2
);
721 if (r1
!= r2
|| b1
!= b2
) goto out
;
722 r1
= FcPatternGetBool (pat
, FC_AUTOHINT
, 0, &b1
);
723 r2
= FcPatternGetBool (oldpat
, FC_AUTOHINT
, 0, &b2
);
724 if (r1
!= r2
|| b1
!= b2
) goto out
;
726 r1
= FcPatternGetBool (pat
, FC_EMBOLDEN
, 0, &b1
);
727 r2
= FcPatternGetBool (oldpat
, FC_EMBOLDEN
, 0, &b2
);
728 if (r1
!= r2
|| b1
!= b2
) goto out
;
730 r1
= FcPatternGetInteger (pat
, FC_HINT_STYLE
, 0, &i1
);
731 r2
= FcPatternGetInteger (oldpat
, FC_HINT_STYLE
, 0, &i2
);
732 if (r1
!= r2
|| i1
!= i2
) goto out
;
733 r1
= FcPatternGetInteger (pat
, FC_LCD_FILTER
, 0, &i1
);
734 r2
= FcPatternGetInteger (oldpat
, FC_LCD_FILTER
, 0, &i2
);
735 if (r1
!= r2
|| i1
!= i2
) goto out
;
736 r1
= FcPatternGetInteger (pat
, FC_RGBA
, 0, &i1
);
737 r2
= FcPatternGetInteger (oldpat
, FC_RGBA
, 0, &i2
);
738 if (r1
!= r2
|| i1
!= i2
) goto out
;
742 FcPatternDestroy (pat
);
747 syms_of_xftfont (void)
749 DEFSYM (Qxft
, "xft");
750 DEFSYM (QChinting
, ":hinting");
751 DEFSYM (QCautohint
, ":autohint");
752 DEFSYM (QChintstyle
, ":hintstyle");
753 DEFSYM (QCrgba
, ":rgba");
754 DEFSYM (QCembolden
, ":embolden");
755 DEFSYM (QClcdfilter
, ":lcdfilter");
757 ascii_printable
[0] = 0;
759 xftfont_driver
= ftfont_driver
;
760 xftfont_driver
.type
= Qxft
;
761 xftfont_driver
.get_cache
= xfont_driver
.get_cache
;
762 xftfont_driver
.list
= xftfont_list
;
763 xftfont_driver
.match
= xftfont_match
;
764 xftfont_driver
.open
= xftfont_open
;
765 xftfont_driver
.close
= xftfont_close
;
766 xftfont_driver
.prepare_face
= xftfont_prepare_face
;
767 xftfont_driver
.done_face
= xftfont_done_face
;
768 xftfont_driver
.has_char
= xftfont_has_char
;
769 xftfont_driver
.encode_char
= xftfont_encode_char
;
770 xftfont_driver
.text_extents
= xftfont_text_extents
;
771 xftfont_driver
.draw
= xftfont_draw
;
772 xftfont_driver
.end_for_frame
= xftfont_end_for_frame
;
773 xftfont_driver
.cached_font_ok
= xftfont_cached_font_ok
;
774 #if defined (HAVE_M17N_FLT) && defined (HAVE_LIBOTF)
775 xftfont_driver
.shape
= xftfont_shape
;
778 register_font_driver (&xftfont_driver
, NULL
);