changeset 95103:974543f59c33

(cs_iso8859_1): Deleted. (ft_face_cache): New variable. (struct ftfont_info): New member fc_charset_idx; (ftfont_build_basic_charsets): Deleted. (fc_charset_table): New variable. (ftfont_pattern_entity): New arg fc_charset_idx. Store (FILENAME . FC_CHARSET_IDX) as :font-entity property in the font entity. Callers changed. (ftfont_lookup_cache, ftfont_get_charset): New funcitons. (ftfont_spec_pattern): New argument fc_charset_idx. Check registry more rigidly. Callers changed. (ftfont_open, ftfont_close, ftfont_has_char): Adjustd for the change of :font-entity property of the font.
author Kenichi Handa <handa@m17n.org>
date Mon, 19 May 2008 07:21:25 +0000
parents a3868b9c34f4
children ae4280e6a166
files src/ftfont.c
diffstat 1 files changed, 205 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/src/ftfont.c	Mon May 19 06:18:51 2008 +0000
+++ b/src/ftfont.c	Mon May 19 07:21:25 2008 +0000
@@ -51,9 +51,8 @@
 /* Cache for FreeType fonts.  */
 static Lisp_Object freetype_font_cache;
 
-/* Fontconfig's charset used for finding fonts of registry
-   "iso8859-1".  */
-static FcCharSet *cs_iso8859_1;
+/* Cache for FT_Face */
+static Lisp_Object ft_face_cache;
 
 /* The actual structure for FreeType font that can be casted to struct
    font.  */
@@ -62,71 +61,95 @@
 {
   struct font font;
   FT_Size ft_size;
+  int fc_charset_idx;
 #ifdef HAVE_LIBOTF
   int maybe_otf;	/* Flag to tell if this may be OTF or not.  */
   OTF *otf;
 #endif	/* HAVE_LIBOTF */
 };
 
-static int ftfont_build_basic_charsets P_ ((void));
-static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object));
+static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object, int));
+
 static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object));
 Lisp_Object ftfont_font_format P_ ((FcPattern *));
 
 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
 
-static int
-ftfont_build_basic_charsets ()
+static struct
 {
-  FcChar32 c;
-
-  cs_iso8859_1 = FcCharSetCreate ();
-  if (! cs_iso8859_1)
-    return -1;
-  for (c = ' '; c < 127; c++)
-    if (! FcCharSetAddChar (cs_iso8859_1, c))
-      return -1;
-#if 0
-  /* This part is currently disabled.  Should be fixed later.  */
-  for (c = 192; c < 256; c++)
-    if (! FcCharSetAddChar (cs_iso8859_1, c))
-      return -1;
-#endif
-  return 0;
-}
+  /* charset name */
+  char *name;
+  /* characters to distinguish the charset from the others */
+  int uniquifier[6];
+  /* set in syms_of_ftfont */
+  int charset_id;
+  /* set on demand */
+  FcCharSet *fc_charset;
+} fc_charset_table[] =
+  { { "iso-8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 }, -1 },
+    { "iso-8859-2", { 0x00A0, 0x010E }},
+    { "iso-8859-3", { 0x00A0, 0x0108 }},
+    { "iso-8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
+    { "iso-8859-5", { 0x00A0, 0x0401 }},
+    { "iso-8859-6", { 0x00A0, 0x060C }},
+    { "iso-8859-7", { 0x00A0, 0x0384 }},
+    { "iso-8859-8", { 0x00A0, 0x05D0 }},
+    { "iso-8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
+    { "iso-8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
+    { "iso-8859-11", { 0x00A0, 0x0E01 }},
+    { "iso-8859-13", { 0x00A0, 0x201C }},
+    { "iso-8859-14", { 0x00A0, 0x0174 }},
+    { "iso-8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
+    { "iso-8859-16", { 0x00A0, 0x0218}},
+    { "chinese-gb2312", { 0x4E13 }},
+    { "big5", { 0xF6B1 }},
+    { "japanese-jisx0208", { 0x4E55 }},
+    { "korean-ksc5601", { 0xAC00 }},
+    { "chinese-cns11643-1", { 0xFE32 }},
+    { "chinese-cns11643-2", { 0x4E33, 0x7934 }},
+    { "chinese-cns11643-3", { 0x201A9 }},
+    { "chinese-cns11643-4", { 0x20057 }},
+    { "chinese-cns11643-5", { 0x20000 }},
+    { "chinese-cns11643-6", { 0x20003 }},
+    { "chinese-cns11643-7", { 0x20055 }},
+    { "chinese-gbk", { 0x4E06 }},
+    { "japanese-jisx0212", { 0x4E44 }},
+    { "japanese-jisx0213-1", { 0xFA10 }},
+    { "japanese-jisx0213-2", { 0xFA49 }},
+    { "japanese-jisx0213.2004-1", { 0x20B9F }},
+    { "viscii", { 0x1EA0, 0x1EAE, 0x1ED2 }},
+    { "tis620", { 0x0E01 }},
+    { "windows-1251", { 0x0401, 0x0490 }},
+    { "koi8-r", { 0x0401, 0x2219 }},
+    { "mule-lao", { 0x0E81 }},
+    { NULL }
+  };
 
 extern Lisp_Object Qc, Qm, Qp, Qd;
 
 static Lisp_Object
-ftfont_pattern_entity (p, registry)
+ftfont_pattern_entity (p, registry, fc_charset_idx)
      FcPattern *p;
      Lisp_Object registry;
+     int fc_charset_idx;
 {
   Lisp_Object entity;
-  FcChar8 *file, *fontformat;
-  FcCharSet *charset;
-  FcChar8 *str;
+  char *file, *str;
   int numeric;
   double dbl;
   FcBool b;
 
-  if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch)
+  if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
     return Qnil;
-  if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) != FcResultMatch)
-    charset = NULL;
-#ifdef FC_FONTFORMAT
-  if (FcPatternGetString (p, FC_FONTFORMAT, 0, &fontformat) != FcResultMatch)
-#endif	/* FC_FONTFORMAT */
-    fontformat = NULL;
 
   entity = font_make_entity ();
 
   ASET (entity, FONT_TYPE_INDEX, Qfreetype);
   ASET (entity, FONT_REGISTRY_INDEX, registry);
 
-  if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch)
+  if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch)
     ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str)));
