changeset 102414:5988cd89cf0b

(fontset_find_font): If a font found without restricting the characters C doen't support C, try to find a font with C restriction.
author Kenichi Handa <handa@m17n.org>
date Thu, 05 Mar 2009 12:21:41 +0000
parents feece1082bed
children ccbe1c8ab377
files src/fontset.c
diffstat 1 files changed, 42 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/fontset.c	Thu Mar 05 08:24:26 2009 +0000
+++ b/src/fontset.c	Thu Mar 05 12:21:41 2009 +0000
@@ -523,7 +523,7 @@
      struct face *face;
      int id, fallback;
 {
-  Lisp_Object elt, vec, font_group;
+  Lisp_Object vec, font_group;
   int i, charset_matched = -1;
   FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
     ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
@@ -561,97 +561,110 @@
   /* Find the first available font in the vector of RFONT-DEF.  */
   for (i = 0; i < ASIZE (vec); i++)
     {
+      Lisp_Object rfont_def, font_def;
       Lisp_Object font_entity, font_object;
 
       if (i == 0 && charset_matched >= 0)
 	{
 	  /* Try the element matching with the charset ID at first.  */
-	  elt = AREF (vec, charset_matched);
+	  rfont_def = AREF (vec, charset_matched);
 	  charset_matched = -1;
 	  i--;
 	}
       else if (i != charset_matched)
-	elt = AREF (vec, i);
+	rfont_def = AREF (vec, i);
       else
 	continue;
 
-      if (NILP (elt))
+      if (NILP (rfont_def))
 	/* This is a sign of not to try the other fonts.  */
 	return Qt;
-      if (INTEGERP (RFONT_DEF_FACE (elt))
-	  && XINT (RFONT_DEF_FACE (elt)) < 0)
+      if (INTEGERP (RFONT_DEF_FACE (rfont_def))
+	  && XINT (RFONT_DEF_FACE (rfont_def)) < 0)
 	/* We couldn't open this font last time.  */
 	continue;
 
-      font_object = RFONT_DEF_OBJECT (elt);
+      font_object = RFONT_DEF_OBJECT (rfont_def);
       if (NILP (font_object))
 	{
-	  Lisp_Object font_def = RFONT_DEF_FONT_DEF (elt);
+	  font_def = RFONT_DEF_FONT_DEF (rfont_def);
 
 	  if (! face)
 	    /* We have not yet opened the font.  */
 	    return Qnil;
+	  /* Find a font best-matching with the spec without checking
+	     the support of the character C.  That checking is costly,
+	     and even without the checking, the found font supports C
+	     in high possibility.  */
 	  font_entity = font_find_for_lface (f, face->lface,
 					     FONT_DEF_SPEC (font_def), -1);
 	  if (NILP (font_entity))
 	    {
 	      /* Record that no font matches the spec.  */
-	      RFONT_DEF_SET_FACE (elt, -1);
+	      RFONT_DEF_SET_FACE (rfont_def, -1);
 	      continue;
 	    }
 	  font_object = font_open_for_lface (f, font_entity, face->lface,
 					     FONT_DEF_SPEC (font_def));
 	  if (NILP (font_object))
 	    {
-	      /* Record that the font is unsable.  */
-	      RFONT_DEF_SET_FACE (elt, -1);
+	      /* Something strange happened, perhaps because of a
+		 Font-backend problem.  Too avoid crashing, record
+		 that this spec is unsable.  It may be better to find
+		 another font of the same spec, but currently we don't
+		 have such an API.  */
+	      RFONT_DEF_SET_FACE (rfont_def, -1);
 	      continue;
 	    }
-	  RFONT_DEF_SET_OBJECT (elt, font_object);
+	  RFONT_DEF_SET_OBJECT (rfont_def, font_object);
 	}
 
       if (font_has_char (f, font_object, c))
-	return elt;
+	return rfont_def;
 
-#if 0
-      /* The following code makes Emacs to find a font for C by fairly
-	 exhausitive search.  But, that takes long time especially for
-	 X font backend.  */
-
-      /* Try to find the different font maching with the current spec
-	 and support C. */
-      font_def = RFONT_DEF_FONT_DEF (elt);
+      /* Find a font already opened, maching with the current spec,
+	 and supporting C. */
+      font_def = RFONT_DEF_FONT_DEF (rfont_def);
       for (i++; i < ASIZE (vec); i++)
 	{
-	  if (! EQ (RFONT_DEF_FONT_DEF (AREF (vec, i)), font_def))
+	  rfont_def = AREF (vec, i);
+	  if (! EQ (RFONT_DEF_FONT_DEF (rfont_def), font_def))
 	    break;
-	  if (font_has_char (f, RFONT_DEF_OBJECT (AREF (vec, i)), c))
-	    return AREF (vec, i);
+	  font_object = RFONT_DEF_OBJECT (AREF (vec, i));
+	  xassert (! NILP (font_object));
+	  if (font_has_char (f, font_object, c))
+	    return rfont_def;
 	}
-      /* Find an font-entity that support C.  */
+
+      /* Find a font-entity with the current spec and supporting C.  */
       font_entity = font_find_for_lface (f, face->lface,
 					 FONT_DEF_SPEC (font_def), c);
       if (! NILP (font_entity))
 	{
-	  Lisp_Object rfont_def, new_vec;
+	  /* We found a font.  Open it and insert a new element for
+	     that font in VEC.  */
+	  Lisp_Object new_vec;
 	  int j;
 
 	  font_object = font_open_for_lface (f, font_entity, face->lface,
 					     Qnil);
+	  if (NILP (font_object))
+	    continue;
 	  RFONT_DEF_NEW (rfont_def, font_def);
 	  RFONT_DEF_SET_OBJECT (rfont_def, font_object);
-	  RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (elt));
+	  RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (rfont_def));
 	  new_vec = Fmake_vector (make_number (ASIZE (vec) + 1), Qnil);
 	  for (j = 0; j < i; j++)
 	    ASET (new_vec, j, AREF (vec, j));
 	  ASET (new_vec, j, rfont_def);
 	  for (j++; j < ASIZE (new_vec); j++)
 	    ASET (new_vec, j, AREF (vec, j - 1));
-	  vec = new_vec;
+	  XSETCDR (font_group, new_vec);
 	  return rfont_def;
 	}
+
+      /* No font of the current spec for C.  Try the next spec.  */
       i--;
-#endif	/* 0 */
     }
 
   FONTSET_SET (fontset, make_number (c), make_number (0));