use guile conses
[bpt/emacs.git] / src / ftfont.c
index e16f967..bea1e01 100644 (file)
@@ -1,5 +1,5 @@
 /* ftfont.c -- FreeType font driver.
-   Copyright (C) 2006-2012 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 Free Software Foundation, Inc.
    Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
@@ -21,8 +21,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <setjmp.h>
-
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
 
@@ -45,7 +43,7 @@ static Lisp_Object Qfreetype;
 static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
 
 /* Flag to tell if FcInit is already called or not.  */
-static int fc_initialized;
+static bool fc_initialized;
 
 /* Handle to a FreeType library instance.  */
 static FT_Library ft_library;
@@ -56,7 +54,7 @@ static Lisp_Object freetype_font_cache;
 /* Cache for FT_Face and FcCharSet. */
 static Lisp_Object ft_face_cache;
 
-/* The actual structure for FreeType font that can be casted to struct
+/* The actual structure for FreeType font that can be cast to struct
    font.  */
 
 struct ftfont_info
@@ -65,7 +63,7 @@ struct ftfont_info
 #ifdef HAVE_LIBOTF
   /* The following four members must be here in this order to be
      compatible with struct xftfont_info (in xftfont.c).  */
-  int maybe_otf;       /* Flag to tell if this may be OTF or not.  */
+  bool maybe_otf;      /* Flag to tell if this may be OTF or not.  */
   OTF *otf;
 #endif /* HAVE_LIBOTF */
   FT_Size ft_size;
@@ -89,8 +87,6 @@ static Lisp_Object ftfont_lookup_cache (Lisp_Object,
 
 static void ftfont_filter_properties (Lisp_Object font, Lisp_Object alist);
 
-Lisp_Object ftfont_font_format (FcPattern *, Lisp_Object);
-
 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
 
 static struct
@@ -395,16 +391,14 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
       cache_data = xmalloc (sizeof *cache_data);
       cache_data->ft_face = NULL;
       cache_data->fc_charset = NULL;
-      val = make_save_value (NULL, 0);
-      XSAVE_VALUE (val)->integer = 0;
-      XSAVE_VALUE (val)->pointer = cache_data;
+      val = make_save_ptr_int (cache_data, 0);
       cache = Fcons (Qnil, val);
       Fputhash (key, cache, ft_face_cache);
     }
   else
     {
       val = XCDR (cache);
-      cache_data = XSAVE_VALUE (val)->pointer;
+      cache_data = XSAVE_POINTER (val, 0);
     }
 
   if (cache_for == FTFONT_CACHE_FOR_ENTITY)
@@ -470,7 +464,7 @@ ftfont_get_fc_charset (Lisp_Object entity)
 
   cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET);
   val = XCDR (cache);
-  cache_data = XSAVE_VALUE (val)->pointer;
+  cache_data = XSAVE_POINTER (val, 0);
   return cache_data->fc_charset;
 }
 
@@ -497,12 +491,12 @@ ftfont_get_otf (struct ftfont_info *ftfont_info)
 }
 #endif /* HAVE_LIBOTF */
 
-static Lisp_Object ftfont_get_cache (FRAME_PTR);
-static Lisp_Object ftfont_list (Lisp_Object, Lisp_Object);
-static Lisp_Object ftfont_match (Lisp_Object, Lisp_Object);
-static Lisp_Object ftfont_list_family (Lisp_Object);
-static Lisp_Object ftfont_open (FRAME_PTR, Lisp_Object, int);
-static void ftfont_close (FRAME_PTR, struct font *);
+static Lisp_Object ftfont_get_cache (struct frame *);
+static Lisp_Object ftfont_list (struct frame *, Lisp_Object);
+static Lisp_Object ftfont_match (struct frame *, Lisp_Object);
+static Lisp_Object ftfont_list_family (struct frame *);
+static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
+static void ftfont_close (struct font *);
 static int ftfont_has_char (Lisp_Object, int);
 static unsigned ftfont_encode_char (struct font *, int);
 static int ftfont_text_extents (struct font *, unsigned *, int,
@@ -543,9 +537,9 @@ struct font_driver ftfont_driver =
     /* We can't draw a text without device dependent functions.  */
     NULL,                      /* draw */
     ftfont_get_bitmap,
-    NULL,                      /* get_bitmap */
     NULL,                      /* free_bitmap */
     NULL,                      /* get_outline */
+    NULL,                      /* free_outline */
     ftfont_anchor_point,
 #ifdef HAVE_LIBOTF
     ftfont_otf_capability,
@@ -572,7 +566,7 @@ struct font_driver ftfont_driver =
   };
 
 static Lisp_Object
-ftfont_get_cache (FRAME_PTR f)
+ftfont_get_cache (struct frame *f)
 {
   return freetype_font_cache;
 }
@@ -659,9 +653,10 @@ struct OpenTypeSpec
 static struct OpenTypeSpec *
 ftfont_get_open_type_spec (Lisp_Object otf_spec)
 {
-  struct OpenTypeSpec *spec = malloc (sizeof *spec);
+  struct OpenTypeSpec *spec = xmalloc_unsafe (sizeof *spec);
   Lisp_Object val;
-  int i, j, negative;
+  int i, j;
+  bool negative;
 
   if (! spec)
     return NULL;
@@ -698,12 +693,12 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec)
       spec->features[i] =
        (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len)
         ? 0
