emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/font.c,v


From: Chong Yidong
Subject: [Emacs-diffs] Changes to emacs/src/font.c,v
Date: Tue, 10 Jun 2008 20:01:07 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Chong Yidong <cyd>      08/06/10 20:01:06

Index: font.c
===================================================================
RCS file: /sources/emacs/emacs/src/font.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -b -r1.42 -r1.43
--- font.c      10 Jun 2008 02:09:15 -0000      1.42
+++ font.c      10 Jun 2008 20:01:06 -0000      1.43
@@ -1323,121 +1323,252 @@
                  f[XLFD_REGISTRY_INDEX]);
 }
 
-/* Parse NAME (null terminated) as Fonconfig's name format and store
-   information in FONT (font-spec or font-entity).  If NAME is
-   successfully parsed, return 0.  Otherwise return -1.  */
+/* Parse NAME (null terminated) and store information in FONT
+   (font-spec or font-entity).  NAME is supplied in either the
+   Fontconfig or GTK font name format.  If NAME is successfully
+   parsed, return 0.  Otherwise return -1.
+
+   The fontconfig format is
+
+    FAMILY[-SIZE][:PROP1[=VAL1][:PROP2[=VAL2]...]]
+
+   The GTK format is
+
+    FAMILY [PROPS...] [SIZE]
+
+   This function tries to guess which format it is.  */
 
 int
 font_parse_fcname (name, font)
      char *name;
      Lisp_Object font;
 {
-  char *p0, *p1;
+  char *p, *q;
+  char *size_beg = NULL, *size_end = NULL;
+  char *props_beg = NULL, *family_end = NULL;
   int len = strlen (name);
-  char *copy;
 
   if (len == 0)
     return -1;
-  /* It is assured that (name[0] && name[0] != '-').  */
-  if (name[0] == ':')
-    p0 = name;
-  else
-    {
-      Lisp_Object family;
-      double point_size;
 
-      for (p0 = name + 1; *p0 && (*p0 != '-' && *p0 != ':'); p0++)
-       if (*p0 == '\\' && p0[1])
-         p0++;
-      family = font_intern_prop (name, p0 - name, 1);
-      if (*p0 == '-')
+  for (p = name; *p; p++)
        {
-         if (! isdigit (p0[1]))
-           return -1;
-         point_size = strtod (p0 + 1, &p1);
-         if (*p1 && *p1 != ':')
-           return -1;
-         ASET (font, FONT_SIZE_INDEX, make_float (point_size));
-         p0 = p1;
+      if (*p == '\\' && p[1])
+       p++;
+      else if (*p == ':')
+       {
+         family_end = p;
+         props_beg = p + 1;
+         break;
        }
+      else if (*p == '-')
+       {
+         int size_found = 1;
+         for (q = p + 1; *q && *q != ':'; q++)
+           if (! isdigit(*q))
+             {
+               size_found = 0;
+               break;
+             }
+         if (size_found)
+           {
+             family_end = p;
+             size_beg = p + 1;
+             size_end = q;
+             break;
+           }
+       }
+    }
+
+  if (family_end)
+    {
+      /* A fontconfig name with size and/or property data.  */
+      if (family_end > name)
+       {
+         Lisp_Object family;
+         family = font_intern_prop (name, family_end - name, 1);
       ASET (font, FONT_FAMILY_INDEX, family);
     }
+      if (size_beg)
+       {
+         double point_size = strtod (size_beg, &size_end);
+         ASET (font, FONT_SIZE_INDEX, make_float (point_size));
+         if (*size_end == ':' && size_end[1])
+           props_beg = size_end + 1;
+       }
+      if (props_beg)
+       {
+         /* Now parse ":KEY=VAL" patterns.  Store known keys and values in
+            extra, copy unknown ones to COPY.  It is stored in extra slot by
+            the key QCfc_unknown_spec.  */
+         char *copy;
 
-  len -= p0 - name;
-  copy = alloca (len + 1);
+         name = copy = alloca (name + len - props_beg);
   if (! copy)
     return -1;
-  name = copy;
 
-  /* Now parse ":KEY=VAL" patterns.  Store known keys and values in
-     extra, copy unknown ones to COPY.  It is stored in extra slot by
-     the key QCfc_unknown_spec.  */
-  while (*p0)
+         p = props_beg;
+         while (*p)
     {
-      Lisp_Object key, val;
-      int prop;
+             Lisp_Object val;
+             int word_len, prop;
+
+#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
 
-      for (p1 = p0 + 1; *p1 && *p1 != '=' && *p1 != ':'; p1++);
-      if (*p1 != '=')
+             for (q = p + 1; *q && *q != '=' && *q != ':'; q++);
+             word_len = q - p;
+             if (*q != '=')
        {
          /* Must be an enumerated value.  */
-         val = font_intern_prop (p0 + 1, p1 - p0 - 1, 1);
-         if (memcmp (p0 + 1, "light", 5) == 0
-             || memcmp (p0 + 1, "medium", 6) == 0
-             || memcmp (p0 + 1, "demibold", 8) == 0
-             || memcmp (p0 + 1, "bold", 4) == 0
-             || memcmp (p0 + 1, "black", 5) == 0)
+                 val = font_intern_prop (p, q - p, 1);
+                 if (PROP_MATCH ("light", 5)
+                     || PROP_MATCH ("medium", 6)
+                     || PROP_MATCH ("demibold", 8)
+                     || PROP_MATCH ("bold", 4)
+                     || PROP_MATCH ("black", 5))
            FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val);
-         else if (memcmp (p0 + 1, "roman", 5) == 0
-                  || memcmp (p0 + 1, "italic", 6) == 0
-                  || memcmp (p0 + 1, "oblique", 7) == 0)
+                 else if (PROP_MATCH ("roman", 5)
+                          || PROP_MATCH ("italic", 6)
+                          || PROP_MATCH ("oblique", 7))
            FONT_SET_STYLE (font, FONT_SLANT_INDEX, val);
-         else if (memcmp (p0 + 1, "charcell", 8) == 0
-                  || memcmp (p0 + 1, "mono", 4) == 0
-                  || memcmp (p0 + 1, "proportional", 12) == 0)
-           {
-             int spacing = (p0[1] == 'c' ? FONT_SPACING_CHARCELL
-                            : p0[1] == 'm' ? FONT_SPACING_MONO
-                            : FONT_SPACING_PROPORTIONAL);
-             ASET (font, FONT_SPACING_INDEX, make_number (spacing));
-           }
+                 else if (PROP_MATCH ("charcell", 8))
+                   ASET (font, FONT_SPACING_INDEX,
+                         make_number (FONT_SPACING_CHARCELL));
+                 else if (PROP_MATCH ("mono", 4))
+                   ASET (font, FONT_SPACING_INDEX,
+                         make_number (FONT_SPACING_MONO));
+                 else if (PROP_MATCH ("proportional", 12))
+                   ASET (font, FONT_SPACING_INDEX,
+                         make_number (FONT_SPACING_PROPORTIONAL));
          else
            {
-             /* unknown key */
-             bcopy (p0, copy, p1 - p0);
-             copy += p1 - p0;
+                     /* Unknown key  */
+                     bcopy (p, copy, word_len);
+                     copy += word_len;
            }
        }
-      else
+             else /* KEY=VAL pairs  */
        {
-         char *keyhead = p0;
+                 Lisp_Object key;
+                 char *keyhead = p;
 
-         if (memcmp (p0 + 1, "pixelsize=", 10) == 0)
+                 if (PROP_MATCH ("pixelsize=", 10))
            prop = FONT_SIZE_INDEX;
          else
            {
-             key = font_intern_prop (p0, p1 - p0, 1);
+                     key = font_intern_prop (p, q - p, 1);
              prop = get_font_prop_index (key);
            }
-         p0 = p1 + 1;
-         for (p1 = p0; *p1 && *p1 != ':'; p1++);
-         val = font_intern_prop (p0, p1 - p0, 0);
+                 p = q + 1;
+                 for (q = p; *q && *q != ':'; q++);
+
+                 val = font_intern_prop (p, word_len, 0);
          if (! NILP (val))
            {
-             if (prop >= FONT_FOUNDRY_INDEX && prop < FONT_EXTRA_INDEX)
-               ASET (font, prop, font_prop_validate (prop, Qnil, val));
+                     if (prop >= FONT_FOUNDRY_INDEX
+                         && prop < FONT_EXTRA_INDEX)
+                       ASET (font, prop,
+                             font_prop_validate (prop, Qnil, val));
              else if (prop >= 0)
                Ffont_put (font, key, val);
              else
-               bcopy (keyhead, copy, p1 - keyhead);
-             copy += p1 - keyhead;
+                       bcopy (keyhead, copy, q - keyhead);
+                     copy += q - keyhead;
            }
        }
-      p0 = p1;
+             p = *q ? q + 1 : q;
+#undef PROP_MATCH
     }
   if (name != copy)
     font_put_extra (font, QCfc_unknown_spec,
                    make_unibyte_string (name, copy - name));
+       }
+    }
+  else
+    {
+      /* Either a fontconfig-style name with no size and property
+        data, or a GTK-style name.  */
+      Lisp_Object prop;
+      int word_len, prop_found = 0;
+
+      for (p = name; *p; p = *q ? q + 1 : q)
+       {
+         if (isdigit (*p))
+           {
+             char *r;
+             int size_found = 1;
+             for (q = p + 1; *q && *q != ' '; q++)
+               if (! isdigit (*q))
+                 {
+                   size_found = 0;
+                   break;
+                 }
+             if (size_found)
+               {
+                 double point_size = strtod (p, &q);
+                 ASET (font, FONT_SIZE_INDEX, make_float (point_size));
+                 continue;
+               }
+           }
+
+         for (q = p + 1; *q && *q != ' '; q++)
+           if (*q == '\\' && q[1])
+             q++;
+         word_len = q - p;
+
+#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
+
+         if (PROP_MATCH ("Ultra-Light", 11))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("ultra-light", 11, 1);
+             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
+           }
+         else if (PROP_MATCH ("Light", 5))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("light", 5, 1);
+             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
+           }
+         else if (PROP_MATCH ("Semi-Bold", 9))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("semi-bold", 9, 1);
+             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
+           }
+         else if (PROP_MATCH ("Bold", 4))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("bold", 4, 1);
+             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
+           }
+         else if (PROP_MATCH ("Italic", 6))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("italic", 4, 1);
+             FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
+           }
+         else if (PROP_MATCH ("Oblique", 7))
+           {
+             prop_found = 1;
+             prop = font_intern_prop ("oblique", 7, 1);
+             FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
+           }
+         else {
+           if (prop_found)
+             return -1; /* Unknown property in GTK-style font name.  */
+           family_end = q;
+         }
+       }
+#undef PROP_MATCH
+
+      if (family_end)
+       {
+         Lisp_Object family;
+         family = font_intern_prop (name, family_end - name, 1);
+         ASET (font, FONT_FAMILY_INDEX, family);
+       }
+    }
 
   return 0;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]