-  if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch)
+  if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch)
     ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str)));
   if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
     {
@@ -158,26 +181,10 @@
       && b == FcTrue)
     ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0));
 
-  file = FcStrCopy (file);
-  if (! file)
-    return Qnil;
-  p = FcPatternCreate ();
-  if (! p)
-    return Qnil;
-
-  if (FcPatternAddString (p, FC_FILE, file) == FcFalse
-      || (charset
-	  && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse)
-#ifdef FC_FONTFORMAT
-      || (fontformat
-	  && FcPatternAddString (p, FC_FONTFORMAT, fontformat) == FcFalse)
-#endif	/* FC_FONTFORMAT */
-      )
-    {
-      FcPatternDestroy (p);
-      return Qnil;
-    }
-  font_put_extra (entity, QCfont_entity, make_save_value (p, 0));
+  font_put_extra (entity, QCfont_entity,
+		  Fcons (make_unibyte_string ((char *) file,
+					      strlen ((char *) file)),
+			 make_number (fc_charset_idx)));
   return entity;
 }
 
@@ -188,12 +195,12 @@
 ftfont_list_generic_family (family)
      Lisp_Object family;
 {
-  Lisp_Object slot, list, val;
+  Lisp_Object slot, list;
   FcObjectSet *objset = NULL;
   FcPattern *pattern = NULL, *pat = NULL;
   FcFontSet *fontset = NULL;
   FcChar8 *fam;
-  int i, j;
+  int i;
 
   if (EQ (family, Qmono))
     family = Qmonospace;
@@ -243,6 +250,35 @@
   return list;
 }
 
+Lisp_Object
+ftfont_lookup_cache (filename)
+     Lisp_Object filename;
+{
+  Lisp_Object cache, val;
+
+  cache = assoc_no_quit (filename, ft_face_cache);
+  if (NILP (cache))
+    {
+      val = make_save_value (NULL, 0);
+      cache = Fcons (filename, val);
+      ft_face_cache = Fcons (cache, ft_face_cache);
+    }
+  else
+    val = XCDR (cache);
+  if (! XSAVE_VALUE (val)->pointer)
+    {
+      FT_Face ft_face;
+
+      if (! ft_library
+	  && FT_Init_FreeType (&ft_library) != 0)
+	return Qnil;
+      if (FT_New_Face (ft_library, (char *) SDATA (filename), 0, &ft_face) != 0)
+	return Qnil;
+      XSAVE_VALUE (val)->pointer = ft_face;
+    }
+  return cache;
+}
+
 static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR));
 static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object));
@@ -303,6 +339,50 @@
   return freetype_font_cache;
 }
 