-        : malloc (XINT (len) * sizeof *spec->features[i]));
+        : xmalloc_atomic_unsafe (XINT (len) * sizeof *spec->features[i]));
       if (! spec->features[i])
        {
          if (i > 0 && spec->features[0])
-           free (spec->features[0]);
-         free (spec);
+           xfree (spec->features[0]);
+         xfree (spec);
          return NULL;
        }
       for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
@@ -873,10 +868,10 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
   if (*otspec)
     {
       if ((*otspec)->nfeatures[0] > 0)
-       free ((*otspec)->features[0]);
+       xfree ((*otspec)->features[0]);
       if ((*otspec)->nfeatures[1] > 0)
-       free ((*otspec)->features[1]);
-      free (*otspec);
+       xfree ((*otspec)->features[1]);
+      xfree (*otspec);
       *otspec = NULL;
     }
 
@@ -887,7 +882,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
 }
 
 static Lisp_Object
-ftfont_list (Lisp_Object frame, Lisp_Object spec)
+ftfont_list (struct frame *f, Lisp_Object spec)
 {
   Lisp_Object val = Qnil, family, adstyle;
   int i;
@@ -1014,6 +1009,7 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec)
       if (otspec)
        {
          FcChar8 *file;
+         bool passed;
          OTF *otf;
 
          if (FcPatternGetString (fontset->fonts[i], FC_FILE, 0, &file)
@@ -1022,14 +1018,16 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec)
          otf = OTF_open ((char *) file);
          if (! otf)
            continue;
-         if (OTF_check_features (otf, 1,
-                                 otspec->script_tag, otspec->langsys_tag,
-                                 otspec->features[0],
-                                 otspec->nfeatures[0]) != 1
-             || OTF_check_features (otf, 0,
-                                    otspec->script_tag, otspec->langsys_tag,
-                                    otspec->features[1],
-                                    otspec->nfeatures[1]) != 1)
+         passed = (OTF_check_features (otf, 1, otspec->script_tag,
+                                       otspec->langsys_tag,
+                                       otspec->features[0],
+                                       otspec->nfeatures[0]) == 1
+                   && OTF_check_features (otf, 0, otspec->script_tag,
+                                          otspec->langsys_tag,
+                                          otspec->features[1],
+                                          otspec->nfeatures[1]) == 1);
+         OTF_close (otf);
+         if (!passed)
            continue;
        }
 #endif /* HAVE_LIBOTF */
@@ -1083,7 +1081,7 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec)
 }
 
 static Lisp_Object
-ftfont_match (Lisp_Object frame, Lisp_Object spec)
+ftfont_match (struct frame *f, Lisp_Object spec)
 {
   Lisp_Object entity = Qnil;
   FcPattern *pattern, *match = NULL;
@@ -1133,7 +1131,7 @@ ftfont_match (Lisp_Object frame, Lisp_Object spec)
 }
 
 static Lisp_Object
-ftfont_list_family (Lisp_Object frame)
+ftfont_list_family (struct frame *f)
 {
   Lisp_Object list = Qnil;
   FcPattern *pattern = NULL;
@@ -1176,7 +1174,7 @@ ftfont_list_family (Lisp_Object frame)
 
 
 static Lisp_Object
-ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
 {
   struct ftfont_info *ftfont_info;
   struct font *font;
@@ -1185,7 +1183,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   FT_Size ft_size;
   FT_UInt size;
   Lisp_Object val, filename, idx, cache, font_object;
-  int scalable;
+  bool scalable;
   int spacing;
   char name[256];
   int i, len;
@@ -1201,9 +1199,9 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   filename = XCAR (val);
   idx = XCDR (val);
   val = XCDR (cache);
-  cache_data = XSAVE_VALUE (XCDR (cache))->pointer;
+  cache_data = XSAVE_POINTER (XCDR (cache), 0);
   ft_face = cache_data->ft_face;
-  if (XSAVE_VALUE (val)->integer > 0)
+  if (XSAVE_INTEGER (val, 1) > 0)
     {
       /* FT_Face in this cache is already used by the different size.  */
       if (FT_New_Size (ft_face, &ft_size) != 0)
@@ -1214,13 +1212,13 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
          return Qnil;
        }
     }
-  XSAVE_VALUE (val)->integer++;
+  set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1);
   size = XINT (AREF (entity, FONT_SIZE_INDEX));
   if (size == 0)
     size = pixel_size;
   if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
     {
-      if (XSAVE_VALUE (val)->integer == 0)
+      if (XSAVE_INTEGER (val, 1) == 0)
        FT_Done_Face (ft_face);
       return Qnil;
     }
@@ -1243,7 +1241,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   ftfont_info->ft_size = ft_face->size;
   ftfont_info->index = XINT (idx);
 #ifdef HAVE_LIBOTF
-  ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
+  ftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
   ftfont_info->otf = NULL;
 #endif /* HAVE_LIBOTF */
   /* This means that there's no need of transformation.  */
