changeset 90414:41626792e297

Include "font.h". (set_lface_from_font_name) (set_font_frame_param, free_realized_face) (prepare_face_for_display, clear_face_gcs) (Finternal_set_font_selection_order, realize_x_face) [USE_FONT_BACKEND]: If enable_font_backend is nonzero, use font-backend mechanism. (clear_face_cache) [USE_FONT_BACKEND]: Don't call clear_font_table. (load_face_font) [USE_FONT_BACKEND]: Abort. (face_symbolic_value, face_symbolic_weight, face_symbolic_slant) (face_symbolic_swidth, face_for_font) [USE_FONT_BACKEND]: New functions.
author Kenichi Handa <handa@m17n.org>
date Tue, 06 Jun 2006 03:52:38 +0000
parents 4ee003f8531c
children fed91f43ffad
files src/xfaces.c
diffstat 1 files changed, 243 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/xfaces.c	Tue Jun 06 03:52:26 2006 +0000
+++ b/src/xfaces.c	Tue Jun 06 03:52:38 2006 +0000
@@ -246,6 +246,12 @@
 #include "window.h"
 #include "intervals.h"
 
+#ifdef HAVE_WINDOW_SYSTEM
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif	/* USE_FONT_BACKEND */
+#endif	/* HAVE_WINDOW_SYSTEM */
+
 #ifdef HAVE_X_WINDOWS
 
 /* Compensate for a bug in Xos.h on some systems, on which it requires
@@ -988,6 +994,9 @@
     {
       struct x_display_info *dpyinfo;
 
+#ifdef USE_FONT_BACKEND
+      if (! enable_font_backend)
+#endif	/* USE_FONT_BACKEND */
       /* Fonts are common for frames on one display, i.e. on
 	 one X screen.  */
       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@ -1249,6 +1258,10 @@
   char *font_name;
   int needs_overstrike;
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    abort ();
+#endif	/* USE_FONT_BACKEND */
   face->font_info_id = -1;
   face->font = NULL;
   face->font_name = NULL;
@@ -2188,6 +2201,58 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+#ifdef USE_FONT_BACKEND
+static INLINE Lisp_Object
+face_symbolic_value (table, dim, font_prop)
+     struct table_entry *table;
+     int dim;
+     Lisp_Object font_prop;
+{
+  struct table_entry *p;
+  char *s = SDATA (SYMBOL_NAME (font_prop));
+  int low, mid, high, cmp;
+
+  low = 0;
+  high = dim - 1;
+
+  while (low <= high)
+    {
+      mid = (low + high) / 2;
+      cmp = strcmp (table[mid].name, s);
+
+      if (cmp < 0)
+	low = mid + 1;
+      else if (cmp > 0)
+	high = mid - 1;
+      else
+	return *table[mid].symbol;
+    }
+
+  return Qnil;
+}
+
+static INLINE Lisp_Object
+face_symbolic_weight (weight)
+     Lisp_Object weight;
+{
+  return face_symbolic_value (weight_table, DIM (weight_table), weight);
+}
+
+static INLINE Lisp_Object
+face_symbolic_slant (slant)
+     Lisp_Object slant;
+{
+  return face_symbolic_value (slant_table, DIM (slant_table), slant);
+}
+
+static INLINE Lisp_Object
+face_symbolic_swidth (width)
+     Lisp_Object width;
+{
+  return face_symbolic_value (swidth_table, DIM (swidth_table), width);
+}
+#endif	/* USE_FONT_BACKEND */
+
 Lisp_Object
 split_font_name_into_vector (fontname)
      Lisp_Object fontname;
@@ -3467,6 +3532,107 @@
 
   /* If FONTNAME is actually a fontset name, get ASCII font name of it.  */
   fontset = fs_query_fontset (fontname, 0);
+
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      Lisp_Object entity;
+      struct font *font = NULL;
+
+      if (fontset > 0)
+	font = fontset_ascii_font (f, fontset);
+      else if (fontset == 0)
+	{
+	  if (may_fail_p)
+	    return 0;
+	  abort ();
+	}
+      else
+	{
+	  Lisp_Object font_object = font_open_by_name (f, SDATA (fontname));
+
+	  if (! NILP (font_object))
+	    {
+	      font = XSAVE_VALUE (font_object)->pointer;
+	      fontset = new_fontset_from_font (f, font_object);
+	    }
+	}
+
+      if (! font)
+	{
+	  if (may_fail_p)
+	    return 0;
+	  abort ();
+	}
+
+      entity = font->entity;
+
+      /* Set attributes only if unspecified, otherwise face defaults for
+	 new frames would never take effect.  If we couldn't get a font
+	 name conforming to XLFD, set normal values.  */
+
+      if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
+	{
+	  Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX);
+	  Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX);
+	  Lisp_Object val;
+
+	  if (! NILP (foundry))
+	    {
+	      if (! NILP (family))
+		val = concat3 (SYMBOL_NAME (foundry), build_string ("-"),
+			       SYMBOL_NAME (family));
+	      else
+		val = concat2 (SYMBOL_NAME (foundry), build_string ("-*"));
+	    }
+	  else
+	    {
+	      if (! NILP (family))
+		val = SYMBOL_NAME (family);
+	      else
+		val = build_string ("*");
+	    }
+	  LFACE_FAMILY (lface) = val;
+	}
+
+      if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
+	{
+	  int pt = pixel_point_size (f, font->pixel_size * 10);
+
+	  xassert (pt > 0);
+	  LFACE_HEIGHT (lface) = make_number (pt);
+	}
+
+      if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
+	LFACE_AVGWIDTH (lface) = make_number (0);
+
+      if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
+	{
+	  Lisp_Object weight = font_symbolic_weight (entity);
+	  Lisp_Object symbol = face_symbolic_weight (weight);
+
+	  LFACE_WEIGHT (lface) = NILP (symbol) ? weight : symbol;
+	}
+      if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
+	{
+	  Lisp_Object slant = font_symbolic_slant (entity);
+	  Lisp_Object symbol = face_symbolic_slant (slant);
+
+	  LFACE_SLANT (lface) = NILP (symbol) ? slant : symbol;
+	}
+      if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
+	{
+	  Lisp_Object width = font_symbolic_width (entity);
+	  Lisp_Object symbol = face_symbolic_swidth (width);
+
+	  LFACE_SWIDTH (lface) = NILP (symbol) ? width : symbol;
+	}
+
+      ASET (lface, LFACE_FONT_INDEX, Ffont_xlfd_name (font->entity));
+      ASET (lface, LFACE_FONTSET_INDEX, fontset_name (fontset));
+      return 1;
+    }
+#endif	/* USE_FONT_BACKEND */
   if (fontset > 0)
     font_name = SDATA (fontset_ascii (fontset));
   else if (fontset == 0)
