font.c (Ffont_at): Fix previous change.
[bpt/emacs.git] / src / font.c
index 5b01a1f..7cb4149 100644 (file)
@@ -23,8 +23,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <float.h>
 #include <stdio.h>
-#include <ctype.h>
-#include <setjmp.h>
+
+#include <c-ctype.h>
 
 #include "lisp.h"
 #include "character.h"
@@ -37,17 +37,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "fontset.h"
 #include "font.h"
 
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif /* HAVE_X_WINDOWS */
-
-#ifdef HAVE_NTGUI
-#include "w32term.h"
-#endif /* HAVE_NTGUI */
-
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif /* HAVE_NS */
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
 
 Lisp_Object Qopentype;
 
@@ -223,13 +215,12 @@ static int num_font_drivers;
 
 
 /* Return a Lispy value of a font property value at STR and LEN bytes.
-   If STR is "*", return nil.
-   If FORCE_SYMBOL is zero and all characters in STR are digits,
-   return an integer.  Otherwise, return a symbol interned from
-   STR.  */
+   If STR is "*", return nil.  If FORCE_SYMBOL, or if STR does not
+   consist entirely of one or more digits, return a symbol interned
+   from STR.  Otherwise, return an integer.  */
 
 Lisp_Object
-font_intern_prop (const char *str, ptrdiff_t len, int force_symbol)
+font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
 {
   ptrdiff_t i;
   Lisp_Object tem;
@@ -290,7 +281,7 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec)
     return XINT (size);
   if (NILP (size))
     return 0;
-  font_assert (FLOATP (size));
+  eassert (FLOATP (size));
   point_size = XFLOAT_DATA (size);
   val = AREF (spec, FONT_DPI_INDEX);
   if (INTEGERP (val))
@@ -313,7 +304,8 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec)
    VAL is an integer.  */
 
 int
-font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror)
+font_style_to_value (enum font_property_index prop, Lisp_Object val,
+                     bool noerror)
 {
   Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
   int len;
@@ -354,8 +346,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
          }
       if (! noerror)
        return -1;
-      if (len == 255)
-       abort ();
+      eassert (len < 255);
       elt = Fmake_vector (make_number (2), make_number (100));
       ASET (elt, 1, val);
       args[0] = table;
@@ -393,7 +384,8 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
 }
 
 Lisp_Object
-font_style_symbolic (Lisp_Object font, enum font_property_index prop, int for_face)
+font_style_symbolic (Lisp_Object font, enum font_property_index prop,
+                     bool for_face)
 {
   Lisp_Object val = AREF (font, prop);
   Lisp_Object table, elt;
@@ -404,10 +396,10 @@ font_style_symbolic (Lisp_Object font, enum font_property_index prop, int for_fa
   table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
   CHECK_VECTOR (table);
   i = XINT (val) & 0xFF;
-  font_assert (((i >> 4) & 0xF) < ASIZE (table));
+  eassert (((i >> 4) & 0xF) < ASIZE (table));
   elt = AREF (table, ((i >> 4) & 0xF));
   CHECK_VECTOR (elt);
-  font_assert ((i & 0xF) + 1 < ASIZE (elt));
+  eassert ((i & 0xF) + 1 < ASIZE (elt));
   elt = (for_face ? AREF (elt, 1) : AREF (elt, (i & 0xF) + 1));
   CHECK_SYMBOL (elt);
   return elt;
@@ -1076,11 +1068,11 @@ font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font)
            {
              double point_size = -1;
 
-             font_assert (FONT_SPEC_P (font));
+             eassert (FONT_SPEC_P (font));
              p = f[XLFD_POINT_INDEX];
              if (*p == '[')
                point_size = parse_matrix (p);
-             else if (isdigit (*p))
+             else if (c_isdigit (*p))
                point_size = atoi (p), point_size /= 10;
              if (point_size >= 0)
                ASET (font, FONT_SIZE_INDEX, make_float (point_size));
@@ -1109,7 +1101,7 @@ font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font)
     }
   else
     {
-      int wild_card_found = 0;
+      bool wild_card_found = 0;
       Lisp_Object prop[XLFD_LAST_INDEX];
 
       if (FONT_ENTITY_P (font))
@@ -1197,7 +1189,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
   Lisp_Object val;
   int i, j, len;
 
-  font_assert (FONTP (font));
+  eassert (FONTP (font));
 
   for (i = FONT_FOUNDRY_INDEX, j = XLFD_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX;
        i++, j++)
@@ -1248,7 +1240,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
     }
 
   val = AREF (font, FONT_SIZE_INDEX);
