]> code.delx.au - gnu-emacs/blobdiff - src/xftfont.c
(math-read-token): Read complement signed numbers.
[gnu-emacs] / src / xftfont.c
index abe8419e833055dfc196cbbec604cb842eedb58e..e66b538fa157231f50afd3dbc757a9a81252b0d6 100644 (file)
@@ -1,6 +1,6 @@
 /* xftfont.c -- XFT font driver.
-   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
-   Copyright (C) 2006, 2007, 2008
+   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
@@ -21,6 +21,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
+#include <setjmp.h>
 #include <X11/Xlib.h>
 #include <X11/Xft/Xft.h>
 
@@ -46,13 +47,14 @@ static Lisp_Object QChinting , QCautohint, QChintstyle, QCrgba, QCembolden;
 struct xftfont_info
 {
   struct font font;
-  /* The following three members must be here in this order to be
+  /* The following four 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.  */
   OTF *otf;
 #endif /* HAVE_LIBOTF */
   FT_Size ft_size;
+  int index;
   Display *display;
   int screen;
   XftFont *xftfont;
@@ -143,6 +145,7 @@ 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 *));
@@ -157,7 +160,7 @@ xftfont_list (frame, spec)
      Lisp_Object spec;
 {
   Lisp_Object list = ftfont_driver.list (frame, spec), tail;
-  
+
   for (tail = list; CONSP (tail); tail = XCDR (tail))
     ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft);
   return list;
@@ -254,7 +257,7 @@ xftfont_open (f, entity, pixel_size)
       else if (EQ (key, QChintstyle))
        {
          if (INTEGERP (val))
-           FcPatternAddInteger (pat, FC_RGBA, XINT (val));
+           FcPatternAddInteger (pat, FC_HINT_STYLE, XINT (val));
        }
       else if (EQ (key, QCrgba))
        {
@@ -269,20 +272,31 @@ xftfont_open (f, entity, pixel_size)
 
   FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
   FcPatternAddInteger (pat, FC_INDEX, XINT (index));
-                      
+
 
   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
+     results in inconsistency of internal states and leads to X
+     protocol error when one reconnects to the same X server.
+     (Bug#1696)  */
+  {
+    int event_base, error_base;
+    XRenderQueryExtension (display, &event_base, &error_base);
+  }
   match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
   FcPatternDestroy (pat);
   xftfont = XftFontOpenPattern (display, match);
-  ft_face = XftLockFace (xftfont);
-  UNBLOCK_INPUT;
-
-  if (! xftfont)
+  if (!xftfont)
     {
+      UNBLOCK_INPUT;
       XftPatternDestroy (match);
       return Qnil;
     }
+  ft_face = XftLockFace (xftfont);
+  UNBLOCK_INPUT;
+
   /* We should not destroy PAT here because it is kept in XFTFONT and
      destroyed automatically when XFTFONT is closed.  */
   font_object = font_make_object (VECSIZE (struct xftfont_info), entity, size);
@@ -333,7 +347,7 @@ xftfont_open (f, entity, pixel_size)
       font->space_width = extents.xOff;
       if (font->space_width <= 0)
        /* dirty workaround */
-       font->space_width = pixel_size; 
+       font->space_width = pixel_size;
       XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
       font->average_width = (font->space_width + extents.xOff) / 95;
     }
@@ -358,7 +372,7 @@ xftfont_open (f, entity, pixel_size)
       int upEM = ft_face->units_per_EM;
 
       font->underline_position = -ft_face->underline_position * size / upEM;
-      font->underline_thickness = -ft_face->underline_thickness * size / upEM;
+      font->underline_thickness = ft_face->underline_thickness * size / upEM;
       if (font->underline_thickness > 2)
        font->underline_position -= font->underline_thickness / 2;
     }
@@ -449,7 +463,7 @@ xftfont_done_face (f, face)
      struct face *face;
 {
   struct xftface_info *xftface_info;
-  
+
 #if 0
   /* This doesn't work if face->ascii_face doesn't use an Xft font. */
   if (face != face->ascii_face
@@ -465,6 +479,32 @@ xftfont_done_face (f, face)
     }
 }
 
+extern Lisp_Object Qja, Qko;
+
+static int
+xftfont_has_char (font, c)
+     Lisp_Object font;
+     int c;
+{
+  struct xftfont_info *xftfont_info;
+  struct charset *cs = NULL;
+
+  if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
+      && charset_jisx0208 >= 0)
+    cs = CHARSET_FROM_ID (charset_jisx0208);
+  else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
+      && charset_ksc5601 >= 0)
+    cs = CHARSET_FROM_ID (charset_ksc5601);
+  if (cs)
+    return (ENCODE_CHAR (cs, c) != CHARSET_INVALID_CODE (cs));
+
+  if (FONT_ENTITY_P (font))
+    return ftfont_driver.has_char (font, c);
+  xftfont_info = (struct xftfont_info *) XFONT_OBJECT (font);
+  return (XftCharExists (xftfont_info->display, xftfont_info->xftfont,
+                        (FcChar32) c) == FcTrue);
+}
+
 static unsigned
 xftfont_encode_char (font, c)
      struct font *font;
@@ -473,7 +513,7 @@ xftfont_encode_char (font, c)
   struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
   unsigned code = XftCharIndex (xftfont_info->display, xftfont_info->xftfont,
                                (FcChar32) c);
-  
+
   return (code ? code : FONT_INVALID_CODE);
 }
 
@@ -506,7 +546,7 @@ static XftDraw *
 xftfont_get_xft_draw (f)
      FRAME_PTR f;
 {
-  XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);;
+  XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);
 
   if (! xft_draw)
     {
@@ -603,6 +643,7 @@ syms_of_xftfont ()
   xftfont_driver.close = xftfont_close;
   xftfont_driver.prepare_face = xftfont_prepare_face;
   xftfont_driver.done_face = xftfont_done_face;
+  xftfont_driver.has_char = xftfont_has_char;
   xftfont_driver.encode_char = xftfont_encode_char;
   xftfont_driver.text_extents = xftfont_text_extents;
   xftfont_driver.draw = xftfont_draw;