Merge from trunk.
[bpt/emacs.git] / src / font.c
index a5b873a..16d09af 100644 (file)
@@ -1,6 +1,6 @@
 /* font.c -- "Font" primitives.
 
-Copyright (C) 2006-2011  Free Software Foundation, Inc.
+Copyright (C) 2006-2012  Free Software Foundation, Inc.
 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
   National Institute of Advanced Industrial Science and Technology (AIST)
   Registration Number H13PRO009
@@ -162,7 +162,7 @@ static struct font_driver_list *font_driver_list;
 
 \f
 
-/* Creaters of font-related Lisp object.  */
+/* Creators of font-related Lisp object.  */
 
 static Lisp_Object
 font_make_spec (void)
@@ -238,7 +238,7 @@ font_intern_prop (const char *str, ptrdiff_t len, int force_symbol)
   ptrdiff_t i;
   Lisp_Object tem;
   Lisp_Object obarray;
-  EMACS_INT nbytes, nchars;
+  ptrdiff_t nbytes, nchars;
 
   if (len == 1 && *str == '*')
     return Qnil;
@@ -364,7 +364,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
   else
     {
       int i, last_n;
-      int numeric = XINT (val);
+      EMACS_INT numeric = XINT (val);
 
       for (i = 0, last_n = -1; i < len; i++)
        {
@@ -518,7 +518,7 @@ font_prop_validate_style (Lisp_Object style, Lisp_Object val)
                                   : FONT_WIDTH_INDEX);
   if (INTEGERP (val))
     {
-      int n = XINT (val);
+      EMACS_INT n = XINT (val);
       if (((n >> 4) & 0xF)
          >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX)))
        val = Qerror;
@@ -614,7 +614,7 @@ static const struct
   /* Function to validate PROP's value VAL, or NULL if any value is
      ok.  The value is VAL or its regularized value if VAL is valid,
      and Qerror if not.  */
-  Lisp_Object (*validater) (Lisp_Object prop, Lisp_Object val);
+  Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val);
 } font_property_table[] =
   { { &QCtype, font_prop_validate_symbol },
     { &QCfoundry, font_prop_validate_symbol },
@@ -672,7 +672,7 @@ font_prop_validate (int idx, Lisp_Object prop, Lisp_Object val)
       if (idx < 0)
        return val;
     }
-  validated = (font_property_table[idx].validater) (prop, val);
+  validated = (font_property_table[idx].validator) (prop, val);
   if (EQ (validated, Qerror))
     signal_error ("invalid font property", Fcons (prop, val));
   return validated;