-  font_assert (NUMBERP (val) || NILP (val));
+  eassert (NUMBERP (val) || NILP (val));
   if (INTEGERP (val))
     {
       EMACS_INT v = XINT (val);
@@ -1345,9 +1337,9 @@ font_parse_fcname (char *name, ptrdiff_t len, Lisp_Object font)
        }
       else if (*p == '-')
        {
-         int decimal = 0, size_found = 1;
+         bool decimal = 0, size_found = 1;
          for (q = p + 1; *q && *q != ':'; q++)
-           if (! isdigit (*q))
+           if (! c_isdigit (*q))
              {
                if (*q != '.' || decimal)
                  {
@@ -1475,7 +1467,7 @@ font_parse_fcname (char *name, ptrdiff_t len, Lisp_Object font)
 
       /* Scan backwards from the end, looking for a size.  */
       for (p = name + len - 1; p >= name; p--)
-       if (!isdigit (*p))
+       if (!c_isdigit (*p))
          break;
 
       if ((p < name + len - 1) && ((p + 1 == name) || *p == ' '))
@@ -1585,8 +1577,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
     }
   else
     {
-      if (! FLOATP (val))
-       abort ();
+      eassert (FLOATP (val));
       pixel_size = -1;
       point_size = (int) XFLOAT_DATA (val);
     }
@@ -1947,7 +1938,7 @@ generate_otf_features (Lisp_Object spec, char *features)
 {
   Lisp_Object val;
   char *p;
-  int asterisk;
+  bool asterisk;
 
   p = features;
   *p = '\0';
@@ -2138,7 +2129,7 @@ static Lisp_Object
 font_vconcat_entity_vectors (Lisp_Object list)
 {
   int nargs = XINT (Flength (list));
-  Lisp_Object *args = alloca (sizeof (Lisp_Object) * nargs);
+  Lisp_Object *args = alloca (word_size * nargs);
   int i;
 
   for (i = 0; i < nargs; i++, list = XCDR (list))
@@ -2227,7 +2218,7 @@ font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int
       maxlen = ASIZE (vec);
     }
 
-  SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * maxlen);
+  data = SAFE_ALLOCA (maxlen * sizeof *data);
   best_score = 0xFFFFFFFF;
   best_entity = Qnil;
 
@@ -2311,11 +2302,12 @@ font_update_sort_order (int *order)
     }
 }
 
