emacs-pretest-bug
[Top][All Lists]
Advanced

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

Mac OS X (Carbon): Font names need code conversion


From: YAMAMOTO Mitsuharu
Subject: Mac OS X (Carbon): Font names need code conversion
Date: Fri, 17 Jan 2003 19:05:38 +0900 (JST)

This bug report will be sent to the Free Software Foundation,
not to your local site managers!
Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the address@hidden mailing list.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:

On Mac OS X, there are some CJK fonts whose names contain non-ASCII
characters.  The Carbon version of Emacs can use them (evaluating
`(x-list-fonts "*")' shows them), but they are just undecoded unibyte
strings and thus hard to read or specify.

The attached patch decodes/encodes font names according to the
``script code'' of each font.  It seems that they are encoded by
different coding systems depending on its script code, e.g., sjis for
Japanese fonts and euc-kr for Korean fonts.

The patch also includes the code to exclude the fonts whose names
start with ``.'', as other Carbon applications do not list such fonts
in their font menus, and there is a font called ``.aqua kana'' that
contains only partial glyphs (Japanese KANAs).

I've tested it for a few weeks and no problems are found so far, but I
would appreciate if someone would check whether it is valid or not.

                                     YAMAMOTO Mitsuharu
                                address@hidden

In GNU Emacs 21.3.50.1 (powerpc-apple-darwin6.3)
 of 2003-01-15 on Macintosh.local.
configured using `configure '--with-carbon' '--without-x' 'CFLAGS=-Os''

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: ja_JP
  locale-coding-system: japanese-iso-8bit
  default-enable-multibyte-characters: t

Recent input:
M-x r e p o r t - e m a c s - b u g <return>

Recent messages:
Loading term/keyswap (source)...done
Loading encoded-kb...done
Loading jka-compr...done
Loading subst-ksc...done
Loading subst-gb2312...done
Loading subst-big5...done
Loading subst-jis...done
For information about the GNU Project and its goals, type C-h C-p.
Loading image...done
Loading emacsbug...done
*** macterm.c.~1.31.~   Mon Jan  6 08:43:19 2003
--- macterm.c   Fri Jan  3 11:29:23 2003
***************
*** 10429,10434 ****
--- 10429,10435 ----
  int font_name_table_size = 0;
  int font_name_count = 0;
  
+ #if 0
  /* compare two strings ignoring case */
  static int
  stricmp (const char *s, const char *t)
***************
*** 10508,10513 ****
--- 10509,10556 ----
            && wildstrieq (m_charset, x_charset))
           || mac_font_pattern_match (mf, xf);
  }
+ #endif
+ 
+ static Lisp_Object Qbig5, Qgb2312, Qsjis, Qeuc_kr;
+ 
+ static void
+ decode_mac_font_name (char *name, int size, short scriptcode)
+ {
+   Lisp_Object coding_system;
+   struct coding_system coding;
+   int srclen;
+   char *buf;
+ 
+   switch (scriptcode)
+     {
+     case smTradChinese:
+       coding_system = Qbig5;
+       break;
+     case smSimpChinese:
+       coding_system = Qgb2312;
+       break;
+     case smJapanese:
+       coding_system = Qsjis;
+       break;
+     case smKorean:
+       coding_system = Qeuc_kr;
+       break;        
+     default:
+       return;
+     }
+ 
+   srclen = strlen(name);
+   setup_coding_system (coding_system, &coding);
+   coding.src_multibyte = 0;
+   coding.dst_multibyte = 1;
+   coding.mode |= CODING_MODE_LAST_BLOCK;
+   coding.composing = COMPOSITION_DISABLED;
+   buf = (char *) alloca (size);
+ 
+   decode_coding (&coding, name, buf, srclen, size - 1);
+   buf[coding.produced] = '\0';
+   strcpy(name, buf);
+ }
  
  
  static char *
***************
*** 10573,10578 ****
--- 10616,10623 ----
  x_font_name_to_mac_font_name (char *xf, char *mf)
  {
    char foundry[32], family[32], weight[20], slant[2], cs[32];
+   Lisp_Object coding_system = Qnil;
+   struct coding_system coding;
  
    strcpy (mf, "");
  
***************
*** 10582,10594 ****
                foundry, family, weight, slant, cs) != 5)
      return;
  
!   if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0
!       || strcmp (cs, "jisx0208.1983-sjis") == 0
!       || strcmp (cs, "jisx0201.1976-0") == 0
!       || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0)
      strcpy(mf, family);
    else
      sprintf(mf, "%s-%s-%s", foundry, family, cs);
  }
  
  
--- 10627,10655 ----
                foundry, family, weight, slant, cs) != 5)
      return;
  
!   if (strcmp (cs, "big5-0") == 0)
!     coding_system = Qbig5;
!   else if (strcmp (cs, "gb2312.1980-0") == 0)
!     coding_system = Qgb2312;
!   else if (strcmp (cs, "jisx0208.1983-sjis") == 0
!          || strcmp (cs, "jisx0201.1976-0") == 0)
!     coding_system = Qsjis;
!   else if (strcmp (cs, "ksc5601.1989-0") == 0)
!     coding_system = Qeuc_kr;
!   else if (strcmp (cs, "mac-roman") == 0)
      strcpy(mf, family);
    else
      sprintf(mf, "%s-%s-%s", foundry, family, cs);
+ 
+   if (!NILP (coding_system))
+     {
+       setup_coding_system (coding_system, &coding);
+       coding.src_multibyte = 1;
+       coding.dst_multibyte = 1;
+       coding.mode |= CODING_MODE_LAST_BLOCK;
+       encode_coding(&coding, family, mf, strlen(family), sizeof(Str32) - 1);
+       mf[coding.produced] = '\0';
+     }
  }
  
  