@@ -802,7 +802,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
   struct {
     /* Minimum possible field.  */
     int from;
-    /* Maxinum possible field.  */
+    /* Maximum possible field.  */
     int to;
     /* Bit mask of possible field.  Nth bit corresponds to Nth field.  */
     int mask;
@@ -825,7 +825,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
     range_mask = (range_mask << 1) | 1;
 
   /* The triplet RANGE_FROM, RANGE_TO, and RANGE_MASK is a
-     position-based retriction for FIELD[I].  */
+     position-based restriction for FIELD[I].  */
   for (i = 0, range_from = 0, range_to = 14 - n; i < n;
        i++, range_from++, range_to++, range_mask <<= 1)
     {
@@ -842,13 +842,13 @@ font_expand_wildcards (Lisp_Object *field, int n)
       else
        {
          /* The triplet FROM, TO, and MASK is a value-based
-            retriction for FIELD[I].  */
+            restriction for FIELD[I].  */
          int from, to;
          unsigned mask;
 
          if (INTEGERP (val))
            {
-             int numeric = XINT (val);
+             EMACS_INT numeric = XINT (val);
 
              if (i + 1 == n)
                from = to = XLFD_ENCODING_INDEX,
@@ -954,7 +954,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
        }
     }
 
-  /* Decide all fileds from restrictions in RANGE.  */
+  /* Decide all fields from restrictions in RANGE.  */
   for (i = j = 0; i < n ; i++)
     {
       if (j < range[i].from)
@@ -1285,14 +1285,14 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
     }
   else
     f[XLFD_AVGWIDTH_INDEX] = "*";
-  len = esnprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
-                  f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
-                  f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
-                  f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
-                  f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
-                  f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
-                  f[XLFD_REGISTRY_INDEX]);
-  return len == nbytes - 1 ? -1 : len;
+  len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
+                 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
+                 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
+                 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
+                 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
+                 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
+                 f[XLFD_REGISTRY_INDEX]);
+  return len < nbytes ? len : -1;
 }
 
 /* Parse NAME (null terminated) and store information in FONT
@@ -1334,7 +1334,7 @@ font_parse_fcname (char *name, Lisp_Object font)
        {
          int decimal = 0, size_found = 1;
          for (q = p + 1; *q && *q != ':'; q++)
-           if (! isdigit(*q))
+           if (! isdigit (*q))
              {
                if (*q != '.' || decimal)
                  {
@@ -1593,31 +1593,75 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
   p = name;
   lim = name + nbytes;
   if (! NILP (family))
-    p += esnprintf (p, lim - p, "%s", SSDATA (family));
+    {
+      int len = snprintf (p, lim - p, "%s", SSDATA (family));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   if (point_size > 0)
-    p += esnprintf (p, lim - p, "-%d" + (p == name), point_size);
+    {
+      int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   else if (pixel_size > 0)
-    p += esnprintf (p, lim - p, ":pixelsize=%d", pixel_size);
+    {
+      int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size);
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
-    p += esnprintf (p, lim - p, ":foundry=%s",
-                   SSDATA (SYMBOL_NAME (AREF (font,
-                                              FONT_FOUNDRY_INDEX))));
+    {
+      int len = snprintf (p, lim - p, ":foundry=%s",
+                         SSDATA (SYMBOL_NAME (AREF (font,
+                                                    FONT_FOUNDRY_INDEX))));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   for (i = 0; i < 3; i++)
     if (! NILP (styles[i]))
-      p += esnprintf (p, lim - p, ":%s=%s", style_names[i],
-                     SSDATA (SYMBOL_NAME (styles[i])));
+      {
+       int len = snprintf (p, lim - p, ":%s=%s", style_names[i],
+                           SSDATA (SYMBOL_NAME (styles[i])));
+       if (! (0 <= len && len < lim - p))
+         return -1;
+       p += len;
+      }
+
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
-    p += esnprintf (p, lim - p, ":dpi=%"pI"d",
-                   XINT (AREF (font, FONT_DPI_INDEX)));
+    {
+      int len = snprintf (p, lim - p, ":dpi=%"pI"d",
+                         XINT (AREF (font, FONT_DPI_INDEX)));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
+
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
-    p += esnprintf (p, lim - p, ":spacing=%"pI"d",
-                   XINT (AREF (font, FONT_SPACING_INDEX)));
+    {
+      int len = snprintf (p, lim - p, ":spacing=%"pI"d",
+                         XINT (AREF (font, FONT_SPACING_INDEX)));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
+
   if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
-    p += esnprintf (p, lim - p,
-                   (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
-                    ? ":scalable=true"
-                    : ":scalable=false"));
-  return lim - p == 1 ? -1 : p - name;
+    {
+      int len = snprintf (p, lim - p,
+                         (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
+                          ? ":scalable=true"
+                          : ":scalable=false"));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
+
+  return (p - name);
 }
 
 /* Parse NAME (null terminated) and store information in FONT
@@ -1696,7 +1740,8 @@ static int
 check_gstring (Lisp_Object gstring)
 {
   Lisp_Object val;
-  int i, j;
+  ptrdiff_t i;
+  int j;
 
   CHECK_VECTOR (gstring);
   val = AREF (gstring, 0);
@@ -2389,7 +2434,7 @@ font_match_p (Lisp_Object spec, Lisp_Object font)
                  /* All characters in the list must be supported.  */
                  for (; CONSP (val2); val2 = XCDR (val2))
                    {
-                     if (! NATNUMP (XCAR (val2)))
+                     if (! CHARACTERP (XCAR (val2)))
                        continue;
                      if (font_encode_char (font, XFASTINT (XCAR (val2)))
                          == FONT_INVALID_CODE)
@@ -2401,7 +2446,7 @@ font_match_p (Lisp_Object spec, Lisp_Object font)
                  /* At most one character in the vector must be supported.  */
                  for (i = 0; i < ASIZE (val2); i++)
                    {
-                     if (! NATNUMP (AREF (val2, i)))
+                     if (! CHARACTERP (AREF (val2, i)))
                        continue;
                      if (font_encode_char (font, XFASTINT (AREF (val2, i)))
                          != FONT_INVALID_CODE)
@@ -3032,6 +3077,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   Lisp_Object foundry[3], *family, registry[3], adstyle[3];
   int pixel_size;
   int i, j, k, l;
+  USE_SAFE_ALLOCA;
 
   registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
   if (NILP (registry[0]))
@@ -3116,18 +3162,12 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   else
     {
       Lisp_Object alters
-       = Fassoc_string (val, Vface_alternative_font_family_alist,
-                         /* Font family names are case-sensitive under NS. */
-#ifndef HAVE_NS
-                        Qt
-#else
-                        Qnil
-#endif
-                        );
+       = Fassoc_string (val, Vface_alternative_font_family_alist, Qt);
 
       if (! NILP (alters))
        {
-         family = alloca ((sizeof family[0]) * (XINT (Flength (alters)) + 2));
+         EMACS_INT alterslen = XFASTINT (Flength (alters));
+         SAFE_ALLOCA_LISP (family, alterslen + 2);
          for (i = 0; CONSP (alters); i++, alters = XCDR (alters))
            family[i] = XCAR (alters);
          if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
@@ -3169,6 +3209,8 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
            }
        }
     }
+
+  SAFE_FREE ();
   return Qnil;
 }
 
