]> code.delx.au - gnu-emacs/blobdiff - src/xftfont.c
Remove now-inaccurate bytecode comments
[gnu-emacs] / src / xftfont.c
index 0a883a7b87b4386acb7d5439b457c8b3c9d3ca14..34c6f7d3e42acbd0bd578c7b6dd6c9765723132f 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.  */
 #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.  */
@@ -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;