changeset 91261:2e5bb6a0a787

(font_parse_fcname): Default weight and slant to normal. (font_score): Prefer normal fonts if weight or slant unspecified. (font_score) [WINDOWSNT]: Scale weight difference down to closer match freetype scores.
author Jason Rumney <jasonr@gnu.org>
date Thu, 20 Dec 2007 10:40:31 +0000
parents 75f89f349f70
children 7fad8cb1e910
files src/font.c
diffstat 1 files changed, 38 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/font.c	Thu Dec 20 00:10:57 2007 +0000
+++ b/src/font.c	Thu Dec 20 10:40:31 2007 +0000
@@ -1248,6 +1248,8 @@
   char *p0, *p1;
   int len = strlen (name);
   char *copy;
+  int weight_set = 0;
+  int slant_set = 0;
 
   if (len == 0)
     return -1;
@@ -1301,12 +1303,14 @@
 	      || memcmp (p0 + 1, "black", 5) == 0)
 	    {
 	      ASET (font, FONT_WEIGHT_INDEX, val);
+              weight_set = 1;
 	    }
 	  else if (memcmp (p0 + 1, "roman", 5) == 0
 		   || memcmp (p0 + 1, "italic", 6) == 0
 		   || memcmp (p0 + 1, "oblique", 7) == 0)
 	    {
 	      ASET (font, FONT_SLANT_INDEX, val);
+              slant_set = 1;
 	    }
 	  else if (memcmp (p0 + 1, "charcell", 8) == 0
 		   || memcmp (p0 + 1, "mono", 4) == 0
@@ -1338,6 +1342,11 @@
 	    {
 	      if (prop >= 0 && prop < FONT_EXTRA_INDEX)
 		{
+                  if (prop == FONT_WEIGHT_INDEX)
+                    weight_set = 1;
+                  else if (prop == FONT_SLANT_INDEX)
+                    slant_set = 1;
+
 		  ASET (font, prop, val);
 		}
 	      else
@@ -1347,6 +1356,11 @@
       p0 = p1;
     }
 
+  if (!weight_set)
+    ASET (font, FONT_WEIGHT_INDEX, build_string ("normal"));
+  if (!slant_set)
+    ASET (font, FONT_SLANT_INDEX, build_string ("normal"));
+
   return 0;
 }
 
@@ -1910,14 +1924,22 @@
   for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
     {
       Lisp_Object entity_val = AREF (entity, i);
-
-      if (! NILP (spec_prop[i]) && ! EQ (spec_prop[i], entity_val))
+      Lisp_Object spec_val = spec_prop[i];
+
+      /* If weight and slant are unspecified, score normal lower (low wins). */
+      if (NILP (spec_val))
+        {
+          if (i == FONT_WEIGHT_INDEX || i == FONT_SLANT_INDEX)
+            spec_val = prop_name_to_numeric (i, build_string ("normal"));
+        }
+
+      if (! NILP (spec_val) && ! EQ (spec_val, entity_val))
 	{
 	  if (! INTEGERP (entity_val))
 	    score |= 127 << sort_shift_bits[i];
 	  else
 	    {
-	      int diff = XINT (entity_val) - XINT (spec_prop[i]);
+	      int diff = XINT (entity_val) - XINT (spec_val);
 
 	      if (diff < 0)
 		diff = - diff;
@@ -1927,6 +1949,19 @@
 		      && diff > FONT_PIXEL_SIZE_QUANTUM)
 		    score |= min (diff, 127) << sort_shift_bits[i];
 		}
+#ifdef WINDOWSNT
+              else if (i == FONT_WEIGHT_INDEX)
+                {
+                  /* Windows uses a much wider range for weight (100-900)
+                     compared with freetype (0-210), so scale down the
+                     difference.  A more general way of doing this
+                     would be to look up the values of regular and bold
+                     and/or light and calculate the scale factor from them,
+                     but the lookup would be expensive, and if only Windows
+                     needs it, not worth the effort.  */
+                  score |= min (diff / 4, 127) << sort_shift_bits[i];
+                }
+#endif
 	      else
 		score |= min (diff, 127) << sort_shift_bits[i];
 	    }