@@ -4592,6 +4758,18 @@
 
       if (STRINGP (LFACE_FONT (lface)))
 	font_name = LFACE_FONT (lface);
+#ifdef USE_FONT_BACKEND
+      else if (enable_font_backend)
+	{
+	  Lisp_Object entity = font_find_for_lface (f, &AREF (lface, 0), Qnil);
+
+	  if (NILP (entity))
+	    error ("No font matches the specified attribute");
+	  font_name = font_open_for_lface (f, &AREF (lface, 0), entity);
+	  if (NILP (font_name))
+	    error ("No font matches the specified attribute");
+	}
+#endif
       else
 	{
 	  /* Choose a font name that reflects LFACE's attributes and has
@@ -5357,6 +5535,10 @@
 	    free_face_fontset (f, face);
 	  if (face->gc)
 	    {
+#ifdef USE_FONT_BACKEND
+	      if (enable_font_backend && face->font_info)
+		font_done_for_face (f, face);
+#endif	/* USE_FONT_BACKEND */
 	      x_free_gc (f, face->gc);
 	      face->gc = 0;
 	    }
@@ -5418,6 +5600,10 @@
 	}
 #endif
       face->gc = x_create_gc (f, mask, &xgcv);
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend && face->font)
+	font_prepare_for_face (f, face);
+#endif	/* USE_FONT_BACKEND */
       UNBLOCK_INPUT;
     }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -5524,6 +5710,10 @@
 	  struct face *face = c->faces_by_id[i];
 	  if (face && face->gc)
 	    {
+#ifdef USE_FONT_BACKEND
+	      if (enable_font_backend && face->font_info)
+		font_done_for_face (c->f, face);
+#endif	/* USE_FONT_BACKEND */
 	      x_free_gc (c->f, face->gc);
 	      face->gc = 0;
 	    }
@@ -5850,6 +6040,43 @@
 
   return face->id;
 }
+
+#ifdef USE_FONT_BACKEND
+int
+face_for_font (f, font, base_face)
+     struct frame *f;
+     struct font *font;
+     struct face *base_face;
+{
+  struct face_cache *cache = FRAME_FACE_CACHE (f);
+  unsigned hash;
+  int i;
+  struct face *face;
+
+  xassert (cache != NULL);
+  base_face = base_face->ascii_face;
+  hash = lface_hash (base_face->lface);
+  i = hash % FACE_CACHE_BUCKETS_SIZE;
+
+  for (face = cache->buckets[i]; face; face = face->next)
+    {
+      if (face->ascii_face == face)
+	continue;
+      if (face->ascii_face == base_face
+	  && face->font_info == (struct font_info *) font)
+	return face->id;
+    }
+
+  /* If not found, realize a new face.  */
+  face = realize_non_ascii_face (f, -1, base_face);
+  face->font = font->font.font;
+  face->font_info = (struct font_info *) font;
+  face->font_info_id = 0;
+  face->font_name = font->font.full_name;
+  return face->id;
+}
+#endif	/* USE_FONT_BACKEND */
+
 #endif	/* HAVE_WINDOW_SYSTEM */
 
 /* Return the face id of the realized face for named face SYMBOL on
@@ -6451,6 +6678,10 @@
       free_all_realized_faces (Qnil);
     }
 
+#ifdef USE_FONT_BACKEND
+  font_update_sort_order (font_sort_order);
+#endif	/* USE_FONT_BACKEND */
+
   return Qnil;
 }
 
@@ -7425,6 +7656,9 @@
     {
       face->font = default_face->font;
       face->font_info_id = default_face->font_info_id;
+#ifdef USE_FONT_BACKEND
+      face->font_info = default_face->font_info;
+#endif	/* USE_FONT_BACKEND */
       face->font_name = default_face->font_name;
       face->fontset
 	= make_fontset_for_ascii_face (f, default_face->fontset, face);
@@ -7447,8 +7681,16 @@
 	fontset = default_face->fontset;
       if (fontset == -1)
 	abort ();
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+	font_load_for_face (f, face);
+      else
+#endif	/* USE_FONT_BACKEND */
       load_face_font (f, face);
-      face->fontset = make_fontset_for_ascii_face (f, fontset, face);
+      if (face->font)
+	face->fontset = make_fontset_for_ascii_face (f, fontset, face);
+      else
+	face->fontset = -1;
     }
 
   /* Load colors, and set remaining attributes.  */