From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Michael Mauger Newsgroups: gmane.emacs.devel Subject: Re: char-displayable-p issue Date: Thu, 23 Oct 2003 13:21:27 -0700 (PDT) Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <20031023202127.20102.qmail@web60303.mail.yahoo.com> References: NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="0-1803830584-1066940487=:19840" X-Trace: sea.gmane.org 1066940720 22759 80.91.224.253 (23 Oct 2003 20:25:20 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 23 Oct 2003 20:25:20 +0000 (UTC) Cc: emacs-devel@gnu.org, Kenichi Handa Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Thu Oct 23 22:25:17 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1ACm1F-0008BZ-00 for ; Thu, 23 Oct 2003 22:25:17 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1ACm1E-0001jO-00 for ; Thu, 23 Oct 2003 22:25:16 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AClyX-00039d-Gb for emacs-devel@quimby.gnus.org; Thu, 23 Oct 2003 16:22:29 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1ACly6-00038r-4d for emacs-devel@gnu.org; Thu, 23 Oct 2003 16:22:02 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1AClxZ-00030s-11 for emacs-devel@gnu.org; Thu, 23 Oct 2003 16:22:00 -0400 Original-Received: from [216.109.118.114] (helo=web60303.mail.yahoo.com) by monty-python.gnu.org with smtp (Exim 4.24) id 1AClxY-00030b-Gy for emacs-devel@gnu.org; Thu, 23 Oct 2003 16:21:28 -0400 Original-Received: from [12.91.6.186] by web60303.mail.yahoo.com via HTTP; Thu, 23 Oct 2003 13:21:27 PDT Original-To: Jason Rumney In-Reply-To: X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:17386 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:17386 --0-1803830584-1066940487=:19840 Content-Type: text/plain; charset=us-ascii Content-Id: Content-Disposition: inline --- Jason Rumney wrote: > Michael Mauger 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 --0-1803830584-1066940487=:19840 Content-Type: text/plain; name="w32fncs.diff" Content-Description: w32fncs.diff Content-Disposition: inline; filename="w32fncs.diff" 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: ! * "[: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: + "[: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. */ --0-1803830584-1066940487=:19840 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://mail.gnu.org/mailman/listinfo/emacs-devel --0-1803830584-1066940487=:19840--