Merge from trunk
[bpt/emacs.git] / src / ftxfont.c
index 62453a1..0a91376 100644 (file)
@@ -1,15 +1,15 @@
 /* ftxfont.c -- FreeType font driver on X (without using XFT).
-   Copyright (C) 2006 Free Software Foundation, Inc.
-   Copyright (C) 2006
+   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+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 2, 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
@@ -17,12 +17,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+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 "lisp.h"
@@ -40,13 +39,12 @@ Boston, MA 02110-1301, USA.  */
 static Lisp_Object Qftx;
 
 /* Prototypes for helper function.  */
-static GC *ftxfont_get_gcs P_ ((FRAME_PTR, unsigned long, unsigned long));
-static int ftxfont_draw_bitmap P_ ((FRAME_PTR, GC, GC *, struct font *,
-                                   unsigned, int, int, XPoint *, int, int *,
-                                   int));
-static void ftxfont_draw_backgrond P_ ((FRAME_PTR, struct font *, GC,
-                                       int, int, int));
-static Font ftxfont_default_fid P_ ((FRAME_PTR));
+static GC *ftxfont_get_gcs (FRAME_PTR, unsigned long, unsigned long);
+static int ftxfont_draw_bitmap (FRAME_PTR, GC, GC *, struct font *,
+                                unsigned, int, int, XPoint *, int, int *,
+                                int);
+static void ftxfont_draw_backgrond (FRAME_PTR, struct font *, GC,
+                                    int, int, int);
 
 struct ftxfont_frame_data
 {
@@ -63,9 +61,7 @@ struct ftxfont_frame_data
 /* Return an array of 6 GCs for antialiasing.  */
 
 static GC *
-ftxfont_get_gcs (f, foreground, background)
-     FRAME_PTR f;
-     unsigned long foreground, background;
+ftxfont_get_gcs (FRAME_PTR f, long unsigned int foreground, long unsigned int background)
 {
   XColor color;
   XGCValues xgcv;
@@ -142,15 +138,7 @@ ftxfont_get_gcs (f, foreground, background)
 }
 
 static int
-ftxfont_draw_bitmap (f, gc_fore, gcs, font, code, x, y, p, size, n, flush)
-     FRAME_PTR f;
-     GC gc_fore, *gcs;
-     struct font *font;
-     unsigned code;
-     int x, y;
-     XPoint *p;
-     int size, *n;
-     int flush;
+ftxfont_draw_bitmap (FRAME_PTR f, GC gc_fore, GC *gcs, struct font *font, unsigned int code, int x, int y, XPoint *p, int size, int *n, int flush)
 {
   struct font_bitmap bitmap;
   unsigned char *b;
@@ -226,11 +214,7 @@ ftxfont_draw_bitmap (f, gc_fore, gcs, font, code, x, y, p, size, n, flush)
 }
 
 static void
-ftxfont_draw_backgrond (f, font, gc, x, y, width)
-     FRAME_PTR f;
-     struct font *font;
-     GC gc;
-     int x, y, width;
+ftxfont_draw_backgrond (FRAME_PTR f, struct font *font, GC gc, int x, int y, int width)
 {
   XGCValues xgcv;
 
@@ -238,63 +222,31 @@ ftxfont_draw_backgrond (f, font, gc, x, y, width)
                GCForeground | GCBackground, &xgcv);
   XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background);
   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
-                 x, y - font->ascent, width, y + font->descent);
+                 x, y - FONT_BASE (font), width, FONT_HEIGHT (font));
   XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground);
 }
 
-/* Return the default Font ID on frame F.  */
-
-static Font
-ftxfont_default_fid (f)
-     FRAME_PTR f;
-{
-  static int fid_known;
-  static Font fid;
-
-  if (! fid_known)
-    {
-      fid = XLoadFont (FRAME_X_DISPLAY (f), "fixed");
-      if (! fid)
-       {
-         fid = XLoadFont (FRAME_X_DISPLAY (f), "*");
-         if (! fid)
-           abort ();
-       }
-      fid_known = 1;
-    }
-  return fid;
-}
-
 /* Prototypes for font-driver methods.  */
-static Lisp_Object ftxfont_list P_ ((Lisp_Object, Lisp_Object));
-static Lisp_Object ftxfont_match P_ ((Lisp_Object, Lisp_Object));
-static struct font *ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int));
-static void ftxfont_close P_ ((FRAME_PTR, struct font *));
-static int ftxfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
+static Lisp_Object ftxfont_list (Lisp_Object, Lisp_Object);
+static Lisp_Object ftxfont_match (Lisp_Object, Lisp_Object);
+static Lisp_Object ftxfont_open (FRAME_PTR, Lisp_Object, int);
+static void ftxfont_close (FRAME_PTR, struct font *);
+static int ftxfont_draw (struct glyph_string *, int, int, int, int, int);
 
 struct font_driver ftxfont_driver;
 
 static Lisp_Object
-ftxfont_list (frame, spec)
-     Lisp_Object frame;
-     Lisp_Object spec;
+ftxfont_list (Lisp_Object frame, Lisp_Object spec)
 {
-  Lisp_Object val = ftfont_driver.list (frame, spec);
+  Lisp_Object list = ftfont_driver.list (frame, spec), tail;
   
-  if (! NILP (val))
-    {
-      int i;
-
-      for (i = 0; i < ASIZE (val); i++)
-       ASET (AREF (val, i), FONT_TYPE_INDEX, Qftx);
-    }
-  return val;
+  for (tail = list; CONSP (tail); tail = XCDR (tail))
+    ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx);
+  return list;
 }
 
 static Lisp_Object