-static int
-font_check_otf_features (Lisp_Object script, Lisp_Object langsys, Lisp_Object features, Lisp_Object table)
+static bool
+font_check_otf_features (Lisp_Object script, Lisp_Object langsys,
+                         Lisp_Object features, Lisp_Object table)
 {
   Lisp_Object val;
-  int negative;
+  bool negative;
 
   table = assq_no_quit (script, table);
   if (NILP (table))
@@ -2351,7 +2343,7 @@ font_check_otf_features (Lisp_Object script, Lisp_Object langsys, Lisp_Object fe
 
 /* Check if OTF_CAPABILITY satisfies SPEC (otf-spec).  */
 
-static int
+static bool
 font_check_otf (Lisp_Object spec, Lisp_Object otf_capability)
 {
   Lisp_Object script, langsys = Qnil, gsub = Qnil, gpos = Qnil;
@@ -2385,7 +2377,7 @@ font_check_otf (Lisp_Object spec, Lisp_Object otf_capability)
 /* Check if FONT (font-entity or font-object) matches with the font
    specification SPEC.  */
 
-int
+bool
 font_match_p (Lisp_Object spec, Lisp_Object font)
 {
   Lisp_Object prop[FONT_SPEC_MAX], *props;
@@ -2540,7 +2532,7 @@ font_finish_cache (FRAME_PTR f, struct font_driver *driver)
   val = XCDR (cache);
   while (CONSP (val) && ! EQ (XCAR (XCAR (val)), driver->type))
     cache = val, val = XCDR (val);
-  font_assert (! NILP (val));
+  eassert (! NILP (val));
   tmp = XCDR (XCAR (val));
   XSETCAR (tmp, make_number (XINT (XCAR (tmp)) - 1));
   if (XINT (XCAR (tmp)) == 0)
@@ -2557,9 +2549,9 @@ font_get_cache (FRAME_PTR f, struct font_driver *driver)
   Lisp_Object val = driver->get_cache (f);
   Lisp_Object type = driver->type;
 
-  font_assert (CONSP (val));
+  eassert (CONSP (val));
   for (val = XCDR (val); ! EQ (XCAR (XCAR (val)), type); val = XCDR (val));
-  font_assert (CONSP (val));
+  eassert (CONSP (val));
   /* VAL = ((DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) ...) */
   val = XCDR (XCAR (val));
   return val;
@@ -2596,7 +2588,7 @@ font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver)
 
                      if (! NILP (AREF (val, FONT_TYPE_INDEX)))
                        {
-                         font_assert (font && driver == font->driver);
+                         eassert (font && driver == font->driver);
                          driver->close (f, font);
                          num_fonts--;
                        }
@@ -2703,10 +2695,10 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec)
   Lisp_Object ftype, val;
   Lisp_Object list = Qnil;
   int size;
-  int need_filtering = 0;
+  bool need_filtering = 0;
   int i;
 
-  font_assert (FONT_SPEC_P (spec));
+  eassert (FONT_SPEC_P (spec));
 
   if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
     size = XINT (AREF (spec, FONT_SIZE_INDEX));
@@ -2826,7 +2818,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   int min_width, height;
   int scaled_pixel_size = pixel_size;
 
-  font_assert (FONT_ENTITY_P (entity));
+  eassert (FONT_ENTITY_P (entity));
   size = AREF (entity, FONT_SIZE_INDEX);
   if (XINT (size) != 0)
     scaled_pixel_size = pixel_size = XINT (size);
@@ -2903,7 +2895,7 @@ font_close_object (FRAME_PTR f, Lisp_Object font_object)
   FONT_ADD_LOG ("close", font_object, Qnil);
   font->driver->close (f, font);
 #ifdef HAVE_WINDOW_SYSTEM
-  font_assert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
+  eassert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
   FRAME_X_DISPLAY_INFO (f)->n_fonts--;
 #endif
   num_fonts--;
@@ -2933,7 +2925,7 @@ font_has_char (FRAME_PTR f, Lisp_Object font, int c)
       return driver_list->driver->has_char (font, c);
     }
 
-  font_assert (FONT_OBJECT_P (font));
+  eassert (FONT_OBJECT_P (font));
   fontp = XFONT_OBJECT (font);
   if (fontp->driver->has_char)
     {
@@ -2953,7 +2945,7 @@ font_encode_char (Lisp_Object font_object, int c)
 {
   struct font *font;
 
-  font_assert (FONT_OBJECT_P (font_object));
+  eassert (FONT_OBJECT_P (font_object));
   font = XFONT_OBJECT (font_object);
   return font->driver->encode_char (font, c);
 }
@@ -2964,7 +2956,7 @@ font_encode_char (Lisp_Object font_object, int c)
 Lisp_Object
 font_get_name (Lisp_Object font_object)
 {
-  font_assert (FONT_OBJECT_P (font_object));
+  eassert (FONT_OBJECT_P (font_object));
   return AREF (font_object, FONT_NAME_INDEX);
 }
 
@@ -3045,15 +3037,14 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs,
 {
   Lisp_Object font_entity;
   Lisp_Object prefer;
-  int result, i;
+  int i;
   FRAME_PTR f = XFRAME (frame);
 
   if (NILP (XCDR (entities))
       && ASIZE (XCAR (entities)) == 1)
     {
       font_entity = AREF (XCAR (entities), 0);
-      if (c < 0
-         || (result = font_has_char (f, font_entity, c)) > 0)
+      if (c < 0 || font_has_char (f, font_entity, c) > 0)
        return font_entity;
       return Qnil;
     }
@@ -3250,10 +3241,8 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
        {
          struct face *def = FACE_FROM_ID (f, DEFAULT_FACE_ID);
          Lisp_Object height = def->lface[LFACE_HEIGHT_INDEX];
-         if (INTEGERP (height))
-           pt = XINT (height);
-         else
-           abort (); /* We should never end up here.  */
+         eassert (INTEGERP (height));
+         pt = XINT (height);
        }
 
       pt /= 10;
@@ -3350,13 +3339,13 @@ font_open_by_spec (FRAME_PTR f, Lisp_Object spec)
    found, return Qnil.  */
 
 Lisp_Object
-font_open_by_name (FRAME_PTR f, const char *name, ptrdiff_t len)
+font_open_by_name (FRAME_PTR f, Lisp_Object name)
 {
   Lisp_Object args[2];
   Lisp_Object spec, ret;
 
   args[0] = QCname;
-  args[1] = make_unibyte_string (name, len);
+  args[1] = name;
   spec = Ffont_spec (2, args);
   ret = font_open_by_spec (f, spec);
   /* Do not lose name originally put in.  */
@@ -3629,7 +3618,7 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
         Lisp_Object string)
 {
   FRAME_PTR f;
-  int multibyte;
+  bool multibyte;
   Lisp_Object font_object;
 
   multibyte = (NILP (string)
@@ -3728,7 +3717,7 @@ font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face
     }
   else
     {
-      font_assert (face);
+      eassert (face);
       pos_byte = string_char_to_byte (string, pos);
     }
 
@@ -4268,7 +4257,7 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
            while (! NILP (val)
                   && ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
              val = XCDR (val);
-           font_assert (! NILP (val));
+           eassert (! NILP (val));
            tmp = XCDR (XCAR (val));
            if (XINT (XCAR (tmp)) == 0)
              {
@@ -4306,12 +4295,15 @@ to get the correct visual image of character sequences set in the
 header of the glyph-string.
 
 If the shaping was successful, the value is GSTRING itself or a newly
-created glyph-string.  Otherwise, the value is nil.  */)
+created glyph-string.  Otherwise, the value is nil.
+
+See the documentation of `composition-get-gstring' for the format of
+GSTRING.  */)
   (Lisp_Object gstring)
 {
   struct font *font;
   Lisp_Object font_object, n, glyph;
-  ptrdiff_t i, j, from, to;
+  ptrdiff_t i, from, to;
 
   if (! composition_gstring_p (gstring))
     signal_error ("Invalid glyph-string: ", gstring);
@@ -4337,44 +4329,42 @@ created glyph-string.  Otherwise, the value is nil.  */)
   if (XINT (n) < LGSTRING_GLYPH_LEN (gstring))
     LGSTRING_SET_GLYPH (gstring, XINT (n), Qnil);
 
+  /* Check FROM_IDX and TO_IDX of each GLYPH in GSTRING to assure that
+     GLYPHS covers all characters (except for the last few ones) in
+     GSTRING.  More formally, provided that NCHARS is the number of
+     characters in GSTRING and GLYPHS[i] is the ith glyph, FROM_IDX
+     and TO_IDX of each glyph must satisfy these conditions:
+
+       GLYPHS[0].FROM_IDX == 0
+       GLYPHS[i].FROM_IDX <= GLYPHS[i].TO_IDX
+       if (GLYPHS[i].FROM_IDX == GLYPHS[i-1].FROM_IDX)
+         ;; GLYPHS[i] and GLYPHS[i-1] belongs to the same grapheme cluster
+         GLYPHS[i].TO_IDX == GLYPHS[i-1].TO_IDX
+       else
+         ;; Be sure to cover all characters.
+         GLYPHS[i].FROM_IDX == GLYPHS[i-1].TO_IDX + 1 */
   glyph = LGSTRING_GLYPH (gstring, 0);
   from = LGLYPH_FROM (glyph);
   to = LGLYPH_TO (glyph);
-  for (i = 1, j = 0; i < LGSTRING_GLYPH_LEN (gstring); i++)
+  if (from != 0 || to < from)
+    goto shaper_error;
+  for (i = 1; i < LGSTRING_GLYPH_LEN (gstring); i++)
     {
-      Lisp_Object this = LGSTRING_GLYPH (gstring, i);
-
-      if (NILP (this))
+      glyph = LGSTRING_GLYPH (gstring, i);
+      if (NILP (glyph))
        break;
-      if (NILP (LGLYPH_ADJUSTMENT (this)))
-       {
-         if (j < i - 1)
-           for (; j < i; j++)
-             {
-               glyph = LGSTRING_GLYPH (gstring, j);
-               LGLYPH_SET_FROM (glyph, from);
-               LGLYPH_SET_TO (glyph, to);
-             }
-         from = LGLYPH_FROM (this);
-         to = LGLYPH_TO (this);
-         j = i;
-       }
-      else
-       {
-         if (from > LGLYPH_FROM (this))
-           from = LGLYPH_FROM (this);
-         if (to < LGLYPH_TO (this))
-           to = LGLYPH_TO (this);
-       }
+      if (! (LGLYPH_FROM (glyph) <= LGLYPH_TO (glyph)
+            && (LGLYPH_FROM (glyph) == from
+                ? LGLYPH_TO (glyph) == to
+                : LGLYPH_FROM (glyph) == to + 1)))
+       goto shaper_error;
+      from = LGLYPH_FROM (glyph);
+      to = LGLYPH_TO (glyph);
     }
-  if (j < i - 1)
-    for (; j < i; j++)
-      {
-       glyph = LGSTRING_GLYPH (gstring, j);
-       LGLYPH_SET_FROM (glyph, from);
-       LGLYPH_SET_TO (glyph, to);
-      }
   return composition_gstring_put_cache (gstring, XINT (n));
+
+ shaper_error:
+  return Qnil;
 }
 
 DEFUN ("font-variation-glyphs", Ffont_variation_glyphs, Sfont_variation_glyphs,
@@ -4722,7 +4712,7 @@ the corresponding element is nil.  */)
          Lisp_Object elt = AREF (object, XFASTINT (from) + i);
          CHECK_CHARACTER (elt);
        }
-      chars = &(AREF (object, XFASTINT (from)));
+      chars = aref_addr (object, XFASTINT (from));
     }
 
   vec = Fmake_vector (make_number (len), Qnil);
@@ -4785,7 +4775,7 @@ the current buffer.  It defaults to the currently selected window.  */)
     {
       CHECK_NUMBER (position);
       CHECK_STRING (string);
-      if (! (0 < XINT (position) && XINT (position) < SCHARS (string)))
+      if (! (0 <= XINT (position) && XINT (position) < SCHARS (string)))
        args_out_of_range (string, position);
       pos = XINT (position);
     }
@@ -4878,7 +4868,7 @@ If the named font is not yet loaded, return nil.  */)
 
       if (fontset >= 0)
        name = fontset_ascii (fontset);
-      font_object = font_open_by_name (f, SSDATA (name), SBYTES (name));
+      font_object = font_open_by_name (f, name);
     }
   else if (FONT_OBJECT_P (name))
     font_object = name;
@@ -5218,9 +5208,9 @@ EMACS_FONT_LOG is set.  Otherwise, it is set to t.  */);
 #ifdef HAVE_BDFFONT
   syms_of_bdffont ();
 #endif /* HAVE_BDFFONT */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
   syms_of_w32font ();
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
 #ifdef HAVE_NS
   syms_of_nsfont ();
 #endif /* HAVE_NS */