+static int
+ftfont_get_charset (registry)
+     Lisp_Object registry;
+{
+  struct charset *encoding;
+  int i, j;
+
+  if (font_registry_charsets (registry, &encoding, NULL) < 0)
+    return -1;
+  if (fc_charset_table[0].charset_id < 0)
+    /* Setup charset_id field of all elements.  */
+    for (i = 0; fc_charset_table[i].name; i++)
+      {
+	Lisp_Object sym = intern (fc_charset_table[i].name);
+
+	if (CHARSETP (sym))
+	  fc_charset_table[i].charset_id = XINT (CHARSET_SYMBOL_ID (sym));
+	else
+	  fc_charset_table[i].charset_id = -1;
+      }
+
+  for (i = 0; fc_charset_table[i].name; i++)
+    if (encoding->id == fc_charset_table[i].charset_id)
+      break;
+  if (! fc_charset_table[i].name)
+    return -1;
+  if (! fc_charset_table[i].fc_charset)
+    {
+      FcCharSet *charset = FcCharSetCreate ();
+      int *uniquifier = fc_charset_table[i].uniquifier;
+
+      if (! charset)
+	return -1;
+      for (j = 0; uniquifier[j]; j++)
+	if (! FcCharSetAddChar (charset, uniquifier[j]))
+	  {
+	    FcCharSetDestroy (charset);
+	    return -1;
+	  }
+      fc_charset_table[i].fc_charset = charset;      
+    }
+  return i;
+}
+
 struct OpenTypeSpec
 {
   Lisp_Object script;
@@ -390,14 +470,17 @@
   return spec;
 }
 
+static FcPattern *ftfont_spec_pattern P_ ((Lisp_Object, int *, char *,
+					   struct OpenTypeSpec **));
+
 static FcPattern *
-ftfont_spec_pattern (spec, otlayout, otspec)
+ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec)
      Lisp_Object spec;
+     int *fc_charset_idx;
      char *otlayout;
      struct OpenTypeSpec **otspec;
 {
-  Lisp_Object val, tmp, extra;
-  int i;
+  Lisp_Object tmp, extra;
   FcPattern *pattern = NULL;
   FcCharSet *charset = NULL;
   FcLangSet *langset = NULL;
@@ -407,7 +490,7 @@
   int scalable = -1;
   Lisp_Object name = Qnil;
   Lisp_Object script = Qnil;
-  Lisp_Object registry = Qunicode_bmp;
+  Lisp_Object registry;
 
   if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))
       && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0)
@@ -426,20 +509,18 @@
       && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0)
     scalable = 1;
 
-  if (! NILP (AREF (spec, FONT_REGISTRY_INDEX)))
+  registry = AREF (spec, FONT_REGISTRY_INDEX);
+  if (NILP (registry)
+      || EQ (registry, Qiso10646_1)
+      || EQ (registry, Qunicode_bmp)
+      || EQ (registry, Qunicode_sip))
+    *fc_charset_idx = -1;
+  else
     {
-      registry = AREF (spec, FONT_REGISTRY_INDEX);
-      if (EQ (registry, Qiso8859_1))
-	{
-	  if (! cs_iso8859_1
-	      && ftfont_build_basic_charsets () < 0)
-	    return NULL;
-	  charset = cs_iso8859_1;
-	}
-      else if (! EQ (registry, Qiso10646_1)
-	       && ! EQ (registry, Qunicode_bmp)
-	       && ! EQ (registry, Qunicode_sip))
+      *fc_charset_idx = ftfont_get_charset (registry);
+      if (*fc_charset_idx < 0)
 	return NULL;
+      charset = fc_charset_table[*fc_charset_idx].fc_charset;
     }
 
   otlayout[0] = '\0';
@@ -547,7 +628,6 @@
     }
 
  finish:
-  if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset);
   if (langset) FcLangSetDestroy (langset);
   return pattern;
 }
@@ -556,16 +636,12 @@
 ftfont_list (frame, spec)
      Lisp_Object frame, spec;
 {
-  Lisp_Object val, tmp, registry, family, family_list;
+  Lisp_Object val, registry, family, family_list;
   int i;
   FcPattern *pattern;
   FcFontSet *fontset = NULL;
   FcObjectSet *objset = NULL;
-  double pixel_size = 0;
-  int weight = -1, slant = -1, width = -1;
-  double dpi = -1;
-  int spacing = -1;
-  int scalable = -1;
+  int fc_charset_idx;
   char otlayout[15];		/* For "otlayout:XXXX" */
   struct OpenTypeSpec *otspec = NULL;
   
@@ -575,7 +651,7 @@
       fc_initialized = 1;
     }
 