@@ -1320,7 +1318,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
 }
 
 static void
-ftfont_close (FRAME_PTR f, struct font *font)
+ftfont_close (struct font *font)
 {
   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
   Lisp_Object val, cache;
@@ -1329,10 +1327,10 @@ ftfont_close (FRAME_PTR f, struct font *font)
   cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
   eassert (CONSP (cache));
   val = XCDR (cache);
-  (XSAVE_VALUE (val)->integer)--;
-  if (XSAVE_VALUE (val)->integer == 0)
+  set_save_integer (val, 1, XSAVE_INTEGER (val, 1) - 1);
+  if (XSAVE_INTEGER (val, 1) == 0)
     {
-      struct ftfont_cache_data *cache_data = XSAVE_VALUE (val)->pointer;
+      struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0);
 
       FT_Done_Face (cache_data->ft_face);
 #ifdef HAVE_LIBOTF
@@ -1392,7 +1390,8 @@ ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
   FT_Face ft_face = ftfont_info->ft_size->face;
   int width = 0;
-  int i, first;
+  int i;
+  bool first;
 
   if (ftfont_info->ft_size != ft_face->size)
     FT_Activate_Size (ftfont_info->ft_size);
@@ -1480,7 +1479,6 @@ ftfont_get_bitmap (struct font *font, unsigned int code, struct font_bitmap *bit
   bitmap->left = ft_face->glyph->bitmap_left;
   bitmap->top = ft_face->glyph->bitmap_top;
   bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6;
-  bitmap->extra = NULL;
 
   return 0;
 }
@@ -1630,7 +1628,7 @@ ftfont_get_metrics (MFLTFont *font, MFLTGlyphString *gstring,
            FT_Glyph_Metrics *m;
 
            if (FT_Load_Glyph (ft_face, g->code, FT_LOAD_DEFAULT) != 0)
-             abort ();
+             emacs_abort ();
            m = &ft_face->glyph->metrics;
            if (flt_font_ft->matrix)
              {
@@ -1682,10 +1680,12 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
   OTF *otf = flt_font_ft->otf;
   OTF_Tag *tags;
-  int i, n, negative;
+  int i, n;
+  bool negative;
 
   if (FEATURE_ANY (0) && FEATURE_ANY (1))
-    /* Return 1 iff any of GSUB or GPOS support the script (and language).  */
+    /* Return true iff any of GSUB or GPOS support the script (and
+       language).  */
     return (otf
            && (OTF_check_features (otf, 0, spec->script, spec->langsys,
                                    NULL, 0) > 0
@@ -2390,7 +2390,7 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
 
 static MFLTGlyphString gstring;
 
-static int m17n_flt_initialized;
+static bool m17n_flt_initialized;
 
 static Lisp_Object
 ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
@@ -2400,7 +2400,7 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
   ptrdiff_t i;
   struct MFLTFontFT flt_font_ft;
   MFLT *flt = NULL;
-  int with_variation_selector = 0;
+  bool with_variation_selector = 0;
 
   if (! m17n_flt_initialized)
     {
@@ -2421,11 +2421,10 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
        break;
       c = LGLYPH_CHAR (g);
       if (CHAR_VARIATION_SELECTOR_P (c))
-       with_variation_selector++;
+       with_variation_selector = 1;
     }
 
   len = i;
-  lint_assume (len <= STRING_BYTES_BOUND);
 
   if (with_variation_selector)
     {
@@ -2541,7 +2540,7 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
 
       if (NILP (lglyph))
        {
-         lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil);
+         lglyph = LGLYPH_NEW ();
          LGSTRING_SET_GLYPH (lgstring, i, lglyph);
        }
       LGLYPH_SET_FROM (lglyph, g->from);
@@ -2555,9 +2554,8 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
       LGLYPH_SET_DESCENT (lglyph, g->descent >> 6);
       if (g->adjusted)
        {
-         Lisp_Object vec;
+         Lisp_Object vec = make_uninit_vector (3);
 
-         vec = Fmake_vector (make_number (3), Qnil);
          ASET (vec, 0, make_number (g->xoff >> 6));
          ASET (vec, 1, make_number (g->yoff >> 6));
          ASET (vec, 2, make_number (g->xadv >> 6));
@@ -2704,13 +2702,12 @@ syms_of_ftfont (void)
   DEFSYM (Qsans__serif, "sans serif");
 
   staticpro (&freetype_font_cache);
-  freetype_font_cache = Fcons (Qt, Qnil);
+  freetype_font_cache = list1 (Qt);
 
   staticpro (&ftfont_generic_family_list);
-  ftfont_generic_family_list
-    = Fcons (Fcons (Qmonospace, Qt),
-            Fcons (Fcons (Qsans_serif, Qt),
-                   Fcons (Fcons (Qsans, Qt), Qnil)));
+  ftfont_generic_family_list = list3 (Fcons (Qmonospace, Qt),
+                                     Fcons (Qsans_serif, Qt),
+                                     Fcons (Qsans, Qt));
 
   staticpro (&ft_face_cache);
   ft_face_cache = Qnil;