***************
*** 10620,10625 ****
--- 10681,10691 ----
  static void
  init_font_name_table ()
  {
+   Qbig5 = intern("big5");
+   Qgb2312 = intern("gb2312");
+   Qsjis = intern("sjis");
+   Qeuc_kr = intern("euc-kr");
+ 
  #if TARGET_API_MAC_CARBON
    SInt32 sv;
    
***************
*** 10652,10659 ****
--- 10718,10728 ----
          if (FMGetFontFamilyName (ff, name) != noErr)
            break;
          p2cstr (name);
+         if (*name == '.')
+           continue;
        
          sc = FontToScript (ff);
+         decode_mac_font_name(name, sizeof(name), sc);
          
          /* Point the instance iterator at the current font family.  */
          if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr)
***************
*** 10661,10687 ****
        
          while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
                 == noErr)
!           if (size == 0)
!             {
!               add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                             style, sc));
!               add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                             italic, sc));
!               add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                             bold, sc));
!               add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                             italic | bold,
!                                                             sc));
!             }
!           else
!             {
!               add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                             style, sc));
!               if (smJapanese == sc)
!                 add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                               style,
!                                                               -smJapanese));
!             }
        }
    
        /* Dispose of the iterators.  */
--- 10730,10760 ----
        
          while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
                 == noErr)
!           {
!             /* Both jisx0208.1983-sjis and jisx0201.1976-sjis parts
!                are contained in Apple Japanese (SJIS) font.  */
!             do
!               {
!                 if (size == 0)
!                   {
!                     add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                                   style, sc));
!                     add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                                   italic, 
sc));
!                     add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                                   bold, sc));
!                     add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                                   italic | 
bold,
!                                                                   sc));
!                   }
!                 else
!                   add_font_name_table_entry (mac_to_x_fontname (name, size,
!                                                                 style, sc));
!               }
!             while (sc == smJapanese && (sc = -smJapanese));
!             if (sc == -smJapanese)
!               sc = smJapanese;
!           }
        }
    
        /* Dispose of the iterators.  */
***************
*** 10723,10728 ****
--- 10796,10802 ----
          
          TextFont (fontnum);
          scriptcode = FontToScript (fontnum);
+         decode_mac_font_name(name, sizeof(name), scriptcode);
          do
            {
              HLock (font_handle);
***************
*** 10786,10791 ****
--- 10860,10911 ----
  }
  
  
+ static Lisp_Object
+ mac_do_list_fonts (pattern, maxnames)
+      char *pattern;
+      int maxnames;
+ {
+   int i, n_fonts = 0;
+   Lisp_Object font_list = Qnil, pattern_regex, fontname;
+   char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
+   char *ptr;
+ 
+   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++ = tolower (*pattern);
+     }
+   *ptr = '$';
+   *(ptr + 1) = '\0';
+ 
+   pattern_regex = build_string (regex);
+ 
+   for (i = 0; i < font_name_count; i++)
+     {
+       fontname = build_string (font_name_table[i]);
+       if (fast_string_match (pattern_regex, fontname) >= 0)
+       {
+         font_list = Fcons (fontname, font_list);
+ 
+           n_fonts++;
+           if (n_fonts >= maxnames)
+             break;
+       }
+     }
+   return font_list;
+ }
+ 
  /* Return a list of at most MAXNAMES font specs matching the one in
     PATTERN.  Cache matching fonts for patterns in
     dpyinfo->name_list_element to avoid looking them up again by
***************
*** 10797,10803 ****
                int size,
                int maxnames)
  {
-   char *ptnstr;
    Lisp_Object newlist = Qnil, tem, key;
    int n_fonts = 0;
    int i;
--- 10917,10922 ----
***************
*** 10820,10846 ****
        }
      }
  
!   ptnstr = SDATA (pattern);
! 
!   GCPRO2 (pattern, newlist);
! 
!   /* Scan and matching bitmap fonts.  */
!   for (i = 0; i < font_name_count; i++)
!     {
!       if (mac_font_pattern_match (font_name_table[i], ptnstr))
!         {
!           newlist = Fcons (build_string (font_name_table[i]), newlist);
  
-           n_fonts++;
-           if (n_fonts >= maxnames)
-             break;
-         }
-     }
-   
    /* MAC_TODO: add code for matching outline fonts here */
  
-   UNGCPRO;
- 
    if (dpyinfo)
      {
        XSETCDR (dpyinfo->name_list_element,
--- 10939,10948 ----
        }
      }
  
!   newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
  
    /* MAC_TODO: add code for matching outline fonts here */
  
    if (dpyinfo)
      {
        XSETCDR (dpyinfo->name_list_element,
***************
*** 11000,11013 ****
      name = fontname;
    else
      {
!       for (i = 0; i < font_name_count; i++)
!         if (mac_font_pattern_match (font_name_table[i], fontname))
!           break;
  
!       if (i >= font_name_count)
!         return NULL;
!   
!       name = font_name_table[i];
      }
  
    GetPort (&port);  /* save the current font number used */
--- 11102,11113 ----
      name = fontname;
    else
      {
!       Lisp_Object matched_fonts;
  
!       matched_fonts = mac_do_list_fonts (fontname, 1);
!       if (NILP (matched_fonts))
!       return NULL;
!       name = SDATA (XCAR (matched_fonts));
      }
  
    GetPort (&port);  /* save the current font number used */

reply via email to

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