X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c12598a62e2e31f3377c52fe4b283b710ce1451e..5932ffcd028af9fc70c9f8e731f2776a9753d81d:/src/xftfont.c diff --git a/src/xftfont.c b/src/xftfont.c index 0a883a7b87..34c6f7d3e4 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -1,5 +1,5 @@ /* 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 @@ -8,8 +8,8 @@ This file is part of GNU Emacs. 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 @@ -25,22 +25,16 @@ along with GNU Emacs. If not, see . */ #include #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. */ @@ -88,7 +82,7 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc, 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, @@ -96,15 +90,15 @@ xftfont_get_colors (struct frame *f, struct face *face, GC 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)) @@ -114,8 +108,7 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc, 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; @@ -402,7 +395,15 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) 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 @@ -437,7 +438,7 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) 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)) { @@ -490,7 +491,7 @@ xftfont_prepare_face (struct frame *f, struct face *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) { @@ -510,7 +511,7 @@ xftfont_done_face (struct frame *f, struct face *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) @@ -620,8 +621,26 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, 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) @@ -643,13 +662,11 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, 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); @@ -687,7 +704,7 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object, 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); @@ -717,7 +734,7 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object, r2 = FcPatternGetInteger (oldpat, FC_RGBA, 0, &i2); if (r1 != r2 || i1 != i2) goto out; - ok = 1; + ok = true; out: FcPatternDestroy (pat); return ok; @@ -734,6 +751,12 @@ syms_of_xftfont (void) 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;