/* xftfont.c -- XFT font driver.
- Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2006-2013 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
#include <config.h>
#include <stdio.h>
-#include <setjmp.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
/* Xft font driver. */
-static Lisp_Object Qxft;
+Lisp_Object Qxft;
static Lisp_Object QChinting, QCautohint, QChintstyle, QCrgba, QCembolden,
QClcdfilter;
/* The following five 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. */
+ bool maybe_otf; /* Flag to tell if this may be OTF or not. */
OTF *otf;
#endif /* HAVE_LIBOTF */
FT_Size ft_size;
XftColor xft_bg; /* color for face->background */
};
-static void xftfont_get_colors P_ ((FRAME_PTR, struct face *, GC gc,
- struct xftface_info *,
- XftColor *fg, XftColor *bg));
+static void xftfont_get_colors (struct frame *, struct face *, GC gc,
+ struct xftface_info *,
+ XftColor *fg, XftColor *bg);
/* Setup foreground and background colors of GC into FG and BG. If
may be NULL. */
static void
-xftfont_get_colors (f, face, gc, xftface_info, fg, bg)
- FRAME_PTR f;
- struct face *face;
- GC gc;
- struct xftface_info *xftface_info;
- XftColor *fg, *bg;
+xftfont_get_colors (struct frame *f, struct face *face, GC gc,
+ struct xftface_info *xftface_info,
+ XftColor *fg, XftColor *bg)
{
if (xftface_info && face->gc == gc)
{
else
{
XGCValues xgcv;
- int fg_done = 0, bg_done = 0;
+ bool fg_done = 0, bg_done = 0;
- BLOCK_INPUT;
+ block_input ();
XGetGCValues (FRAME_X_DISPLAY (f), gc,
GCForeground | GCBackground, &xgcv);
if (xftface_info)
*bg = xftface_info->xft_fg, bg_done = 1;
}
- if (fg_done + bg_done < 2)
+ if (! (fg_done & bg_done))
{
XColor colors[2];
bg->color.blue = colors[1].blue;
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
-static Lisp_Object xftfont_list P_ ((Lisp_Object, Lisp_Object));
-static Lisp_Object xftfont_match P_ ((Lisp_Object, Lisp_Object));
-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_end_for_frame P_ ((FRAME_PTR f));
-
struct font_driver xftfont_driver;
static Lisp_Object
-xftfont_list (frame, spec)
- Lisp_Object frame;
- Lisp_Object spec;
+xftfont_list (struct frame *f, Lisp_Object spec)
{
- Lisp_Object list = ftfont_driver.list (frame, spec), tail;
+ Lisp_Object list = ftfont_driver.list (f, spec), tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft);
}
static Lisp_Object
-xftfont_match (frame, spec)
- Lisp_Object frame;
- Lisp_Object spec;
+xftfont_match (struct frame *f, Lisp_Object spec)
{
- Lisp_Object entity = ftfont_driver.match (frame, spec);
+ Lisp_Object entity = ftfont_driver.match (f, spec);
if (! NILP (entity))
ASET (entity, FONT_TYPE_INDEX, Qxft);
return entity;
}
-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 void
-xftfont_fix_match (pat, match)
- FcPattern *pat, *match;
+xftfont_fix_match (FcPattern *pat, FcPattern *match)
{
/* These values are not used for matching (except antialias), but for
rendering, so make sure they are carried over to the match.
double dpi;
FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
- if (! b)
+ if (! b)
{
FcPatternDel (match, FC_ANTIALIAS);
FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
}
FcPatternGetBool (pat, FC_HINTING, 0, &b);
- if (! b)
+ if (! b)
{
FcPatternDel (match, FC_HINTING);
FcPatternAddBool (match, FC_HINTING, FcFalse);
}
+#ifndef FC_HINT_STYLE
+# define FC_HINT_STYLE "hintstyle"
+#endif
if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
{
FcPatternDel (match, FC_HINT_STYLE);
}
static void
-xftfont_add_rendering_parameters (pat, entity)
- FcPattern *pat;
- Lisp_Object entity;
+xftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
{
Lisp_Object tail;
int ival;
}
static Lisp_Object
-xftfont_open (f, entity, pixel_size)
- FRAME_PTR f;
- Lisp_Object entity;
- int pixel_size;
+xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
FcResult result;
Display *display = FRAME_X_DISPLAY (f);
- Lisp_Object val, filename, index, font_object;
+ Lisp_Object val, filename, idx, font_object;
FcPattern *pat = NULL, *match;
struct xftfont_info *xftfont_info = NULL;
struct font *font;
return Qnil;
val = XCDR (val);
filename = XCAR (val);
- index = XCDR (val);
+ idx = XCDR (val);
size = XINT (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
xftfont_add_rendering_parameters (pat, entity);
FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
- FcPatternAddInteger (pat, FC_INDEX, XINT (index));
+ FcPatternAddInteger (pat, FC_INDEX, XINT (idx));
- BLOCK_INPUT;
+ block_input ();
/* Make sure that the Xrender extension is added before the Xft one.
Otherwise, the close-display hook set by Xft is called after the
one for Xrender, and the former tries to re-add the latter. This
xftfont = XftFontOpenPattern (display, match);
if (!xftfont)
{
- UNBLOCK_INPUT;
+ unblock_input ();
XftPatternDestroy (match);
return Qnil;
}
ft_face = XftLockFace (xftfont);
- UNBLOCK_INPUT;
+ unblock_input ();
/* We should not destroy PAT here because it is kept in XFTFONT and
destroyed automatically when XFTFONT is closed. */
ASET (font_object, FONT_FORMAT_INDEX,
ftfont_font_format (xftfont->pattern, filename));
font = XFONT_OBJECT (font_object);
- font->pixel_size = pixel_size;
+ font->pixel_size = size;
font->driver = &xftfont_driver;
font->encoding_charset = font->repertory_charset = -1;
xftfont_info->matrix.xy = 0x10000L * matrix->xy;
xftfont_info->matrix.yx = 0x10000L * matrix->yx;
}
- font->pixel_size = size;
- font->driver = &xftfont_driver;
if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)))
spacing = XINT (AREF (entity, FONT_SPACING_INDEX));
else
spacing = FC_PROPORTIONAL;
if (! ascii_printable[0])
{
- int i;
- for (i = 0; i < 95; i++)
- ascii_printable[i] = ' ' + i;
+ int ch;
+ for (ch = 0; ch < 95; ch++)
+ ascii_printable[ch] = ' ' + ch;
}
- BLOCK_INPUT;
+ block_input ();
+
+ /* Unfortunately Xft doesn't provide a way to get minimum char
+ width. So, we set min_width to space_width. */
+
if (spacing != FC_PROPORTIONAL
#ifdef FC_DUAL
&& spacing != FC_DUAL
#endif /* FC_DUAL */
)
{
- font->min_width = font->average_width = font->space_width
- = xftfont->max_advance_width;
+ font->min_width = font->max_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->space_width = extents.xOff;
+ font->min_width = font->max_width = font->space_width
+ = extents.xOff;
if (font->space_width <= 0)
/* dirty workaround */
font->space_width = pixel_size;
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
- UNBLOCK_INPUT;
+ unblock_input ();
font->ascent = xftfont->ascent;
font->descent = xftfont->descent;
font->underline_thickness = 0;
}
#ifdef HAVE_LIBOTF
- xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
+ xftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
xftfont_info->otf = NULL;
#endif /* HAVE_LIBOTF */
xftfont_info->ft_size = ft_face->size;
- /* 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;
}
static void
-xftfont_close (f, font)
- FRAME_PTR f;
- struct font *font;
+xftfont_close (struct frame *f, struct font *font)
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
if (xftfont_info->otf)
OTF_close (xftfont_info->otf);
#endif
- BLOCK_INPUT;
+ block_input ();
XftUnlockFace (xftfont_info->xftfont);
XftFontClose (xftfont_info->display, xftfont_info->xftfont);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static int
-xftfont_prepare_face (f, face)
- FRAME_PTR f;
- struct face *face;
+xftfont_prepare_face (struct frame *f, struct face *face)
{
struct xftface_info *xftface_info;
}
#endif
- xftface_info = malloc (sizeof (struct xftface_info));
+ xftface_info = malloc (sizeof *xftface_info);
if (! xftface_info)
return -1;
xftfont_get_colors (f, face, face->gc, NULL,
}
static void
-xftfont_done_face (f, face)
- FRAME_PTR f;
- struct face *face;
+xftfont_done_face (struct frame *f, struct face *face)
{
struct xftface_info *xftface_info;
}
}
-extern Lisp_Object Qja, Qko;
-
static int
-xftfont_has_char (font, c)
- Lisp_Object font;
- int c;
+xftfont_has_char (Lisp_Object font, int c)
{
struct xftfont_info *xftfont_info;
struct charset *cs = NULL;
}
static unsigned
-xftfont_encode_char (font, c)
- struct font *font;
- int c;
+xftfont_encode_char (struct font *font, int c)
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
unsigned code = XftCharIndex (xftfont_info->display, xftfont_info->xftfont,
}
static int
-xftfont_text_extents (font, code, nglyphs, metrics)
- struct font *font;
- unsigned *code;
- int nglyphs;
- struct font_metrics *metrics;
+xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics)
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
- BLOCK_INPUT;
+ block_input ();
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
- UNBLOCK_INPUT;
+ unblock_input ();
if (metrics)
{
metrics->lbearing = - extents.x;
}
static XftDraw *
-xftfont_get_xft_draw (f)
- FRAME_PTR f;
+xftfont_get_xft_draw (struct frame *f)
{
XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);
if (! xft_draw)
{
- BLOCK_INPUT;
+ 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 ();
+ unblock_input ();
+ eassert (xft_draw != NULL);
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;
- int from, to, x, y, with_background;
+xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
+ bool with_background)
{
- FRAME_PTR f = s->f;
+ struct frame *f = s->f;
struct face *face = s->face;
struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font;
struct xftface_info *xftface_info = NULL;
xftface_info = (struct xftface_info *) face->extra;
xftfont_get_colors (f, face, s->gc, xftface_info,
&fg, with_background ? &bg : NULL);
- BLOCK_INPUT;
+ block_input ();
if (s->num_clips > 0)
XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips);
else
if (with_background)
XftDrawRect (xft_draw, &bg,
- x, y - face->font->ascent, s->width, face->font->height);
+ x, y - s->font->ascent, s->width, s->font->height);
code = alloca (sizeof (FT_UInt) * len);
for (i = 0; i < len; i++)
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
else
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x, y, code, len);
- UNBLOCK_INPUT;
+ unblock_input ();
return len;
}
-Lisp_Object
+#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
+static Lisp_Object
xftfont_shape (Lisp_Object lgstring)
{
struct font *font;
XftUnlockFace (xftfont_info->xftfont);
return val;
}
+#endif
static int
-xftfont_end_for_frame (f)
- FRAME_PTR f;
+xftfont_end_for_frame (struct frame *f)
{
XftDraw *xft_draw;
if (xft_draw)
{
- BLOCK_INPUT;
+ block_input ();
XftDrawDestroy (xft_draw);
- UNBLOCK_INPUT;
+ unblock_input ();
font_put_frame_data (f, &xftfont_driver, NULL);
}
return 0;
}
-static int
-xftfont_cached_font_ok (f, font_object, entity)
- struct frame *f;
- Lisp_Object font_object;
- Lisp_Object entity;
-
+static bool
+xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
+ Lisp_Object entity)
{
struct xftfont_info *info = (struct xftfont_info *) XFONT_OBJECT (font_object);
FcPattern *oldpat = info->xftfont->pattern;
Display *display = FRAME_X_DISPLAY (f);
FcPattern *pat = FcPatternCreate ();
FcBool b1, b2;
- int ok = 0, i1, i2, r1, r2;
+ bool ok = 0;
+ int i1, i2, r1, r2;
xftfont_add_rendering_parameters (pat, entity);
XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
}
void
-syms_of_xftfont ()
+syms_of_xftfont (void)
{
DEFSYM (Qxft, "xft");
DEFSYM (QChinting, ":hinting");
DEFSYM (QCembolden, ":embolden");
DEFSYM (QClcdfilter, ":lcdfilter");
+ ascii_printable[0] = 0;
+
xftfont_driver = ftfont_driver;
xftfont_driver.type = Qxft;
xftfont_driver.get_cache = xfont_driver.get_cache;
register_font_driver (&xftfont_driver, NULL);
}
-
-/* arch-tag: 64ec61bf-7c8e-4fe6-b953-c6a85d5e1605
- (do not change this comment) */