emacs-devel
[Top][All Lists]
Advanced

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

w32 font parsing patch


From: Michael Mauger
Subject: w32 font parsing patch
Date: Mon, 5 Apr 2004 21:37:09 -0700 (PDT)

Below is an updated (large) patch which corrects the parsing of font
specifications under w32.  The current code handles several special cases
of XLFDs and a W32-specific format.  It then treats them all as a fully
qualified XLFD (even the w32-specific form) when it tries to match. 
Obviously, the results are less than ideal.

The patch below has been proposed before (although this version has been
updated to reflect other changes to the w32 code).  It addresses the
issue described above and avoids some intermittent crashes. 
Specifically, the patch does the following:

* Translates all font specifications into a fully qualified XLFD form
(including the w32-specific form).  It uses a heuristic which works for
all the original special cases and seems to work reasonably for the
remaining cases.  The next-to-last wildcard (or the last one, if there is
only one wildcard) is expanded into multiple wildcards to fill out the
XLFD string.  

* If there are no wildcards in the face name portion of the XLFD string,
it is passed to w32 to restrict font enumeration rather than enumerating
all of the installed fonts and then excluding them based on the font name
during the string match.  This significantly improves performance in some
cases.

I first detected problems with the font parsing when I used
`char-displayable-p' on 16-bit values.  The problem was that the
character set was not being properly identified in the XLFD specification
and the character set was defaulting incorrectly.

[Jason, we've discussed this patch before.  I wanted you to have the
latest version and to let you know that I still find it necessary.]

-- Michael


Index: emacs/src/w32fns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32fns.c,v
retrieving revision 1.229
diff -u -r1.229 w32fns.c
--- emacs/src/w32fns.c  11 Mar 2004 00:26:21 -0000      1.229
+++ emacs/src/w32fns.c  13 Mar 2004 02:09:34 -0000
@@ -4377,6 +4377,23 @@
 }

 
+/* XLFD fields */
+#define XLFD_FOUNDRY   (0)
+#define XLFD_FAMILY    (1)
+#define XLFD_WEIGHT    (2)
+#define XLFD_SLANT     (3)
+#define XLFD_SWIDTH    (4)
+#define XLFD_ADSTYLE   (5)
+#define XLFD_PIXELSIZE (6)
+#define XLFD_POINTSIZE (7)
+#define XLFD_RESX      (8)
+#define XLFD_RESY      (9)
+#define XLFD_SPACING   (10)
+#define XLFD_AVGWIDTH  (11)
+#define XLFD_REGISTRY  (12)
+#define XLFD_ENCODING  (13)
+#define XLFD_NUM_FIELDS        (14)
+
 /* Return the charset portion of a font name.  */
 char * xlfd_charset_of_font (char * fontname)
 {
@@ -4399,6 +4416,8 @@
 struct font_info *w32_load_bdf_font (struct frame *f, char *fontname,
                                      int size, char* filename);
 static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int
max_names);
+static BOOL w32_normalize_xlfd (char * normal, char * orig);
+static char * w32_get_xlfd_field (char * buf, char * normal, int field);
 static BOOL w32_to_x_font (LOGFONT * lplf, char * lpxstr, int len,
                           char * charset);
 static BOOL x_to_w32_font (char *lpxstr, LOGFONT *lplogfont);
@@ -4694,6 +4713,218 @@
  *      )
  */

+static BOOL
+w32_normalize_xlfd (normal, orig)
+     char * normal;
+     char * orig;
+{
+  int nfields;
+  char * field[XLFD_NUM_FIELDS];
+  char * buf;
+  int i;
+  char * this;
+  char * next;
+  char widthbuf[10];
+
+  /* Make a copy of the XLFD string that we can modify. */
+  buf = alloca (strlen (orig) + 1);
+  strcpy (buf, orig);
+
+  /* Parse the string as an XLFD spec if it starts with a hyphen. */
+  if (*buf == '-')
+    {
+      int lastwild;
+
+      /* break XLFD string on hyphens */
+      next = buf;
+      lastwild = -1;
+      for (nfields = 0; nfields < XLFD_NUM_FIELDS; ++nfields)
+       {
+         this = next + 1;
+
+         /* Locate the next hyphen */
+         next = strchr (this, '-');
+
+         /* Terminate this segment */
+         if (next != NULL)
+           *next = '\0';
+
+         /* Save this segment. */
+         field[nfields] = this;
+
+         /* Break out if there are no more segments. */
+         if (next == NULL)
+           {
+             ++nfields;
+             break;
+           }
+
+         /* Is this segment a wildcrd?
+
+         This is done after we have bailed out on the last
+         segment.  Thus `lastwild' is always < `fields'. */
+         if (strcmp (field[nfields], "*") == 0)
+           lastwild = nfields;
+       }
+
+      /* If there's still more to parse, return an error. */
+      if (next) return (FALSE);
+
+      /* If there are not enough fields, then expand the last
+        wildcard to fill out the specification. */
+      if (nfields < XLFD_NUM_FIELDS)
+       {
+         /* If there was a wildcard, expand it out. */
+         if (lastwild > -1)
+           {
+             /* Copy what's after the wildcard to the end. */
+             for (i = 1; i <= nfields - lastwild; ++i)
+               field[XLFD_NUM_FIELDS - i] = field[nfields - i];
+
+             /* Fill in the middle with wildcards. */
+             for (i = 1; i < XLFD_NUM_FIELDS - nfields; ++i)
+               field[lastwild + i] = "*";
+           }
+
+         /* There were no wildcards, pad it with wildcards. */
+         else
+           {
+             for (i = nfields; i < XLFD_NUM_FIELDS; ++i)
+               field[i] = "*";
+           }
+
+         /* The font spec is now complete. */
+         nfields = XLFD_NUM_FIELDS;
+       }
+    }
+  /* Provide a simple escape mechanism for specifying Windows font names
+     directly in this format:
+     "<font name>[:height in pixels[:width in pixels[:weight]]]"
+  */
+  else
+    {
+      /* Pre-fill the fields with wildcards. */
+      for (i = 0; i < XLFD_NUM_FIELDS; ++i)
+       field[i] = "*";
+
+      /* Parse off the font name. */
+      this = buf;
+      next = strchr (this, ':');
+      if (next != NULL)
+       *next = '\0';
+
+      if (this[1] != '\0')
+       field[XLFD_FAMILY] = this;
+
+      if (next == NULL)
+       this = NULL;
+      else
+       this = next + 1;
+
+      /* Parse off the height */
+      if (this != NULL)
+       {
+         next = strchr (this, ':');
+         if (next != NULL)
+           *next = '\0';
+
+         if (this[1] != '\0')
+           field[XLFD_PIXELSIZE] = this;
+
+         if (next == NULL)
+           this = NULL;
+         else
+           this = next + 1;
+       }
+
+      /* Parse off the width */
+      if (this != NULL)
+       {
+         next = strchr (this, ':');
+         if (next != NULL)
+           *next = '\0';
+
+         if (this[1] != '\0')
+           {
+             strcpy (widthbuf, this);
+             strcat (widthbuf, "0");
+             field[XLFD_AVGWIDTH] = widthbuf;
+           }
+
+         if (next == NULL)
+           this = NULL;
+         else
+           this = next + 1;
+       }
+
+      /* Parse off the weight */
+      if (this != NULL)
+       {
+         next = strchr (this, ':');
+         if (next != NULL)
+           *next = '\0';
+
+         if (this[1] != '\0')
+           field[XLFD_WEIGHT] = this;
+
+         if (next == NULL)
+           this = NULL;
+         else
+           this = next + 1;
+       }
+
+      /* If there is more the format is bad */
+      if (this != NULL)
+       return (FALSE);
+
+      nfields = XLFD_NUM_FIELDS;
+    }
+
+  /* Format a complete XLFD string */
+  normal[0] = '\0';
+  for (i = 0; i < nfields; ++i)
+    {
+      strcat (normal, "-");
+      strcat (normal, field[i]);
+    }
+
+  return (TRUE);
+}
+
+static char *
+w32_get_xlfd_field (buf, normal, field)
+     char * buf;
+     char * normal;
+     int field;
+{
+  char * this;
+  char * next;
+
+  /* Skip to the desired field */
+  next = normal;
+  do
+    {
+      this = next + 1;
+      next = strchr (this, '-');
+    }
+  while (--field >= 0);
+
+  /* Copy the text of the field to the buf. */
+  if (next == NULL)
+    {
+      strcpy (buf, this);
+    }
+  else
+    {
+      int len = next - this;
+
+      strncpy (buf, this, len);
+      buf[len] = '\0';
+    }
+
+  return (buf);
+}
+
 static LONG
 x_to_w32_weight (lpw)
      char * lpw;
