changeset 90501:2ef165ebcc7d

(xfont_query_font): Adjusted for the change of font_parse_xlfd. (xfont_list_pattern): New function. (xfont_list): Use xfont_list_pattern.
author Kenichi Handa <handa@m17n.org>
date Wed, 28 Jun 2006 05:41:21 +0000
parents 60e0667ab709
children 9d1084bd033e
files src/xfont.c
diffstat 1 files changed, 113 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/src/xfont.c	Wed Jun 28 05:40:15 2006 +0000
+++ b/src/xfont.c	Wed Jun 28 05:41:21 2006 +0000
@@ -92,7 +92,7 @@
 	{
 	  char *n = (char *) XGetAtomName (display, (Atom) value);
 
-	  if (font_parse_xlfd (n, spec, 0) >= 0)
+	  if (font_parse_xlfd (n, spec) >= 0)
 	    name = n;
 	  else
 	    XFree (n);
@@ -283,158 +283,153 @@
 extern Lisp_Object Vface_alternative_font_registry_alist;
 
 static Lisp_Object
-xfont_list (frame, spec)
-     Lisp_Object frame, spec;
+xfont_list_pattern (frame, display, pattern)
+     Lisp_Object frame;
+     Display *display;
+     char *pattern;
 {
-  FRAME_PTR f = XFRAME (frame);
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  Lisp_Object *vec, val, extra, font_name, entity;
-  char name[256], **names;
-  int i, idx, limit, num_fonts;
-  int error_occurred = 0;
-  USE_SAFE_ALLOCA;
-  
-  extra = AREF (spec, FONT_EXTRA_INDEX);
-  font_name = Qnil;
-  if (CONSP (extra))
-    {
-      val = Fassq (QCotf, extra);
-      if (! NILP (val))
-	return null_vector;
-      val = Fassq (QCscript, extra);
-      if (! NILP (val))
-	return null_vector;
-      val = Fassq (QCname, extra);
-      if (CONSP (val))
-	font_name = XCDR (val);
-    }
-
-  if (! STRINGP (font_name)
-      && font_unparse_xlfd (spec, 0, name, 256) < 0)
-    return null_vector;
+  Lisp_Object list = Qnil;
+  int i, limit, num_fonts;
+  char **names;
 
   BLOCK_INPUT;
-  x_catch_errors (dpyinfo->display);
+  x_catch_errors (display);
 
-  if (STRINGP (font_name))
+  for (limit = 512; ; limit *= 2)
     {
-      XFontStruct *font = XLoadQueryFont (dpyinfo->display,
-					  (char *) SDATA (font_name));
-      unsigned long value;
-
-      num_fonts = 0;
-      if (x_had_errors_p (dpyinfo->display))
+      names = XListFonts (display, pattern, limit, &num_fonts);
+      if (x_had_errors_p (display))
 	{
 	  /* This error is perhaps due to insufficient memory on X
 	     server.  Let's just ignore it.  */
-	  font = NULL;
-	  error_occurred = 1;
-	  x_clear_errors (dpyinfo->display);
+	  x_clear_errors (display);
+	  num_fonts = 0;
+	  break;
 	}
-      if (font)
+      if (num_fonts < limit)
+	break;
+      XFreeFontNames (names);
+    }
+
+  for (i = 0; i < num_fonts; i++)
+    {
+      Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
+      int result;
+
+      ASET (entity, FONT_TYPE_INDEX, Qx);
+      ASET (entity, FONT_FRAME_INDEX, frame);
+
+      result = font_parse_xlfd (names[i], entity);
+      if (result < 0)
 	{
+	  /* This may be an alias name.  Try to get the full XLFD name
+	     from XA_FONT property of the font.  */
+	  XFontStruct *font = XLoadQueryFont (display, names[i]);
+	  unsigned long value;
+
+	  if (! font)
+	    continue;
 	  if (XGetFontProperty (font, XA_FONT, &value))
 	    {
-	      char *n = (char *) XGetAtomName (dpyinfo->display, (Atom) value);
-	      int len = strlen (n);
-	      char *tmp;
+	      char *name = (char *) XGetAtomName (display, (Atom) value);
+	      int len = strlen (name);
 
 	      /* If DXPC (a Differential X Protocol Compressor)
                  Ver.3.7 is running, XGetAtomName will return null
                  string.  We must avoid such a name.  */
 	      if (len > 0)
-		{
-		  num_fonts = 1;
-		  names = (char **) alloca (sizeof (char *));
-		  /* Some systems only allow alloca assigned to a
-                     simple var.  */
-		  tmp = (char *) alloca (len + 1);  names[0] = tmp;
-		  bcopy (n, names[0], len + 1);
-		}
-	      XFree (n);
+		result = font_parse_xlfd (name, entity);
+	      XFree (name);
 	    }
-	  XFreeFont (dpyinfo->display, font);
+	  XFreeFont (display, font);
 	}
-    }
-  else
-    {
-      Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
-      Lisp_Object alter = Qnil;
-      char *r = NULL;
 
-      if (! NILP (registry))
-	alter = Fassoc_string (SYMBOL_NAME (registry),
-			       Vface_alternative_font_registry_alist);
-      while (1)
+      if (result == 0)
 	{
-	  for (limit = 512, num_fonts = 0; ; limit *= 2)
+	  Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
+	  char *p = (char *) SDATA (SYMBOL_NAME (val));
+
+	  /* P == "RESX-RESY-SPACING-AVGWIDTH.  We rejust this font if
+	     it's an autoscaled one (i.e. RESX > 0 && AVGWIDTH == 0).  */
+	  if (atoi (p) > 0)
 	    {
-	      names = XListFonts (dpyinfo->display, name, limit, &num_fonts);
-	      if (x_had_errors_p (dpyinfo->display))
-		{
-		  /* This error is perhaps due to insufficient memory
-		     on X server.  Let's just ignore it.  */
-		  x_clear_errors (dpyinfo->display);
-		  error_occurred = 1;
-		  num_fonts = 0;
-		  break;
-		}
-	      if (num_fonts < limit)
-		break;
-	      XFreeFontNames (names);
+	      p += SBYTES (SYMBOL_NAME (val));
+	      while (p[-1] != '-') p--;
+	      if (atoi (p) == 0)
+		continue;
 	    }
-	  if (num_fonts > 0
-	      || NILP (alter))
-	    break;
-
-	  /* Setup for trying alternatives.  */
-	  if (! r
-	      && ! (r = strstr (name, (char *) SDATA (SYMBOL_NAME (registry)))))
-	    abort ();
-	  while (1)
-	    {
-	      registry = Qnil;
-	      alter = XCDR (alter);
-	      if (NILP (alter))
-		break;
-	      registry = XCAR (alter);
-	      if ((r - name) + SBYTES (registry) < 255)
-		break;
-	    }
-	  if (NILP (registry))
-	    break;
-	  bcopy (SDATA (registry), r, SBYTES (registry));
+	  list = Fcons (entity, list);
 	}
     }
 
   x_uncatch_errors ();
   UNBLOCK_INPUT;
 
-  if (error_occurred)
-    return Qnil;
-  if (num_fonts == 0)
-    return null_vector;
+  return list;
+}
 
-  entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
-  ASET (entity, FONT_TYPE_INDEX, Qx);
-  ASET (entity, FONT_FRAME_INDEX, frame);
-
-  SAFE_ALLOCA_LISP (vec, num_fonts);
-  for (i = idx = 0; i < num_fonts; i++)
+static Lisp_Object
+xfont_list (frame, spec)
+     Lisp_Object frame, spec;
+{
+  FRAME_PTR f = XFRAME (frame);
+  Display *display = FRAME_X_DISPLAY_INFO (f)->display;
+  Lisp_Object list, val, extra, font_name;
+  int len;
+  char name[256];
+  
+  extra = AREF (spec, FONT_EXTRA_INDEX);
+  font_name = Qnil;
+  if (CONSP (extra))
     {
-      if (font_parse_xlfd (names[i], entity, 0) > 0)
-	vec[idx++] = Fcopy_sequence (entity);
+      val = assq_no_quit (QCotf, extra);
+      if (! NILP (val))
+	return null_vector;
+      val = assq_no_quit (QCscript, extra);
+      if (! NILP (val))
+	return null_vector;
+      val = assq_no_quit (QClanguage, extra);
+      if (! NILP (val))
+	return null_vector;
+      val = assq_no_quit (QCname, extra);
+      if (CONSP (val))
+	font_name = XCDR (val);
     }
-  if (! STRINGP (font_name))
+
+  if (STRINGP (font_name))
+    list = xfont_list_pattern (frame, display, (char *) SDATA (font_name));
+  else if ((len = font_unparse_xlfd (spec, 0, name, 256)) < 0)
+    return null_vector;
+  else
     {
-      BLOCK_INPUT;
-      XFreeFontNames (names);
-      UNBLOCK_INPUT;
+      list = xfont_list_pattern (frame, display, name);
+      if (NILP (list))
+	{
+	  Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
+	  Lisp_Object alter;
+
+	  if (! NILP (registry)
+	      && (alter = Fassoc (SYMBOL_NAME (registry),
+				  Vface_alternative_font_registry_alist))
+	      && CONSP (alter))
+	    {
+	      /* Pointer to REGISTRY-ENCODING field.  */
+	      char *r = name + len - SBYTES (SYMBOL_NAME (registry));
+
+	      for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
+		if (STRINGP (XCAR (alter))
+		    && ((r - name) + SBYTES (XCAR (alter))) < 255)
+		  {
+		    strcpy (r, (char *) SDATA (XCAR (alter)));
+		    list = xfont_list_pattern (frame, display, name);
+		    if (! NILP (list))
+		      break;
+		  }
+	    }
+	}
     }
-  val = Fvector (idx, vec);
-  SAFE_FREE ();
 
-  return val;
+  return (NILP (list) ? null_vector : Fvconcat (1, &list));
 }
 
 static int