-ftxfont_match (frame, spec)
-     Lisp_Object frame;
-     Lisp_Object spec;
+ftxfont_match (Lisp_Object frame, Lisp_Object spec)
 {
   Lisp_Object entity = ftfont_driver.match (frame, spec);
 
@@ -303,80 +255,39 @@ ftxfont_match (frame, spec)
   return entity;
 }
 
-static struct font *
-ftxfont_open (f, entity, pixel_size)
-     FRAME_PTR f;
-     Lisp_Object entity;
-     int pixel_size;
+static Lisp_Object
+ftxfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Lisp_Object font_object;
   struct font *font;
-  XFontStruct *xfont = malloc (sizeof (XFontStruct));
-  
-  if (! xfont)
-    return NULL;
-  font = ftfont_driver.open (f, entity, pixel_size);
-  if (! font)
-    {
-      free (xfont);
-      return NULL;
-    }
 
-  xfont->fid = ftxfont_default_fid (f);
-  xfont->ascent = font->ascent;
-  xfont->descent = font->descent;
-  xfont->max_bounds.width = font->font.size;
-  xfont->min_bounds.width = font->min_width;
-  font->font.font = xfont;
+  font_object = ftfont_driver.open (f, entity, pixel_size);
+  if (NILP (font_object))
+    return Qnil;
+  font = XFONT_OBJECT (font_object);
   font->driver = &ftxfont_driver;
-
-  dpyinfo->n_fonts++;
-
-  /* Set global flag fonts_changed_p to non-zero if the font loaded
-     has a character with a smaller width than any other character
-     before, or if the font loaded has a smaller height than any other
-     font loaded before.  If this happens, it will make a glyph matrix
-     reallocation necessary.  */
-  if (dpyinfo->n_fonts == 1)
-    {
-      dpyinfo->smallest_font_height = font->font.height;
-      dpyinfo->smallest_char_width = font->min_width;
-      fonts_changed_p = 1;
-    }
-  else
-    {
-      if (dpyinfo->smallest_font_height > font->font.height)
-       dpyinfo->smallest_font_height = font->font.height, fonts_changed_p |= 1;
-      if (dpyinfo->smallest_char_width > font->min_width)
-       dpyinfo->smallest_char_width = font->min_width, fonts_changed_p |= 1;
-    }
-
-  return font;
+  return font_object;
 }
 
 static void
-ftxfont_close (f, font)
-     FRAME_PTR f;
-     struct font *font;
+ftxfont_close (FRAME_PTR f, struct font *font)
 {
   ftfont_driver.close (f, font);
-  FRAME_X_DISPLAY_INFO (f)->n_fonts--;
 }
 
 static int
-ftxfont_draw (s, from, to, x, y, with_background)
-     struct glyph_string *s;
-     int from, to, x, y, with_background;
+ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y, int with_background)
 {
   FRAME_PTR f = s->f;
   struct face *face = s->face;
-  struct font *font = (struct font *) face->font_info;
+  struct font *font = s->font;
   XPoint p[0x700];
   int n[7];
   unsigned *code;
   int len = to - from;
   int i;
   GC *gcs;
+  int xadvance;
 
   n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
 
@@ -409,8 +320,11 @@ ftxfont_draw (s, from, to, x, y, with_background)
                              s->clip, s->num_clips, Unsorted);
 
       for (i = 0; i < len; i++)
-       x += ftxfont_draw_bitmap (f, s->gc, gcs, font, code[i], x, y,
-                                 p, 0x100, n, i + 1 == len);
+       {
+         xadvance = ftxfont_draw_bitmap (f, s->gc, gcs, font, code[i], x, y,
+                                         p, 0x100, n, i + 1 == len);
+         x += (s->padding_p ? 1 : xadvance);
+       }
       if (s->num_clips)
        for (i = 0; i < 6; i++)
          XSetClipMask (FRAME_X_DISPLAY (f), gcs[i], None);
@@ -420,8 +334,11 @@ ftxfont_draw (s, from, to, x, y, with_background)
       /* We can't draw with antialiasing.
         s->gc should already have a proper clipping setting. */
       for (i = 0; i < len; i++)
-       x += ftxfont_draw_bitmap (f, s->gc, NULL, font, code[i], x, y,
-                                 p, 0x700, n, i + 1 == len);
+       {
+         xadvance = ftxfont_draw_bitmap (f, s->gc, NULL, font, code[i], x, y,
+                                         p, 0x700, n, i + 1 == len);
+         x += (s->padding_p ? 1 : xadvance);
+       }
     }
 
   UNBLOCK_INPUT;
@@ -430,8 +347,7 @@ ftxfont_draw (s, from, to, x, y, with_background)
 }
 
 static int
-ftxfont_end_for_frame (f)
-     FRAME_PTR f;
+ftxfont_end_for_frame (FRAME_PTR f)
 {
   struct ftxfont_frame_data *data = font_get_frame_data (f, &ftxfont_driver);
   
@@ -447,13 +363,14 @@ ftxfont_end_for_frame (f)
       data = next;
     }
   UNBLOCK_INPUT;
+  font_put_frame_data (f, &ftxfont_driver, NULL);
   return 0;
 }
 
 \f
 
 void
-syms_of_ftxfont ()
+syms_of_ftxfont (void)
 {
   DEFSYM (Qftx, "ftx");