/* xftfont.c -- XFT font driver.
- Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Copyright (C) 2006-2016 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
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 3 of the License, 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
#include <X11/Xft/Xft.h>
#include "lisp.h"
-#include "dispextern.h"
#include "xterm.h"
#include "frame.h"
#include "blockinput.h"
-#include "character.h"
#include "charset.h"
#include "composite.h"
-#include "fontset.h"
#include "font.h"
#include "ftfont.h"
/* Xft font driver. */
-Lisp_Object Qxft;
-static Lisp_Object QChinting, QCautohint, QChintstyle, QCrgba, QCembolden,
- QClcdfilter;
/* The actual structure for Xft font that can be cast to struct
font. */
else
{
XGCValues xgcv;
- bool fg_done = 0, bg_done = 0;
+ bool fg_done = false, bg_done = false;
block_input ();
XGetGCValues (FRAME_X_DISPLAY (f), gc,
if (xftface_info)
{
if (xgcv.foreground == face->foreground)
- *fg = xftface_info->xft_fg, fg_done = 1;
+ *fg = xftface_info->xft_fg, fg_done = true;
else if (xgcv.foreground == face->background)
- *fg = xftface_info->xft_bg, fg_done = 1;
+ *fg = xftface_info->xft_bg, fg_done = true;
if (! bg)
- bg_done = 1;
+ bg_done = true;
else if (xgcv.background == face->background)
- *bg = xftface_info->xft_bg, bg_done = 1;
+ *bg = xftface_info->xft_bg, bg_done = true;
else if (xgcv.background == face->foreground)
- *bg = xftface_info->xft_fg, bg_done = 1;
+ *bg = xftface_info->xft_fg, bg_done = true;
}
if (! (fg_done & bg_done))
colors[0].pixel = fg->pixel = xgcv.foreground;
if (bg)
colors[1].pixel = bg->pixel = xgcv.background;
- XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors,
- bg ? 2 : 1);
+ x_query_colors (f, colors, bg ? 2 : 1);
fg->color.alpha = 0xFFFF;
fg->color.red = colors[0].red;
fg->color.green = colors[0].green;
font->ascent = xftfont->ascent;
font->descent = xftfont->descent;
- if (pixel_size >= 5)
+ /* The following workaround is unnecessary on most systems, and
+ causes annoying differences in glyph height between regular and
+ bold fonts (see bug#22383). However, with some fonts, such as
+ monaco, removing the workaround results in overlapping vertical
+ space of a line, see bug#23360. As long as the way to reconcile
+ these opposites is not known, we provide a user option to work
+ around the problem. */
+ if (pixel_size >= 5
+ && xft_font_ascent_descent_override)
{
/* The above condition is a dirty workaround because
XftTextExtents8 behaves strangely for some fonts
font->baseline_offset = 0;
font->relative_compose = 0;
font->default_ascent = 0;
- font->vertical_centering = 0;
+ font->vertical_centering = false;
#ifdef FT_BDF_H
if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT))
{
{
struct xftface_info *xftface_info;
-#if 0
+#if false
/* This doesn't work if face->ascii_face doesn't use an Xft font. */
if (face != face->ascii_face)
{
{
struct xftface_info *xftface_info;
-#if 0
+#if false
/* This doesn't work if face->ascii_face doesn't use an Xft font. */
if (face != face->ascii_face
|| ! face->extra)
XftDrawSetClip (xft_draw, NULL);
if (with_background)
- XftDrawRect (xft_draw, &bg,
- x, y - s->font->ascent, s->width, s->font->height);
+ {
+ int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+ /* Font's global height and ascent values might be
+ preposterously large for some fonts. We fix here the case
+ when those fonts are used for display of glyphless
+ characters, because drawing background with font dimensions
+ in those cases makes the display illegible. There's only one
+ more call to the draw method with with_background set to
+ true, and that's in x_draw_glyph_string_foreground, when
+ drawing the cursor, where we have no such heuristics
+ available. FIXME. */
+ if (s->first_glyph->type == GLYPHLESS_GLYPH
+ && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
+ || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
+ height = ascent =
+ s->first_glyph->slice.glyphless.lower_yoff
+ - s->first_glyph->slice.glyphless.upper_yoff;
+ XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
+ }
code = alloca (sizeof (FT_UInt) * len);
for (i = 0; i < len; i++)
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
static Lisp_Object
xftfont_shape (Lisp_Object lgstring)
{
- struct font *font;
- struct xftfont_info *xftfont_info;
+ struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
+ struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
FT_Face ft_face;
Lisp_Object val;
- CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font);
- xftfont_info = (struct xftfont_info *) font;
ft_face = XftLockFace (xftfont_info->xftfont);
xftfont_info->ft_size = ft_face->size;
val = ftfont_driver.shape (lgstring);
Display *display = FRAME_X_DISPLAY (f);
FcPattern *pat = FcPatternCreate ();
FcBool b1, b2;
- bool ok = 0;
+ bool ok = false;
int i1, i2, r1, r2;
xftfont_add_rendering_parameters (pat, entity);
r2 = FcPatternGetInteger (oldpat, FC_RGBA, 0, &i2);
if (r1 != r2 || i1 != i2) goto out;
- ok = 1;
+ ok = true;
out:
FcPatternDestroy (pat);
return ok;
DEFSYM (QCembolden, ":embolden");
DEFSYM (QClcdfilter, ":lcdfilter");
+ DEFVAR_BOOL ("xft-font-ascent-descent-override",
+ xft_font_ascent_descent_override,
+ doc: /* Non-nil means override the ascent and descent values for Xft font driver.
+This is needed with some fonts to correct vertical overlap of glyphs. */);
+ xft_font_ascent_descent_override = 0;
+
ascii_printable[0] = 0;
xftfont_driver = ftfont_driver;