@@ -3195,7 +3237,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
          if (INTEGERP (height))
            pt = XINT (height);
          else
-           abort(); /* We should never end up here.  */
+           abort (); /* We should never end up here.  */
        }
 
       pt /= 10;
@@ -3203,7 +3245,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
 #ifdef HAVE_NS
       if (size == 0)
         {
-          Lisp_Object ffsize = get_frame_param(f, Qfontsize);
+          Lisp_Object ffsize = get_frame_param (f, Qfontsize);
           size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
         }
 #endif
@@ -3567,7 +3609,7 @@ font_filter_properties (Lisp_Object font,
    STRING.  */
 
 static Lisp_Object
-font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
+font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
         Lisp_Object string)
 {
   FRAME_PTR f;
@@ -3583,7 +3625,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
        {
          if (multibyte)
            {
-             EMACS_INT pos_byte = CHAR_TO_BYTE (pos);
+             ptrdiff_t pos_byte = CHAR_TO_BYTE (pos);
 
              c = FETCH_CHAR (pos_byte);
            }
@@ -3597,7 +3639,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
          multibyte = STRING_MULTIBYTE (string);
          if (multibyte)
            {
-             EMACS_INT pos_byte = string_char_to_byte (string, pos);
+             ptrdiff_t pos_byte = string_char_to_byte (string, pos);
 
              str = SDATA (string) + pos_byte;
              c = STRING_CHAR (str);
@@ -3613,7 +3655,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
   if (! face)
     {
       int face_id;
-      EMACS_INT endptr;
+      ptrdiff_t endptr;
 
       if (STRINGP (string))
        face_id = face_at_string_position (w, string, pos, 0, -1, -1, &endptr,
@@ -3650,9 +3692,9 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
    It is assured that the current buffer (or STRING) is multibyte.  */
 
 Lisp_Object
-font_range (EMACS_INT pos, EMACS_INT *limit, struct window *w, struct face *face, Lisp_Object string)
+font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face, Lisp_Object string)
 {
-  EMACS_INT pos_byte, ignore;
+  ptrdiff_t pos_byte, ignore;
   int c;
   Lisp_Object font_object = Qnil;
 
@@ -4058,7 +4100,7 @@ how close they are to PREFER.  */)
   (Lisp_Object font_spec, Lisp_Object frame, Lisp_Object num, Lisp_Object prefer)
 {
   Lisp_Object vec, list;
-  int n = 0;
+  EMACS_INT n = 0;
 
   if (NILP (frame))
     frame = selected_frame;
@@ -4225,13 +4267,10 @@ void
 font_fill_lglyph_metrics (Lisp_Object glyph, Lisp_Object font_object)
 {
   struct font *font = XFONT_OBJECT (font_object);
-  unsigned code;
-  /* ecode used in LGLYPH_SET_CODE to avoid compiler warnings.  */
-  EMACS_INT ecode = font->driver->encode_char (font, LGLYPH_CHAR (glyph));
+  unsigned code = font->driver->encode_char (font, LGLYPH_CHAR (glyph));
   struct font_metrics metrics;
 
-  LGLYPH_SET_CODE (glyph, ecode);
-  code = ecode;
+  LGLYPH_SET_CODE (glyph, code);
   font->driver->text_extents (font, &code, 1, &metrics);
   LGLYPH_SET_LBEARING (glyph, metrics.lbearing);
   LGLYPH_SET_RBEARING (glyph, metrics.rbearing);
@@ -4253,7 +4292,7 @@ created glyph-string.  Otherwise, the value is nil.  */)
 {
   struct font *font;
   Lisp_Object font_object, n, glyph;
-  EMACS_INT i, j, from, to;
+  ptrdiff_t i, j, from, to;
 
   if (! composition_gstring_p (gstring))
     signal_error ("Invalid glyph-string: ", gstring);
@@ -4272,8 +4311,7 @@ created glyph-string.  Otherwise, the value is nil.  */)
       if (INTEGERP (n))
        break;
       gstring = larger_vector (gstring,
-                              ASIZE (gstring) + LGSTRING_GLYPH_LEN (gstring),
-                              Qnil);
+                              LGSTRING_GLYPH_LEN (gstring), -1);
     }
   if (i == 3 || XINT (n) == 0)
     return Qnil;
@@ -4481,7 +4519,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
        doc: /* Open FONT-ENTITY.  */)
   (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame)
 {
-  int isize;
+  EMACS_INT isize;
 
   CHECK_FONT_ENTITY (font_entity);
   if (NILP (frame))
@@ -4497,6 +4535,8 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
        isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy);
       else
        isize = XINT (size);
+      if (! (INT_MIN <= isize && isize <= INT_MAX))
+       args_out_of_range (font_entity, size);
       if (isize == 0)
        isize = 120;
     }
@@ -4600,14 +4640,14 @@ the corresponding element is nil.  */)
    Lisp_Object object)
 {
   struct font *font;
-  int i, len;
+  ptrdiff_t i, len;
   Lisp_Object *chars, vec;
   USE_SAFE_ALLOCA;
 
   CHECK_FONT_GET_OBJECT (font_object, font);
   if (NILP (object))
     {
-      EMACS_INT charpos, bytepos;
+      ptrdiff_t charpos, bytepos;
 
       validate_region (&from, &to);
       if (EQ (from, to))
@@ -4713,22 +4753,22 @@ the current buffer.  It defaults to the currently selected window.  */)
   (Lisp_Object position, Lisp_Object window, Lisp_Object string)
 {
   struct window *w;
-  EMACS_INT pos;
+  ptrdiff_t pos;
 
   if (NILP (string))
     {
       CHECK_NUMBER_COERCE_MARKER (position);
-      pos = XINT (position);
-      if (pos < BEGV || pos >= ZV)
+      if (! (BEGV <= XINT (position) && XINT (position) < ZV))
        args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
+      pos = XINT (position);
     }
   else
     {
       CHECK_NUMBER (position);
       CHECK_STRING (string);
-      pos = XINT (position);
-      if (pos < 0 || pos >= SCHARS (string))
+      if (! (0 < XINT (position) && XINT (position) < SCHARS (string)))
        args_out_of_range (string, position);
+      pos = XINT (position);
     }
   if (NILP (window))
     window = selected_window;
@@ -5100,7 +5140,7 @@ the corresponding glyph code.  If ENCODING is a char-table, looking up
 the table by a character gives the corresponding glyph code.
 
 REPERTORY specifies a repertory of characters supported by the font.
-If REPERTORY is a charset, all characters beloging to the charset are
+If REPERTORY is a charset, all characters belonging to the charset are
 supported.  If REPERTORY is a char-table, all characters who have a
 non-nil value in the table are supported.  If REPERTORY is nil, Emacs
 gets the repertory information by an opened font and ENCODING.  */);