]> code.delx.au - gnu-emacs/blobdiff - src/xftfont.c
Merge from origin/emacs-25
[gnu-emacs] / src / xftfont.c
index c587d814efa103bd8cfbecac090b19f8197dae98..7926325419c10195d8a8681579f7e1009216a0fc 100644 (file)
@@ -1,5 +1,5 @@
 /* xftfont.c -- XFT font driver.
 /* xftfont.c -- XFT font driver.
-   Copyright (C) 2006-2015 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
    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
 
 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
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,14 +25,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <X11/Xft/Xft.h>
 
 #include "lisp.h"
 #include <X11/Xft/Xft.h>
 
 #include "lisp.h"
-#include "dispextern.h"
 #include "xterm.h"
 #include "frame.h"
 #include "blockinput.h"
 #include "xterm.h"
 #include "frame.h"
 #include "blockinput.h"
-#include "character.h"
 #include "charset.h"
 #include "composite.h"
 #include "charset.h"
 #include "composite.h"
-#include "fontset.h"
 #include "font.h"
 #include "ftfont.h"
 
 #include "font.h"
 #include "ftfont.h"
 
@@ -85,7 +82,7 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc,
   else
     {
       XGCValues xgcv;
   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,
 
       block_input ();
       XGetGCValues (FRAME_X_DISPLAY (f), gc,
@@ -93,15 +90,15 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc,
       if (xftface_info)
        {
          if (xgcv.foreground == face->foreground)
       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)
          else if (xgcv.foreground == face->background)
-           *fg = xftface_info->xft_bg, fg_done = 1;
+           *fg = xftface_info->xft_bg, fg_done = true;
          if (! bg)
          if (! bg)
-           bg_done = 1;
+           bg_done = true;
          else if (xgcv.background == face->background)
          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)
          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))
        }
 
       if (! (fg_done & bg_done))
@@ -111,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;
          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;
          fg->color.alpha = 0xFFFF;
          fg->color.red = colors[0].red;
          fg->color.green = colors[0].green;
@@ -399,16 +395,6 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
 
   font->ascent = xftfont->ascent;
   font->descent = xftfont->descent;
 
   font->ascent = xftfont->ascent;
   font->descent = xftfont->descent;
-  if (pixel_size >= 5)
-    {
-      /* The above condition is a dirty workaround because
-        XftTextExtents8 behaves strangely for some fonts
-        (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */
-      if (font->ascent < extents.y)
-       font->ascent = extents.y;
-      if (font->descent < extents.height - extents.y)
-       font->descent = extents.height - extents.y;
-    }
   font->height = font->ascent + font->descent;
 
   if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0)
   font->height = font->ascent + font->descent;
 
   if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0)
@@ -434,7 +420,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->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))
     {
 #ifdef FT_BDF_H
   if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT))
     {
@@ -487,7 +473,7 @@ xftfont_prepare_face (struct frame *f, struct face *face)
 {
   struct xftface_info *xftface_info;
 
 {
   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)
     {
   /* This doesn't work if face->ascii_face doesn't use an Xft font. */
   if (face != face->ascii_face)
     {
@@ -507,7 +493,7 @@ xftfont_done_face (struct frame *f, struct face *face)
 {
   struct xftface_info *xftface_info;
 
 {
   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)
   /* This doesn't work if face->ascii_face doesn't use an Xft font. */
   if (face != face->ascii_face
       || ! face->extra)
@@ -617,8 +603,26 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     XftDrawSetClip (xft_draw, NULL);
 
   if (with_background)
     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)
   code = alloca (sizeof (FT_UInt) * len);
   for (i = 0; i < len; i++)
     code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
@@ -640,13 +644,11 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 static Lisp_Object
 xftfont_shape (Lisp_Object lgstring)
 {
 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;
 
   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);
   ft_face = XftLockFace (xftfont_info->xftfont);
   xftfont_info->ft_size = ft_face->size;
   val = ftfont_driver.shape (lgstring);
@@ -684,7 +686,7 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
   Display *display = FRAME_X_DISPLAY (f);
   FcPattern *pat = FcPatternCreate ();
   FcBool b1, b2;
   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);
   int i1, i2, r1, r2;
 
   xftfont_add_rendering_parameters (pat, entity);
@@ -714,7 +716,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;
 
   r2 = FcPatternGetInteger (oldpat, FC_RGBA, 0, &i2);
   if (r1 != r2 || i1 != i2) goto out;
 
-  ok = 1;
+  ok = true;
  out:
   FcPatternDestroy (pat);
   return ok;
  out:
   FcPatternDestroy (pat);
   return ok;