@@ -5193,7 +5424,7 @@
   else if (lplogfont->lfOutPrecision == OUT_STROKE_PRECIS)
     fonttype = "outline";
   else
-    fonttype = "unknown";
+    fonttype = "*";

   setup_coding_system (Fcheck_coding_system (Vlocale_coding_system),
                        &coding);
@@ -5209,6 +5440,8 @@
   decode_coding (&coding, lplogfont->lfFaceName, fontname,
                  strlen(lplogfont->lfFaceName), bufsz - 1);
   *(fontname + coding.produced) = '\0';
+  if (coding.produced == 0)
+    strcpy (fontname, "*");

   /* Replace dashes with underscores so the dashes are not
      misinterpreted.  */
@@ -5261,7 +5494,8 @@
      char * lpxstr;
      LOGFONT * lplogfont;
 {
-  struct coding_system coding;
+  char * field;
+  char * xstrbuf;

   if (!lplogfont) return (FALSE);

@@ -5286,159 +5520,114 @@
   if (!lpxstr)
     return FALSE;

-  /* Provide a simple escape mechanism for specifying Windows font names
-   * directly -- if font spec does not beginning with '-', assume this
-   * format:
-   *   "<font name>[:height in pixels[:width in pixels[:weight]]]"
-   */
-
-  if (*lpxstr == '-')
-    {
-      int fields, tem;
-      char name[50], weight[20], slant, pitch, pixels[10], height[10],
-        width[10], resy[10], remainder[50];
-      char * encoding;
-      int dpi = (int) one_w32_display_info.resy;
-
-      fields = sscanf (lpxstr,
-                     
"-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%9[^-]-%c-%9[^-]-%49s",
-                      name, weight, &slant, pixels, height, resy, &pitch, 
width,
remainder);
-      if (fields == EOF)
-       return (FALSE);
-
-      /* In the general case when wildcards cover more than one field,
-        we don't know which field is which, so don't fill any in.
-        However, we need to cope with this particular form, which is
-        generated by font_list_1 (invoked by try_font_list):
-            "-raster-6x10-*-gb2312*-*"
-        and make sure to correctly parse the charset field.  */
-      if (fields == 3)
-       {
-         fields = sscanf (lpxstr,
-                          "-%*[^-]-%49[^-]-*-%49s",
-                          name, remainder);
-       }
-      else if (fields < 9)
-       {
-         fields = 0;
-         remainder[0] = 0;
-       }
-
-      if (fields > 0 && name[0] != '*')
-        {
-         int bufsize;
-         unsigned char *buf;
-
-          setup_coding_system
-            (Fcheck_coding_system (Vlocale_coding_system), &coding);
-         coding.src_multibyte = 1;
-         coding.dst_multibyte = 1;
-         /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
-            encode_coding_iso2022 trying to dereference a null pointer.  */
-         coding.composing = COMPOSITION_DISABLED;
-         if (coding.type == coding_type_iso2022)
-           coding.flags |= CODING_FLAG_ISO_SAFE;
-         bufsize = encoding_buffer_size (&coding, strlen (name));
-         buf = (unsigned char *) alloca (bufsize);
-          coding.mode |= CODING_MODE_LAST_BLOCK;
-          encode_coding (&coding, name, buf, strlen (name), bufsize);
-         if (coding.produced >= LF_FACESIZE)
-           coding.produced = LF_FACESIZE - 1;
-         buf[coding.produced] = 0;
-         strcpy (lplogfont->lfFaceName, buf);
-       }
-      else
-        {
-         lplogfont->lfFaceName[0] = '\0';
-       }
-
-      fields--;
-
-      lplogfont->lfWeight = x_to_w32_weight ((fields > 0 ? weight :
""));
+   /* Convert font pattern to a normalized XLFD string */
+   xstrbuf = alloca (strlen (lpxstr)
+                   + XLFD_NUM_FIELDS*2 + 1); /* enough extra space for 14 "-*" 
*/
+   if (!w32_normalize_xlfd (xstrbuf, lpxstr))
+     return (FALSE);
+
+   field = alloca (strlen (xstrbuf) + 1);
+
+   /* Copy the name portion to the facename. */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_FAMILY);
+   if (strcmp (field, "*") != 0)
+     {
+       int bufsize;
+       unsigned char *buf;
+       struct coding_system coding;
+
+       setup_coding_system
+        (Fcheck_coding_system (Vlocale_coding_system), &coding);
+       coding.src_multibyte = 1;
+       coding.dst_multibyte = 1;
+       /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
+         encode_coding_iso2022 trying to dereference a null pointer.  */
+       coding.composing = COMPOSITION_DISABLED;
+       if (coding.type == coding_type_iso2022)
+        coding.flags |= CODING_FLAG_ISO_SAFE;
+       bufsize = encoding_buffer_size (&coding, strlen (field));
+       buf = (unsigned char *) alloca (bufsize);
+       coding.mode |= CODING_MODE_LAST_BLOCK;
+       encode_coding (&coding, field, buf, strlen (field), bufsize);
+       if (coding.produced >= LF_FACESIZE)
+        coding.produced = LF_FACESIZE - 1;
+       buf[coding.produced] = 0;
+       strcpy (lplogfont->lfFaceName, buf);
+     }
+   else
+     {
+       lplogfont->lfFaceName[0] = '\0';
+     }
+
+   /* Copy over the weight. */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_WEIGHT);
+   lplogfont->lfWeight = x_to_w32_weight (field);
+
+   /* Copy over the italic flag */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_SLANT);
+   lplogfont->lfItalic = (field[0] == 'i');
+
+   /* Copy over the pixel height. */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_PIXELSIZE);
+   {
+     int pixelsize = atoi (field);
+
+     if (pixelsize > 0)
+       lplogfont->lfHeight = pixelsize;
+   }
+
+   /* Copy over the X- and Y-resolution as height. */
+   if (lplogfont->lfHeight == 0)
+     {
+       int resy = 0;
+       int pointsize = 0;
+
+       w32_get_xlfd_field (field, xstrbuf, XLFD_RESY);
+       if (strcmp (field, "*") != 0)
+       resy = atoi (field);
+       if (resy <= 0)
+       resy = (int) one_w32_display_info.resy;
+
+       w32_get_xlfd_field (field, xstrbuf, XLFD_POINTSIZE);
+       if (strcmp (field, "*") != 0)
+       pointsize = atoi (field);
+       if (pointsize > 0)
+       lplogfont->lfHeight = (pointsize * resy) / 720;
+     }
+
+   /* This makes TrueType fonts work better. */
+   lplogfont->lfHeight = - abs (lplogfont->lfHeight);
+
+   /* Copy over the pitch. */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_SPACING);
+   lplogfont->lfPitchAndFamily =
+     (field[0] == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
+
+   /* Copy over the point size. */
+   w32_get_xlfd_field (field, xstrbuf, XLFD_AVGWIDTH);
+   {
+     int avgwidth = atoi (field);
+
+     if (avgwidth > 0)
+       lplogfont->lfWidth = avgwidth / 10;
+   }
+
+   /* Copy over the character set encoding. */
+   {
+     char encoding[50];

-      fields--;
+     w32_get_xlfd_field (field, xstrbuf, XLFD_REGISTRY);
+     strcpy (encoding, field);

-      lplogfont->lfItalic = (fields > 0 && slant == 'i');
-
-      fields--;
-
-      if (fields > 0 && pixels[0] != '*')
-       lplogfont->lfHeight = atoi (pixels);
-
-      fields--;
-      fields--;
-      if (fields > 0 && resy[0] != '*')
+     w32_get_xlfd_field (field, xstrbuf, XLFD_ENCODING);
+     if (strcmp (field, "*") != 0)
         {
-          tem = atoi (resy);
-          if (tem > 0) dpi = tem;
+       strcat (encoding, "-");
+       strcat (encoding, field);
         }

-      if (fields > -1 && lplogfont->lfHeight == 0 && height[0] != '*')
-       lplogfont->lfHeight = atoi (height) * dpi / 720;
-
-      if (fields > 0)
-      lplogfont->lfPitchAndFamily =
-       (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
-
-      fields--;
-
-      if (fields > 0 && width[0] != '*')
-       lplogfont->lfWidth = atoi (width) / 10;
-
-      fields--;
-
-      /* Strip the trailing '-' if present. (it shouldn't be, as it
-         fails the test against xlfd-tight-regexp in fontset.el).  */
-      {
-       int len = strlen (remainder);
-       if (len > 0 && remainder[len-1] == '-')
-         remainder[len-1] = 0;
-      }
-      encoding = remainder;
-#if 0
-      if (strncmp (encoding, "*-", 2) == 0)
-       encoding += 2;
-#endif
-      lplogfont->lfCharSet = x_to_w32_charset (encoding);
-    }
-  else
-    {
-      int fields;
-      char name[100], height[10], width[10], weight[20];
-
-      fields = sscanf (lpxstr,
-                      "%99[^:]:%9[^:]:%9[^:]:%19s",
-                      name, height, width, weight);
-
-      if (fields == EOF) return (FALSE);
-
-      if (fields > 0)
-        {
-         strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
-         lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
-       }
-      else
-        {
-         lplogfont->lfFaceName[0] = 0;
-       }
-
-      fields--;
-
-      if (fields > 0)
-       lplogfont->lfHeight = atoi (height);
-
-      fields--;
-
-      if (fields > 0)
-       lplogfont->lfWidth = atoi (width);
-
-      fields--;
-
-      lplogfont->lfWeight = x_to_w32_weight ((fields > 0 ? weight :
""));
-    }
-
-  /* This makes TrueType fonts work better. */
-  lplogfont->lfHeight = - abs (lplogfont->lfHeight);
+     lplogfont->lfCharSet = x_to_w32_charset (encoding);
+   }

   return (TRUE);
 }