-  pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
+  pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec);
   if (! pattern)
     return Qnil;
   objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
@@ -584,9 +660,6 @@
 #ifdef FC_CAPABILITY
 			     FC_CAPABILITY,
 #endif	/* FC_CAPABILITY */
-#ifdef FC_FONTFORMAT
-			     FC_FONTFORMAT,
-#endif	/* FC_FONTFORMAT */
 			     NULL);
   if (! objset)
     goto err;
@@ -618,8 +691,6 @@
       for (i = 0; i < fontset->nfont; i++)
 	{
 	  Lisp_Object entity;
-	  int n;
-	  double dbl;
 
 #ifdef FC_CAPABILITY
 	  if (otlayout[0])
@@ -655,7 +726,8 @@
 		continue;
 	    }
 #endif	/* HAVE_LIBOTF */
-	  entity = ftfont_pattern_entity (fontset->fonts[i], registry);
+	  entity = ftfont_pattern_entity (fontset->fonts[i], registry,
+					  fc_charset_idx);
 	  if (! NILP (entity))
 	    val = Fcons (entity, val);
 	}
@@ -680,11 +752,12 @@
 ftfont_match (frame, spec)
      Lisp_Object frame, spec;
 {
-  Lisp_Object extra, val, entity;
+  Lisp_Object entity;
   FcPattern *pattern, *match = NULL;
   FcResult result;
   char otlayout[15];		/* For "otlayout:XXXX" */
   struct OpenTypeSpec *otspec = NULL;
+  int fc_charset_idx;
 
   if (! fc_initialized)
     {
@@ -692,7 +765,7 @@
       fc_initialized = 1;
     }
 
-  pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
+  pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec);
   if (! pattern)
     return Qnil;
 
@@ -710,7 +783,7 @@
       match = FcFontMatch (NULL, pattern, &result);
       if (match)
 	{
-	  entity = ftfont_pattern_entity (match, Qunicode_bmp);
+	  entity = ftfont_pattern_entity (match, Qunicode_bmp, fc_charset_idx);
 	  FcPatternDestroy (match);
 	  if (! NILP (AREF (spec, FONT_FAMILY_INDEX))
 	      && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX),
@@ -781,10 +854,10 @@
   FT_Face ft_face;
   FT_Size ft_size;
   FT_UInt size;
-  Lisp_Object val, font_object;
+  Lisp_Object val, filename, cache, font_object;
+  int fc_charset_idx;
   FcPattern *pattern;
-  FcChar8 *file = NULL, *fmt = NULL;
-  FcBool scalable;
+  int scalable;
   int spacing;
   char name[256];
   int i, len;
@@ -794,26 +867,17 @@
   if (! CONSP (val))
     return Qnil;
   val = XCDR (val);
-  pattern = XSAVE_VALUE (val)->pointer;
-  if (XSAVE_VALUE (val)->integer == 0)
+  filename = XCAR (val);
+  fc_charset_idx = XINT (XCDR (val));
+  cache = ftfont_lookup_cache (filename);
+  if (NILP (cache))
+    return Qnil;
+  filename = XCAR (cache);
+  val = XCDR (cache);
+  ft_face = XSAVE_VALUE (val)->pointer;
+  if (XSAVE_VALUE (val)->integer > 0)
     {
-      /* We have not yet created FT_Face for this font.  */
-      if (! ft_library
-	  && FT_Init_FreeType (&ft_library) != 0)
-	return Qnil;
-      if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
-	return Qnil;
-      if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0)
-	return Qnil;
-      FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face);
-      ft_size = ft_face->size;
-      XSAVE_VALUE (val)->integer++;
-    }
-  else
-    {
-      if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face)
-	  != FcResultMatch)
-	return Qnil;
+      /* FT_Face in this cache is already used by the different size.  */
       if (FT_New_Size (ft_face, &ft_size) != 0)
 	return Qnil;
       if (FT_Activate_Size (ft_size) != 0)
@@ -821,8 +885,8 @@
 	  FT_Done_Size (ft_size);
 	  return Qnil;
 	}
-    } 
-
+    }
+  XSAVE_VALUE (val)->integer++;
   size = XINT (AREF (entity, FONT_SIZE_INDEX));
   if (size == 0)
     size = pixel_size;
