unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* char-displayable-p issue
@ 2003-10-08  7:04 David PONCE
  2003-10-13 23:40 ` Kenichi Handa
  0 siblings, 1 reply; 12+ messages in thread
From: David PONCE @ 2003-10-08  7:04 UTC (permalink / raw)


Hi,

I got a little problem in ruler-mode that no more chose the right
default characters to display in the ruler.

If fact, `char-displayable-p' wrongly says that characters ?¶ (2230)
and ?\¦ (2214) are not displayable although I clearly see them
displayed.

Here is some information about my running environment:

runemacs.exe -q -no-site-file

(frame-parameter (selected-frame) 'font)
"-outline-Courier New-normal-r-normal-normal-13-97-96-96-c-80-iso8859-1"

In GNU Emacs 21.3.50.1 (i386-mingw-nt4.0.1381)
 of 2003-10-08 on MYHOST
configured using `configure --with-gcc (3.2)'

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: ENU
  locale-coding-system: iso-latin-1
  default-enable-multibyte-characters: t

Hope it will help.

David

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-08  7:04 David PONCE
@ 2003-10-13 23:40 ` Kenichi Handa
  2003-10-14  5:56   ` David Ponce
  0 siblings, 1 reply; 12+ messages in thread
From: Kenichi Handa @ 2003-10-13 23:40 UTC (permalink / raw)
  Cc: emacs-devel

In article <12298630.1065596660178.JavaMail.www@wwinf0402>, David PONCE <david.ponce@wanadoo.fr> writes:
> I got a little problem in ruler-mode that no more chose the right
> default characters to display in the ruler.

> If fact, `char-displayable-p' wrongly says that characters ?¶ (2230)
> and ?\¦ (2214) are not displayable although I clearly see them
> displayed.

I can't reproduce that bug.  When I turned on ruler-mode, I
see both characters in the ruler head.  Isn't it a bug
specific to Windows?

---
Ken'ichi HANDA
handa@m17n.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-13 23:40 ` Kenichi Handa
@ 2003-10-14  5:56   ` David Ponce
  0 siblings, 0 replies; 12+ messages in thread
From: David Ponce @ 2003-10-14  5:56 UTC (permalink / raw)
  Cc: emacs-devel

> 
> I can't reproduce that bug.  When I turned on ruler-mode, I
> see both characters in the ruler head.  Isn't it a bug
> specific to Windows?
> 

Yes, it seems the problem is specific to Windows.  Work well on my
GNU/Linux box.

David

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
@ 2003-10-21 23:22 Michael Mauger
  2003-10-22  5:51 ` Kenichi Handa
  0 siblings, 1 reply; 12+ messages in thread
From: Michael Mauger @ 2003-10-21 23:22 UTC (permalink / raw)



[-- Attachment #1.1: Type: text/plain, Size: 1699 bytes --]

I can't reproduce that bug. When I turned on ruler-mode, I see both characters in the ruler head. Isn't it a bug specific to Windows?

Yes, it seems the problem is specific to Windows. Work well on my GNU/Linux box. 


I'm not sure that this is just a Windows issue -- it may affect some X implementations as well.  The problem seems to be that the wildcard pattern generated in `char-displayable-p' is not matching multiple hyphen separated portions of the font name.  That is, '-*-*-iso8859-1' doesn't match any fonts while '-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1' does.

Here's a patch that corrects the problem (and should work reliably on all X implementations) but which runs very slowly on Windows.  

Please review...

Index: emacs/lisp/international/mule-util.el===================================================================RCS file: /cvsroot/emacs/emacs/lisp/international/mule-util.el,vretrieving revision 1.53diff -b -u -r1.53 mule-util.el--- emacs/lisp/international/mule-util.el       1 Sep 2003 18:45:35 -00001.53+++ emacs/lisp/international/mule-util.el       21 Oct 2003 22:47:42 -0000@@ -386,7 +386,7 @@                 (or (stringp font-pattern)                     (setq font-pattern (concat "-"                                                (or (car font-pattern) "*")-                                               "-*-"+                                               "-*-*-*-*-*-*-*-*-*-*-*-"                                                (cdr font-pattern))))                 (x-list-fonts font-pattern 'default (selected-frame) 1)))))        (t

-- Michael


---------------------------------
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software

[-- Attachment #1.2: Type: text/html, Size: 2110 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-21 23:22 Michael Mauger
@ 2003-10-22  5:51 ` Kenichi Handa
  2003-10-22 16:00   ` Michael Mauger
  0 siblings, 1 reply; 12+ messages in thread
From: Kenichi Handa @ 2003-10-22  5:51 UTC (permalink / raw)
  Cc: emacs-devel

In article <20031021232240.14826.qmail@web60306.mail.yahoo.com>, Michael Mauger <mmaug@yahoo.com> writes:

> [1  <multipart/alternative (7bit)>]
> [1.1  <text/plain; us-ascii (7bit)>]
> I can't reproduce that bug. When I turned on ruler-mode, I
> see both characters in the ruler head. Isn't it a bug
> specific to Windows?

> Yes, it seems the problem is specific to Windows. Work
> well on my GNU/Linux box.

> I'm not sure that this is just a Windows issue -- it may
> affect some X implementations as well.  The problem seems
> to be that the wildcard pattern generated in
> `char-displayable-p' is not matching multiple hyphen
> separated portions of the font name.  That is,
> '-*-*-iso8859-1' doesn't match any fonts while
> '-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1' does.

> Here's a patch that corrects the problem (and should work
> reliably on all X implementations) but which runs very
> slowly on Windows.

Ummm, I didn't know that such a server exists.  How about
'-*-iso8859-1'?  Doest it match all iso8859-1 fonts?  If so,
instead of just changing "-*-" to "-*-*-*-*-*-*-*-*-*-*-*-",
generating the most compact font-pattern (i.e. no succeeding
wildcards) will solve the problem without making Windows
version slow.

Could you try that?

Even if that doesn't work, your patch is not enough.  I
think we must change the length of "-*-..-*-" according to
the form of car of font-pattern ("FOUNDRY-FAMILY",
"*FAMILY", or "FOUNDRY*")

---
Ken'ichi HANDA
handa@m17n.org

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-22  5:51 ` Kenichi Handa
@ 2003-10-22 16:00   ` Michael Mauger
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Mauger @ 2003-10-22 16:00 UTC (permalink / raw)
  Cc: emacs-devel

--- Kenichi Handa <handa@m17n.org> wrote:
> In article <20031021232240.14826.qmail@web60306.mail.yahoo.com>,
> Michael Mauger <mmaug@yahoo.com> writes:
> 
> > I can't reproduce that bug. When I turned on ruler-mode, I
> > see both characters in the ruler head. Isn't it a bug
> > specific to Windows?
> 
> > Yes, it seems the problem is specific to Windows. Work
> > well on my GNU/Linux box.
> 
> > I'm not sure that this is just a Windows issue -- it may
> > affect some X implementations as well.  The problem seems
> > to be that the wildcard pattern generated in
> > `char-displayable-p' is not matching multiple hyphen
> > separated portions of the font name.  That is,
> > '-*-*-iso8859-1' doesn't match any fonts while
> > '-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1' does.
> 
> > Here's a patch that corrects the problem (and should work
> > reliably on all X implementations) but which runs very
> > slowly on Windows.
> 
> Ummm, I didn't know that such a server exists.  How about
> '-*-iso8859-1'?  Doest it match all iso8859-1 fonts?  If so,
> instead of just changing "-*-" to "-*-*-*-*-*-*-*-*-*-*-*-",
> generating the most compact font-pattern (i.e. no succeeding
> wildcards) will solve the problem without making Windows
> version slow.
> 
> Could you try that?
> 
> Even if that doesn't work, your patch is not enough.  I
> think we must change the length of "-*-..-*-" according to
> the form of car of font-pattern ("FOUNDRY-FAMILY",
> "*FAMILY", or "FOUNDRY*")

I tried '-*-iso8859-1' and it also failed.  The problem appears to be in
the Windows implementation of x-list-fonts (w32_list_fonts in
src/w32fns.c).  The wildcarding is obviously not working as intended.

(length (x-list-fonts "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1")) 
= 584
(length (x-list-fonts "-*-iso8859-1"))
= 0

I'll take a look at w32_list_fonts but I am very rusty on Windows
internals.  

-- Michael

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
@ 2003-10-22 19:09 Michael Mauger
  2003-10-22 19:53 ` Jason Rumney
  0 siblings, 1 reply; 12+ messages in thread
From: Michael Mauger @ 2003-10-22 19:09 UTC (permalink / raw)
  Cc: emacs-devel

--- Michael Mauger <mmaug@yahoo.com> wrote:
> --- Kenichi Handa <handa@m17n.org> wrote:
> > --- Michael Mauger <mmaug@yahoo.com> wrote:
> > 
> > > I can't reproduce that bug. When I turned on ruler-mode, I
> > > see both characters in the ruler head. Isn't it a bug
> > > specific to Windows?
> > 
> > > Yes, it seems the problem is specific to Windows. Work
> > > well on my GNU/Linux box.
> > 
> > > The problem seems
> > > to be that the wildcard pattern generated in
> > > `char-displayable-p' is not matching multiple hyphen
> > > separated portions of the font name.  That is,
> > > '-*-*-iso8859-1' doesn't match any fonts while
> > > '-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1' does.
> > 
> > How about
> > '-*-iso8859-1'?  Doest it match all iso8859-1 fonts?  If so,
> > instead of just changing "-*-" to "-*-*-*-*-*-*-*-*-*-*-*-",
> > generating the most compact font-pattern (i.e. no succeeding
> > wildcards) will solve the problem without making Windows
> > version slow.
> > 
> > Even if that doesn't work, your patch is not enough.  I
> > think we must change the length of "-*-..-*-" according to
> > the form of car of font-pattern ("FOUNDRY-FAMILY",
> > "*FAMILY", or "FOUNDRY*")
> 
> I tried '-*-iso8859-1' and it also failed.  The problem appears to be
> in the Windows implementation of x-list-fonts (w32_list_fonts in
> src/w32fns.c).  The wildcarding is obviously not working as intended.
> 

Okay, I think I've isolated the font matching problem down to its
source.  The issue arises in the routine `x_to_w32_font' in
src/w32fns.c.  This routine translates a XLFD string into a Windows
LOGFONT structure.  The problem is that this routine only handles the
following formats:

[fully qualified]
-FOUNDRY-FAMILY-WEIGHT-SLANT-WIDTH-STYLE-PIXELSIZE-POINTSIZE-RESX-RESY
    -SPACING-AVGWIDTH-REGISTRY-ENCODING

[special case generated by font_list_1 invoked by try_font_list]
-FOUNDRY-FAMILY-*-REGISTRY-ENCODING

[Windows-specific formats]
FAMILY:PIXELHEIGHT:PIXELWIDTH:WEIGHT
FAMILY:PIXELHEIGHT:PIXELWIDTH
FAMILY:PIXELHEIGHT
FAMILY

Thus, the strings '-*-iso8859-1' and '-*-*-iso8859-1' are not being
parsed properly.

I see several possible solutions to this specific (char-displayable-p
failing) problem (somewhat in the order of complexity):

1. Alter `char-displayable-p' to generate a string of the form
   '-FOUNDRY-FAMILY-*-REGISTRY-ENCODING' in all cases.  Requires
   parsing the car of the result from fontset-font to ensure
   sufficient hyphens/wildcards have been inserted for it to be
   properly parsed on Windows.

2. Same as above but conditional on (eq window-system 'w32).

3. Modify `x_to_w32_font' to handle the forms:
   -FOUNDRY-*-REGISTRY-ENCODING
   -*-REGISTRY-ENCODING

   The code in this routine is a little fragile.  There are many
   special cases handled implicitly without explicit acknowledgement
   that they are there.  

4. Rewrite the parser in `x_to_w32_font' to more properly handle
   wildcards.  I'm not sure that this can even be done and it is
   probably unnecessary given the limited number of font patterns
   likely to be encountered.

I see option 3 as the ideal, and I will start to work on it. 

One other issue: Kenichi Handa said that the car of font-pattern
could be one of "FOUNDRY-FAMILY", "*FAMILY", or "FOUNDRY*", in
addition to nil.  My solution would not handle the "*FAMILY" form
unless it is really sent as "*-FAMILY".  The Windows code does
not handle partial wildcards in the font pattern.  Will these forms
ever be generated by the Windows code?

If the car of the font-pattern does not have the hyphens with the
wildcard then we need to handle these cases specially.  I would
propose handling them in `char-displayable-p' because their meaning
is clear at that point.  Trying to accommodate the partial wildcards
in `x_to_w32_font' may break other usages.

The internals of Emacs and Windows are by no means my strength, so
if you have comments please send them along.  Thanks.

-- Michael

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-22 19:09 char-displayable-p issue Michael Mauger
@ 2003-10-22 19:53 ` Jason Rumney
  2003-10-23 20:21   ` Michael Mauger
  0 siblings, 1 reply; 12+ messages in thread
From: Jason Rumney @ 2003-10-22 19:53 UTC (permalink / raw)
  Cc: emacs-devel, Kenichi Handa

Michael Mauger <mmaug@yahoo.com> writes:

> 3. Modify `x_to_w32_font' to handle the forms:
>    -FOUNDRY-*-REGISTRY-ENCODING
>    -*-REGISTRY-ENCODING
> 
>    The code in this routine is a little fragile.  There are many
>    special cases handled implicitly without explicit acknowledgement
>    that they are there.  

> I see option 3 as the ideal, and I will start to work on it. 

Thank you. I have tweaked that bit of code many times now to fix
bugs like this, it could do with a fresh set of eyes. Please document
any implicit special cases that you find.

> One other issue: Kenichi Handa said that the car of font-pattern
> could be one of "FOUNDRY-FAMILY", "*FAMILY", or "FOUNDRY*", in
> addition to nil.  My solution would not handle the "*FAMILY" form
> unless it is really sent as "*-FAMILY".  The Windows code does
> not handle partial wildcards in the font pattern.

I recently changed the font selection code in the emacs-unicode-2
branch to fix the same problem in charset and encoding fields. The
approach I took is to treat partial wildcards as full wildcards in
x_to_w32_charset, and to do more thorough comparisons in
enum_font_cb2.

> Trying to accommodate the partial wildcards in `x_to_w32_font' may
> break other usages.

That is my experience with trying to do anything in x_to_w32_font. It
is not an easy piece of code to get "right". That is why I have not
rushed into merging the changes I made to get emacs-unicode-2 to work
back into HEAD.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-22 19:53 ` Jason Rumney
@ 2003-10-23 20:21   ` Michael Mauger
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Mauger @ 2003-10-23 20:21 UTC (permalink / raw)
  Cc: emacs-devel, Kenichi Handa

[-- Attachment #1: Type: text/plain, Size: 3242 bytes --]

--- Jason Rumney <jasonr@gnu.org> wrote:
> Michael Mauger <mmaug@yahoo.com> writes:
> 
> > 3. Modify `x_to_w32_font' to handle the forms:
> >    -FOUNDRY-*-REGISTRY-ENCODING
> >    -*-REGISTRY-ENCODING
> > 
> >    The code in this routine is a little fragile.  There are many
> >    special cases handled implicitly without explicit acknowledgement
> >    that they are there.  
> 
> > I see option 3 as the ideal, and I will start to work on it. 
> 
> Thank you. I have tweaked that bit of code many times now to fix
> bugs like this, it could do with a fresh set of eyes. Please document
> any implicit special cases that you find.
> 

I ended up having to rewrite the parser.  (See diff attached).  The XLFD
string is broken into segments and the last wildcard prior to the last
segment is expanded into multiple wildcards to fill out the full spec. 
This is not perfect but seems to address the most common usages.  It does
correct the bug that raised this thread.  However, it does expose some
bugs deeper in the font selection process that I have not been able to
isolate yet.  

For example, '-*-*-iso8859-1' returns all the Latin-1 fonts as does
'-*-*-*-*-*-*-iso8859-1' (6 segments prior to the charset), but
'-*-*-*-*-*-iso8859-1' (5 segments prior to the charset) returns none. 
The function `x_to_w32_font' returns the same LOGFONT structure in each
case.  The issues appear to be in interpreting portions of the XLFD
string later during the font enumeration process.  I haven't been able to
decypher that code as of yet.

I've been using the following elisp code to test `x-list-fonts':

(let ((i 0) (p "") l)
  (while (< i 14)
    (setq i (+ i 1)
	  p (concat p "-*")
	  l (length (x-list-fonts (concat p "-iso8859-1"))))
    (princ (concat (number-to-string i) "=>" (number-to-string l) " 
"))))

For values of `i' of 5, 8, and 9, no matches are made (also for values of
12 and 13, but that is because the the pattern is too long).

> > One other issue: Kenichi Handa said that the car of font-pattern
> > could be one of "FOUNDRY-FAMILY", "*FAMILY", or "FOUNDRY*", in
> > addition to nil.  My solution would not handle the "*FAMILY" form
> > unless it is really sent as "*-FAMILY".  The Windows code does
> > not handle partial wildcards in the font pattern.
> 
> I recently changed the font selection code in the emacs-unicode-2
> branch to fix the same problem in charset and encoding fields. The
> approach I took is to treat partial wildcards as full wildcards in
> x_to_w32_charset, and to do more thorough comparisons in
> enum_font_cb2.
> 

I don't want to attempt this until I understand the font emun process
better.

> > Trying to accommodate the partial wildcards in `x_to_w32_font' may
> > break other usages.
> 
> That is my experience with trying to do anything in x_to_w32_font. It
> is not an easy piece of code to get "right". That is why I have not
> rushed into merging the changes I made to get emacs-unicode-2 to work
> back into HEAD.
> 

Jason, you're probably the best one to evaluate these changes and their
impact on the future unicode changes.

-- Michael

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

[-- Attachment #2: w32fncs.diff --]
[-- Type: text/plain, Size: 10543 bytes --]

Index: emacs/src/w32fns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32fns.c,v
retrieving revision 1.222
diff -b -c -r1.222 w32fns.c
*** emacs/src/w32fns.c	2 Oct 2003 23:07:28 -0000	1.222
--- emacs/src/w32fns.c	23 Oct 2003 18:47:29 -0000
***************
*** 5485,5492 ****
       char * lpxstr;
       LOGFONT * lplogfont;
  {
-   struct coding_system coding;
- 
    if (!lplogfont) return (FALSE);
  
    memset (lplogfont, 0, sizeof (*lplogfont));
--- 5485,5490 ----
***************
*** 5510,5555 ****
    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;
  
--- 5508,5614 ----
    if (!lpxstr)
      return FALSE;
  
!   /* Parse the string as an XLFD spec if it starts with a hyphen. */
    if (*lpxstr == '-')
      {
!       int nfields;
! #define F_FOUNDRY	(0)
! #define F_FAMILY	(1)
! #define F_WEIGHT	(2)
! #define F_SLANT 	(3)
! #define F_SWIDTH 	(4)
! #define F_ADSTYLE 	(5)
! #define F_PIXELSIZE	(6)
! #define F_POINTSIZE	(7)
! #define F_RESX  	(8)
! #define F_RESY  	(9)
! #define F_SPACING	(10)
! #define F_AVGWIDTH	(11)
! #define F_REGISTRY	(12)
! #define F_ENCODING	(13)
! 
! #define FCNT   14
! #define FSIZ 50
!       char field[FCNT][FSIZ];
!       char * next;
!       int lastwild;
! 
!       /* break XLFD string on hyphens */
!       next = lpxstr;
!       lastwild = -1;
!       for (nfields = 0; nfields < FCNT; ++nfields)
! 	{
! 	  char * this = next + 1;
! 	  int len;
! 
! 	  /* Locate the next hyphen */
! 	  next = strchr (this, '-');
! 
! 	  /* Calculate the length of this segment. */
! 	  if (next == NULL)
! 	    len = strlen (this);
! 	  else
! 	    len = next - this;
! 
! 	  /* Make sure the segment is not too long. */
! 	  if (len >= FSIZ)
! 	    len = FSIZ - 1;
! 
! 	  /* Copy this segment and terminate it. */
! 	  strncpy (field[nfields], this, len);
! 	  field[nfields][len] = '\0';
! 
! 	  /* 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 < `nfields'. */
! 	  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 < FCNT)
! 	{
! 	  int f0;
! 
! 	  /* If there was a wildcard, expand it out. */
! 	  if (lastwild > -1)
! 	    {
! 	      /* Copy what's after the wildcard to the end. */
! 	      for (f0 = 1; f0 <= nfields - lastwild; ++f0)
! 		strcpy (field[FCNT - f0], field[nfields - f0]);
! 
! 	      /* Fill in the middle with wildcards. */
! 	      for (f0 = 1; f0 < FCNT - nfields; ++f0)
! 		strcpy (field[lastwild + f0], "*");
  	    }
! 
! 	  /* There were no wildcards, pad it with wildcards. */
! 	  else
  	    {
! 	      for (f0 = nfields; f0 < FCNT; ++f0)
! 		strcpy (field[f0], "*");
  	    }
  
! 	  /* The font spec is now complete. */
! 	  nfields = FCNT;
! 	}
! 
!       /* Copy the name portion to the facename. */
!       if (strcmp (field[F_FAMILY], "*") != 0)
          {
+ 	  struct coding_system coding;
  	  int bufsize;
  	  unsigned char *buf;
  
***************
*** 5557,5566 ****
              (Fcheck_coding_system (Vlocale_coding_system), &coding);
  	  coding.src_multibyte = 1;
  	  coding.dst_multibyte = 1;
! 	  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;
--- 5616,5626 ----
              (Fcheck_coding_system (Vlocale_coding_system), &coding);
  	  coding.src_multibyte = 1;
  	  coding.dst_multibyte = 1;
! 	  bufsize = encoding_buffer_size (&coding, strlen (field[F_FAMILY]));
  	  buf = (unsigned char *) alloca (bufsize);
            coding.mode |= CODING_MODE_LAST_BLOCK;
!           encode_coding (&coding, field[F_FAMILY], buf,
! 			 strlen (field[F_FAMILY]), bufsize);
  	  if (coding.produced >= LF_FACESIZE)
  	    coding.produced = LF_FACESIZE - 1;
  	  buf[coding.produced] = 0;
***************
*** 5571,5637 ****
  	  lplogfont->lfFaceName[0] = '\0';
  	}
  
!       fields--;
  
!       lplogfont->lfWeight = x_to_w32_weight ((fields > 0 ? weight : ""));
  
!       fields--;
  
!       lplogfont->lfItalic = (fields > 0 && slant == 'i');
  
!       fields--;
  
!       if (fields > 0 && pixels[0] != '*')
! 	lplogfont->lfHeight = atoi (pixels);
  
!       fields--;
!       fields--;
!       if (fields > 0 && resy[0] != '*')
!         {
!           tem = atoi (resy);
!           if (tem > 0) dpi = tem;
          }
  
!       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;
--- 5631,5709 ----
  	  lplogfont->lfFaceName[0] = '\0';
  	}
  
!       /* Copy over the weight. */
!       lplogfont->lfWeight = x_to_w32_weight (field[F_WEIGHT]);
  
!       /* Copy over the italic flag */
!       lplogfont->lfItalic = (field[F_SLANT][0] == 'i');
  
!       /* Copy over the pixel height. */
!       {
! 	int pixelsize = atoi (field[F_PIXELSIZE]);
  
! 	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;
  
! 	  if (strcmp (field[F_RESY], "*") != 0)
! 	    resy = atoi (field[F_RESY]);
! 	  if (resy <= 0)
! 	    resy = (int) one_w32_display_info.resy;
  
! 	  if (strcmp (field[F_POINTSIZE], "*") != 0)
! 	    pointsize = atoi (field[F_POINTSIZE]);
! 	  if (pointsize > 0)
! 	    lplogfont->lfHeight = (pointsize * resy) / 720;
          }
  
!       /* Copy over the pitch. */
        lplogfont->lfPitchAndFamily =
! 	(field[F_SPACING][0] == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
  
!       /* Copy over the point size. */
!       {
! 	int avgwidth = atoi (field[F_AVGWIDTH]);
  
! 	if (avgwidth > 0)
! 	  lplogfont->lfWidth = avgwidth / 10;
!       }
  
!       /* Copy over the character set encoding. */
!       {
! 	char encoding[2 * FSIZ];
  
! 	strcpy (encoding, field[F_REGISTRY]);
! 	if (strcmp (field[F_ENCODING], "*") != 0)
  	  {
! 	    strcat (encoding, "-");
! 	    strcat (encoding, field[F_ENCODING]);
  	  }
! 
  	lplogfont->lfCharSet = x_to_w32_charset (encoding);
        }
+     }
+   /* Provide a simple escape mechanism for specifying Windows font names
+      directly in this format:
+      "<font name>[:height in pixels[:width in pixels[:weight]]]"
+   */
    else
      {
!       int nfields;
        char name[100], height[10], width[10], weight[20];
  
!       nfields = sscanf (lpxstr,
  			"%99[^:]:%9[^:]:%9[^:]:%19s",
  			name, height, width, weight);
  
!       if (nfields == EOF) return (FALSE);
  
!       if (nfields > 0)
          {
  	  strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
  	  lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
***************
*** 5641,5659 ****
  	  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. */
--- 5713,5731 ----
  	  lplogfont->lfFaceName[0] = 0;
  	}
  
!       nfields--;
  
!       if (nfields > 0)
  	lplogfont->lfHeight = atoi (height);
  
!       nfields--;
  
!       if (nfields > 0)
  	lplogfont->lfWidth = atoi (width);
  
!       nfields--;
  
!       lplogfont->lfWeight = x_to_w32_weight ((nfields > 0 ? weight : ""));
      }
  
    /* This makes TrueType fonts work better. */

[-- Attachment #3: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
@ 2003-10-27 23:48 Michael Mauger
  2003-10-28  8:21 ` Jason Rumney
  0 siblings, 1 reply; 12+ messages in thread
From: Michael Mauger @ 2003-10-27 23:48 UTC (permalink / raw)
  Cc: emacs-devel, Kenichi Handa

[-- Attachment #1: Type: text/plain, Size: 2442 bytes --]

--- Michael Mauger <mmaug@yahoo.com> wrote:
> I ended up having to rewrite the parser.  (See diff attached).  The 
> XLFD
> string is broken into segments and the last wildcard prior to the last
> segment is expanded into multiple wildcards to fill out the full spec. 
> This is not perfect but seems to address the most common usages.  It
> does
> correct the bug that raised this thread.  However, it does expose some
> bugs deeper in the font selection process that I have not been able to
> isolate yet.  
> 
> I don't want to attempt this until I understand the font emun process
> better.
> 

I've spent some time looking into the font enum code.  There were
several interrelated bugs involved in the matching of font
specifications.  I've attached a patch that addresses these
problems.  Here's the ChangeLog for these changes. 

2003-10-27  Michael Mauger  <mmaug@yahoo.com>

	* (w32_normalize_xlfd): Added function.  Expands a partial XLFD
	specification into a fully qualified specification by filling in
	wildcards. Translates Windows-specific font format to a fully
	qualified XLFD specification.
	* (w32_get_xlfd_field): Added function.  Returns a portion of a
	XLFD specification.
	* (w32_to_x_font): Use "*" rather than "unknown" for unknown XLFD
	FOUNDRY.  Use "*" when FAMILY is empty.
	* (x_to_w32_font): Rewritten.  Use `w32_normalize_xlfd' and
	`w32_get_xlfd_field' to parse XLFD string properly.
	* (xlfd_strip_height): Rewrote to simplify and correct.  
	* (w32_font_match): Normalize XLFD pattern before stripping
	height or converting to a regex.  Because the pattern is fully
	qualified, wildcards now match "[^-]*" rather than ".*" as it
	did before. 
	* (w32_list_fonts): If face name has no wildcards then use it in
	Windows FontEnum to reduce the number of fonts enumerated.

This version runs in reasonable time (I'm running on a 200Mhz w/ 12Mb
and nearly 600 fonts -- font lookup is running in less than .5
secs -- much better than the 12+ secs before).  There are definitely
opportunities for improving performance (caching pattern regexs in long
font enums processes is a likely target).

As before, Jason, this probably still applies:
> Jason, you're probably the best one to evaluate these changes and their
> impact on the future unicode changes.
> 

-- Michael


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

[-- Attachment #2: w32fncs.diff --]
[-- Type: text/plain, Size: 21511 bytes --]

Index: emacs/src/w32fns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32fns.c,v
retrieving revision 1.222
diff -u -r1.222 w32fns.c
--- emacs/src/w32fns.c	2 Oct 2003 23:07:28 -0000	1.222
+++ emacs/src/w32fns.c	27 Oct 2003 18:34:57 -0000
@@ -4601,6 +4601,23 @@
 }

 \f
+/* 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)
 {
@@ -4623,6 +4640,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);
@@ -4918,6 +4937,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;
@@ -5417,7 +5648,7 @@
   else if (lplogfont->lfOutPrecision == OUT_STROKE_PRECIS)
     fonttype = "outline";
   else
-    fonttype = "unknown";
+    fonttype = "*";

   setup_coding_system (Fcheck_coding_system (Vlocale_coding_system),
                        &coding);
@@ -5433,6 +5664,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.  */
@@ -5485,7 +5718,8 @@
      char * lpxstr;
      LOGFONT * lplogfont;
 {
-  struct coding_system coding;
+  char * field;
+  char * xstrbuf;

   if (!lplogfont) return (FALSE);

@@ -5508,156 +5742,112 @@
   lplogfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;

   if (!lpxstr)
-    return FALSE;
+    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);
+  /* 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);

-      /* 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;
-	}
+  field = alloca (strlen (xstrbuf) + 1);

-      if (fields > 0 && name[0] != '*')
-        {
-	  int bufsize;
-	  unsigned char *buf;
+  /* Copy the name portion to the facename. */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_FAMILY);
+  if (strcmp (field, "*") != 0)
+    {
+      struct coding_system coding;
+      int bufsize;
+      unsigned char *buf;

-          setup_coding_system
-            (Fcheck_coding_system (Vlocale_coding_system), &coding);
-	  coding.src_multibyte = 1;
-	  coding.dst_multibyte = 1;
-	  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';
-	}
+      setup_coding_system
+	(Fcheck_coding_system (Vlocale_coding_system), &coding);
+      coding.src_multibyte = 1;
+      coding.dst_multibyte = 1;
+      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';
+    }

-      fields--;
+  /* Copy over the weight. */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_WEIGHT);
+  lplogfont->lfWeight = x_to_w32_weight (field);

-      lplogfont->lfWeight = x_to_w32_weight ((fields > 0 ? weight : ""));
+  /* Copy over the italic flag */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_SLANT);
+  lplogfont->lfItalic = (field[0] == 'i');

-      fields--;
+  /* Copy over the pixel height. */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_PIXELSIZE);
+  {
+    int pixelsize = atoi (field);

-      lplogfont->lfItalic = (fields > 0 && slant == 'i');
+    if (pixelsize > 0)
+      lplogfont->lfHeight = pixelsize;
+  }

-      fields--;
+  /* Copy over the X- and Y-resolution as height. */
+  if (lplogfont->lfHeight == 0)
+    {
+      int resy = 0;
+      int pointsize = 0;

-      if (fields > 0 && pixels[0] != '*')
-	lplogfont->lfHeight = atoi (pixels);
+      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;
+    }

-      fields--;
-      fields--;
-      if (fields > 0 && resy[0] != '*')
-        {
-          tem = atoi (resy);
-          if (tem > 0) dpi = tem;
-        }
+  /* This makes TrueType fonts work better. */
+  lplogfont->lfHeight = - abs (lplogfont->lfHeight);

-      if (fields > -1 && lplogfont->lfHeight == 0 && height[0] != '*')
-	lplogfont->lfHeight = atoi (height) * dpi / 720;
+  /* Copy over the pitch. */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_SPACING);
+  lplogfont->lfPitchAndFamily =
+    (field[0] == 'p') ? VARIABLE_PITCH : FIXED_PITCH;

-      if (fields > 0)
-      lplogfont->lfPitchAndFamily =
-	(fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
+  /* Copy over the point size. */
+  w32_get_xlfd_field (field, xstrbuf, XLFD_AVGWIDTH);
+  {
+    int avgwidth = atoi (field);

-      fields--;
+    if (avgwidth > 0)
+      lplogfont->lfWidth = avgwidth / 10;
+  }

-      if (fields > 0 && width[0] != '*')
-	lplogfont->lfWidth = atoi (width) / 10;
+  /* Copy over the character set encoding. */
+  {
+    char encoding[50];

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

-      /* Strip the trailing '-' if present. (it shouldn't be, as it
-         fails the test against xlfd-tight-regexp in fontset.el).  */
+    w32_get_xlfd_field (field, xstrbuf, XLFD_ENCODING);
+    if (strcmp (field, "*") != 0)
       {
-	int len = strlen (remainder);
-	if (len > 0 && remainder[len-1] == '-')
-	  remainder[len-1] = 0;
+	strcat (encoding, "-");
+	strcat (encoding, field);
       }
-      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);
 }
@@ -5666,118 +5856,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;
 }
@@ -5788,31 +5941,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
@@ -5823,7 +5963,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.  */
@@ -5831,6 +5971,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);
 }
@@ -6170,7 +6335,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.  */

[-- Attachment #3: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-27 23:48 Michael Mauger
@ 2003-10-28  8:21 ` Jason Rumney
  2003-10-28 15:12   ` Michael Mauger
  0 siblings, 1 reply; 12+ messages in thread
From: Jason Rumney @ 2003-10-28  8:21 UTC (permalink / raw)
  Cc: emacs-devel, Kenichi Handa

Michael Mauger <mmaug@yahoo.com> writes:

> I've spent some time looking into the font enum code.  There were
> several interrelated bugs involved in the matching of font
> specifications.  I've attached a patch that addresses these
> problems.  Here's the ChangeLog for these changes. 

Thank you. I'll take a look at both sets of changes over the next few
days.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: char-displayable-p issue
  2003-10-28  8:21 ` Jason Rumney
@ 2003-10-28 15:12   ` Michael Mauger
  0 siblings, 0 replies; 12+ messages in thread
From: Michael Mauger @ 2003-10-28 15:12 UTC (permalink / raw)
  Cc: emacs-devel, Kenichi Handa

You can ignore the first patch -- the second one supercedes it.  I should
have clearer about that.

No rush -- I realize this is a significant change to a very complex and
critical piece of code.

Below is a correct version of the ChangeLog entry:

2003-10-27  Michael Mauger  <mmaug@yahoo.com>

	* w32fns.c (w32_normalize_xlfd): Added function.  Expands a
	partial XLFD specification into a fully qualified specification by
	filling in wildcards. Translates Windows-specific font format to a
	fully qualified XLFD specification.
	(w32_get_xlfd_field): Added function.  Returns a portion of a XLFD
	specification.
	(w32_to_x_font): Use "*" rather than "unknown" for unknown XLFD
	FOUNDRY.  Use "*" when FAMILY is empty.
	(x_to_w32_font): Rewritten.  Use `w32_normalize_xlfd' and
	`w32_get_xlfd_field' to parse XLFD string properly.
	(xlfd_strip_height): Rewrote to simplify and correct.
	(w32_font_match): Normalize XLFD pattern before stripping height
	or converting to a regex.  Because the pattern is fully qualified,
	wildcards now match "[^-]*" rather than ".*" as it did before.
	(w32_list_fonts): If face name has no wildcards then use it in
	Windows FontEnum to reduce the number of fonts enumerated.


--- Jason Rumney <jasonr@gnu.org> wrote:
> Michael Mauger <mmaug@yahoo.com> writes:
> 
> > I've spent some time looking into the font enum code.  There were
> > several interrelated bugs involved in the matching of font
> > specifications.  I've attached a patch that addresses these
> > problems.  Here's the ChangeLog for these changes. 
> 
> Thank you. I'll take a look at both sets of changes over the next few
> days.
> 


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2003-10-28 15:12 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-22 19:09 char-displayable-p issue Michael Mauger
2003-10-22 19:53 ` Jason Rumney
2003-10-23 20:21   ` Michael Mauger
  -- strict thread matches above, loose matches on Subject: below --
2003-10-27 23:48 Michael Mauger
2003-10-28  8:21 ` Jason Rumney
2003-10-28 15:12   ` Michael Mauger
2003-10-21 23:22 Michael Mauger
2003-10-22  5:51 ` Kenichi Handa
2003-10-22 16:00   ` Michael Mauger
2003-10-08  7:04 David PONCE
2003-10-13 23:40 ` Kenichi Handa
2003-10-14  5:56   ` David Ponce

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).