@@ -5447,118 +5636,81 @@
    return the pixel height. If no pixel height is specified, calculate
    one from the point height, or if that isn't defined either, return
    0 (which usually signifies a scalable font).
+
+   `fontname' *must* be a fully qualified XLFD spec.
 */
 static int
 xlfd_strip_height (char *fontname)
 {
-  int pixel_height, field_number;
-  char *read_from, *write_to;
+  int pixel_height, point_size;
+  int field_number;
+  char * read_from;
+  char * write_to;
+  char * start;
+  char c;

   xassert (fontname);

-  pixel_height = field_number = 0;
-  write_to = NULL;
+  pixel_height = point_size = 0;

   /* Look for height fields.  */
-  for (read_from = fontname; *read_from; read_from++)
+  field_number = -1;
+  for (read_from = write_to = fontname; *read_from; read_from++)
     {
+      /* If we need to copy this character, copy it. */
+      if (read_from > write_to)
+       *write_to = *read_from;
+      ++write_to;
+
+      /* Is this the start of a field? */
       if (*read_from == '-')
         {
           field_number++;
-          if (field_number == 7) /* Pixel height.  */
+
+          if (field_number == XLFD_PIXELSIZE)
             {
-              read_from++;
-              write_to = read_from;
+             start = ++read_from;

               /* Find end of field.  */
               for (;*read_from && *read_from != '-'; read_from++)
                 ;

-              /* Split the fontname at end of field.  */
-              if (*read_from)
-                {
-                  *read_from = '\0';
-                  read_from++;
-                }
-              pixel_height = atoi (write_to);
-              /* Blank out field. */
-              if (read_from > write_to)
-                {
-                  *write_to = '-';
-                  write_to++;
-                }
-              /* If the pixel height field is at the end (partial xlfd),
-                 return now.  */
-              else
-                return pixel_height;
-
-              /* If we got a pixel height, the point height can be
-                 ignored. Just blank it out and break now.  */
-              if (pixel_height)
-                {
-                  /* Find end of point size field.  */
-                  for (; *read_from && *read_from != '-'; read_from++)
-                    ;
-
-                  if (*read_from)
-                    read_from++;
-
-                  /* Blank out the point size field.  */
-                  if (read_from > write_to)
-                    {
-                      *write_to = '-';
-                      write_to++;
-                    }
-                  else
-                    return pixel_height;
-
-                  break;
-                }
-              /* If the point height is already blank, break now.  */
-              if (*read_from == '-')
-                {
-                  read_from++;
-                  break;
-                }
+              /* Terminate the field and evaluate.  */
+             c = *read_from;
+             *read_from = '\0';
+
+              pixel_height = atoi (start);
+
+             /* Put the original terminator back,
+                and prepare to re-read it. */
+             *read_from-- = c;
             }
-          else if (field_number == 8)
+          else if (field_number == XLFD_POINTSIZE)
             {
-              /* If we didn't get a pixel height, try to get the point
-                 height and convert that.  */
-              int point_size;
-              char *point_size_start = read_from++;
+              start = ++read_from;

               /* Find end of field.  */
               for (; *read_from && *read_from != '-'; read_from++)
                 ;

-              if (*read_from)
-                {
-                  *read_from = '\0';
-                  read_from++;
-                }
-
-              point_size = atoi (point_size_start);
-
-              /* Convert to pixel height. */
-              pixel_height = point_size
-                           * one_w32_display_info.height_in / 720;
-
-              /* Blank out this field and break.  */
-              *write_to = '-';
-              write_to++;
-              break;
+             /* Terminate the field and evaluate. */
+             c = *read_from;
+             *read_from = '\0';
+
+              point_size = atoi (start);
+
+             /* Put the original terminator back,
+                and prepare to re-read it. */
+             *read_from-- = c;
             }
         }
     }

-  /* Shift the rest of the font spec into place.  */
-  if (write_to && read_from > write_to)
-    {
-      for (; *read_from; read_from++, write_to++)
-        *write_to = *read_from;
-      *write_to = '\0';
-    }
+  *write_to = '\0';
+
+  /* If pixel_size hasn't been set, but point_size has, use it. */
+  if (pixel_height == 0 && point_size > 0)
+    pixel_height = point_size * one_w32_display_info.height_in / 720;

   return pixel_height;
 }
@@ -5569,31 +5721,18 @@
     char * fontname;
     char * pattern;
 {
-  char *regex = alloca (strlen (pattern) * 2 + 3);
+  int pattern_len = strlen (pattern) + XLFD_NUM_FIELDS*2 + 1;
+  char *full_pattern = alloca (pattern_len);
+  char *regex;
   char *font_name_copy = alloca (strlen (fontname) + 1);
   char *ptr;

   /* Copy fontname so we can modify it during comparison.  */
   strcpy (font_name_copy, fontname);

-  ptr = regex;
-  *ptr++ = '^';
-
-  /* Turn pattern into a regexp and do a regexp match.  */
-  for (; *pattern; pattern++)
-    {
-      if (*pattern == '?')
-        *ptr++ = '.';
-      else if (*pattern == '*')
-        {
-          *ptr++ = '.';
-          *ptr++ = '*';
-        }
-      else
-        *ptr++ = *pattern;
-    }
-  *ptr = '$';
-  *(ptr + 1) = '\0';
+  /* Expand pattern into a full XFLD pattern */
+  if (!w32_normalize_xlfd (full_pattern, pattern))
+    return (FALSE);

   /* Strip out font heights and compare them seperately, since
      rounding error can cause mismatches. This also allows a
@@ -5604,7 +5743,7 @@
     int font_height, pattern_height;

     font_height = xlfd_strip_height (font_name_copy);
-    pattern_height = xlfd_strip_height (regex);
+    pattern_height = xlfd_strip_height (full_pattern);

     /* Compare now, and don't bother doing expensive regexp matching
        if the heights differ.  */
@@ -5612,6 +5751,31 @@
       return FALSE;
   }

+  /* Reformat pattern ito a regexp */
+  regex = alloca (strlen (full_pattern) * 3 + 3);
+
+  ptr = regex;
+  *ptr++ = '^';
+
+  /* Turn pattern into a regexp and do a regexp match.  */
+  for (; *full_pattern; full_pattern++)
+    {
+      if (*full_pattern == '?')
+        *ptr++ = '.';
+      else if (*full_pattern == '*')
+        {
+          *ptr++ = '[';
+          *ptr++ = '^';
+          *ptr++ = '-';
+          *ptr++ = ']';
+          *ptr++ = '*';
+        }
+      else
+        *ptr++ = *full_pattern;
+    }
+  *ptr = '$';
+  *(ptr + 1) = '\0';
+
   return (fast_c_string_match_ignore_case (build_string (regex),
                                            font_name_copy) >= 0);
 }
@@ -5951,7 +6115,15 @@
           = GetProcAddress ( gdi32, "EnumFontFamiliesExA");

         /* We do our own pattern matching so we can handle wildcards. 
*/
-        font_match_pattern.lfFaceName[0] = 0;
+       if (strchr (ef.logfont.lfFaceName, '*') == NULL
+           && strchr (ef.logfont.lfFaceName, '_') == NULL)
+         {
+           strcpy (font_match_pattern.lfFaceName,
+                   ef.logfont.lfFaceName);
+         }
+       else
+         font_match_pattern.lfFaceName[0] = 0;
+
         font_match_pattern.lfPitchAndFamily = 0;
         /* We can use the charset, because if it is a wildcard it will
            be DEFAULT_CHARSET anyway.  */



__________________________________
Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway 
http://promotions.yahoo.com/design_giveaway/




reply via email to

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