@@ -847,15 +911,12 @@
   else
     ASET (font_object, FONT_FULLNAME_INDEX,
 	  AREF (font_object, FONT_NAME_INDEX));
-  if (! file
-      && ! FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
-    return Qnil;
-  ASET (font_object, FONT_FILE_INDEX,
-	make_unibyte_string ((char *) file, strlen ((char *) file)));
+  ASET (font_object, FONT_FILE_INDEX, filename);
   ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern));
   font = XFONT_OBJECT (font_object);
   ftfont_info = (struct ftfont_info *) font;
-  ftfont_info->ft_size = ft_size;
+  ftfont_info->ft_size = ft_face->size;
+  ftfont_info->fc_charset_idx = fc_charset_idx;
 #ifdef HAVE_LIBOTF
   ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
   ftfont_info->otf = NULL;
@@ -865,8 +926,8 @@
   font->encoding_charset = font->repertory_charset = -1;
 
   upEM = ft_face->units_per_EM;
-  if (! FcPatternGetBool (pattern, FC_SCALABLE, 0, &scalable) == FcResultMatch)
-    scalable = FcFalse;
+  scalable = (INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+	      && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0);
   if (scalable)
     {
       font->ascent = ft_face->ascender * size / upEM;
@@ -879,7 +940,9 @@
       font->descent = - ft_face->size->metrics.descender >> 6;
       font->height = ft_face->size->metrics.height >> 6;
     }
-  if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch)
+  if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)))
+    spacing = XINT (AREF (entity, FONT_SPACING_INDEX));
+  else
     spacing = FC_PROPORTIONAL;
   if (spacing != FC_PROPORTIONAL)
     font->min_width = font->average_width = font->space_width
@@ -931,18 +994,21 @@
      struct font *font;
 {
   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
-  Lisp_Object val;
+  Lisp_Object val, cache;
 
-  val = assq_no_quit (QCfont_entity, font->props[FONT_EXTRA_INDEX]);
-  val = XCDR (val);
+  cache = ftfont_lookup_cache (font->props[FONT_FILE_INDEX]);
+  val = XCDR (cache);
   (XSAVE_VALUE (val)->integer)--;
   if (XSAVE_VALUE (val)->integer == 0)
     {
-      FT_Done_Face (ftfont_info->ft_size->face);
+      FT_Face ft_face = XSAVE_VALUE (val)->pointer;
+
+      FT_Done_Face (ft_face);
 #ifdef HAVE_LIBOTF
       if (ftfont_info->otf)
 	OTF_close (ftfont_info->otf);
 #endif
+      XSAVE_VALUE (val)->pointer = NULL;
     }
   else
     FT_Done_Size (ftfont_info->ft_size);
@@ -954,15 +1020,15 @@
      int c;
 {
   Lisp_Object val;
-  FcPattern *pattern;
-  FcCharSet *charset;
+  int fc_charset_idx;
+  struct charset *charset;
 
   val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
-  val = XCDR (val);
-  pattern = XSAVE_VALUE (val)->pointer;
-  if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
+  fc_charset_idx = XINT (XCDR (XCDR (val)));
+  if (fc_charset_idx < 0)
     return -1;
-  return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue);
+  charset = CHARSET_FROM_ID (fc_charset_table[fc_charset_idx].charset_id);
+  return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset));
 }
 
 static unsigned
@@ -1316,7 +1382,6 @@
 	return -2;
       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
 	{
-	  OTF_Glyph *endg;
 	  MFLTGlyph *g;
 	  int min_from, max_to;
 	  int j;
@@ -1550,7 +1615,8 @@
     if (NILP (family))
       flt_font_ft.flt_font.family = Mnil;
     else
-      flt_font_ft.flt_font.family = msymbol (SDATA (SYMBOL_NAME (family)));
+      flt_font_ft.flt_font.family
+	= msymbol ((char *) SDATA (SYMBOL_NAME (family)));
   }
   flt_font_ft.flt_font.x_ppem = ft_face->size->metrics.x_ppem;
   flt_font_ft.flt_font.y_ppem = ft_face->size->metrics.y_ppem;
@@ -1699,6 +1765,9 @@
 	     Fcons (Fcons (Qsans_serif, Qt),
 		    Fcons (Fcons (Qsans, Qt), Qnil)));
 
+  staticpro (&ft_face_cache);
+  ft_face_cache = Qnil;
+
   ftfont_driver.type = Qfreetype;
   register_font_driver (&ftfont_driver, NULL);
 }