changeset 61658:38a086380ddc

(Qbig5, Qcn_gb, Qsjis, Qeuc_kr): Remove variables. (syms_of_mac): Don't initialize them. (Vmac_charset_info_alist): New variable. (syms_of_mac): Defvar it. (create_text_encoding_info_alist): New function. (decode_mac_font_name, mac_to_x_fontname) (x_font_name_to_mac_font_name, init_font_name_table): Don't hard code the correspondence among XLFD charsets, Mac script codes, and Emacs coding systems. Use Vmac_charset_info_alist and result of create_text_encoding_info_alist instead. (init_font_name_table) [TARGET_API_MAC_CARBON]: Use Font Manager routines also on Mac OS Classic. (init_font_name_table) [!TARGET_API_MAC_CARBON]: Use add_font_name_table_entry. (mac_do_list_fonts): Regard 0 in XLFD scaleble fields as specified. Derive unspecified scalable fields from specified one. (x_list_fonts): Consider Valternate_fontname_alist. (kDefaultFontSize): Change value from 9 to 12. (XLoadQueryFont): Get decoded font family, font face, and charset from x_font_name_to_mac_font_name. Set full name of loaded font. (mac_unload_font): Free `full_name' member. (x_load_font): Don't try XLoadQueryFont if x_list_fonts returns NULL. Copy full_name member of struct MacFontStruct to that of struct font_info.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Tue, 19 Apr 2005 12:04:09 +0000
parents 8af99087c1e5
children e40b2bd9a366
files src/macterm.c
diffstat 1 files changed, 362 insertions(+), 432 deletions(-) [+]
line wrap: on
line diff
--- a/src/macterm.c	Tue Apr 19 12:03:38 2005 +0000
+++ b/src/macterm.c	Tue Apr 19 12:04:09 2005 +0000
@@ -5841,121 +5841,59 @@
 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)
-{
-  for ( ; tolower (*s) == tolower (*t); s++, t++)
-    if (*s == '\0')
-      return 0;
-  return tolower (*s) - tolower (*t);
-}
-
-/* compare two strings ignoring case and handling wildcard */
-static int
-wildstrieq (char *s1, char *s2)
-{
-  if (strcmp (s1, "*") == 0 || strcmp (s2, "*") == 0)
-    return true;
-
-  return stricmp (s1, s2) == 0;
-}
-
-/* Assume parameter 1 is fully qualified, no wildcards. */
-static int
-mac_font_pattern_match (fontname, pattern)
-    char * fontname;
-    char * pattern;
-{
-  char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
-  char *font_name_copy = (char *) 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++ = '*';
-        }
+/* Alist linking character set strings to Mac text encoding and Emacs
+   coding system. */
+static Lisp_Object Vmac_charset_info_alist;
+
+static Lisp_Object
+create_text_encoding_info_alist ()
+{
+  Lisp_Object result = Qnil, rest;
+
+  for (rest = Vmac_charset_info_alist; CONSP (rest); rest = XCDR (rest))
+    {
+      Lisp_Object charset_info = XCAR (rest);
+      Lisp_Object charset, coding_system, text_encoding;
+      Lisp_Object existing_info;
+
+      if (!(CONSP (charset_info)
+	    && STRINGP (charset = XCAR (charset_info))
+	    && CONSP (XCDR (charset_info))
+	    && INTEGERP (text_encoding = XCAR (XCDR (charset_info)))
+	    && CONSP (XCDR (XCDR (charset_info)))
+	    && SYMBOLP (coding_system = XCAR (XCDR (XCDR (charset_info))))))
+	continue;
+
+      existing_info = assq_no_quit (text_encoding, result);
+      if (NILP (existing_info))
+	result = Fcons (list3 (text_encoding, coding_system, charset),
+			result);
       else
-        *ptr++ = *pattern;
-    }
-  *ptr = '$';
-  *(ptr + 1) = '\0';
-
-  return (fast_c_string_match_ignore_case (build_string (regex),
-                                           font_name_copy) >= 0);
-}
-
-/* Two font specs are considered to match if their foundry, family,
-   weight, slant, and charset match.  */
-static int
-mac_font_match (char *mf, char *xf)
-{
-  char m_foundry[50], m_family[50], m_weight[20], m_slant[2], m_charset[20];
-  char x_foundry[50], x_family[50], x_weight[20], x_slant[2], x_charset[20];
-
-  if (sscanf (mf, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
-              m_foundry, m_family, m_weight, m_slant, m_charset) != 5)
-    return mac_font_pattern_match (mf, xf);
-
-  if (sscanf (xf, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
-              x_foundry, x_family, x_weight, x_slant, x_charset) != 5)
-    return mac_font_pattern_match (mf, xf);
-
-  return (wildstrieq (m_foundry, x_foundry)
-          && wildstrieq (m_family, x_family)
-          && wildstrieq (m_weight, x_weight)
-          && wildstrieq (m_slant, x_slant)
-          && wildstrieq (m_charset, x_charset))
-         || mac_font_pattern_match (mf, xf);
-}
-#endif
-
-static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
-
-static void
-decode_mac_font_name (name, size, scriptcode)
+	if (NILP (Fmember (charset, XCDR (XCDR (existing_info)))))
+	  XSETCDR (XCDR (existing_info),
+		   Fcons (charset, XCDR (XCDR (existing_info))));
+    }
+
+  return result;
+}
+
+
+static void
+decode_mac_font_name (name, size, coding_system)
      char *name;
      int size;
-#if TARGET_API_MAC_CARBON
-     int scriptcode;
-#else
-     short scriptcode;
-#endif
-{
-  Lisp_Object coding_system;
+     Lisp_Object coding_system;
+{
   struct coding_system coding;
-  char *buf;
-
-  switch (scriptcode)
-    {
-    case smTradChinese:
-      coding_system = Qbig5;
-      break;
-    case smSimpChinese:
-      coding_system = Qcn_gb;
+  char *buf, *p;
+
+  for (p = name; *p; p++)
+    if (!isascii (*p) || iscntrl (*p))
       break;
-    case smJapanese:
-      coding_system = Qsjis;
-      break;
-    case smKorean:
-      coding_system = Qeuc_kr;
-      break;
-    default:
-      return;
-    }
+
+  if (*p == '\0'
+      || NILP (coding_system) || NILP (Fcoding_system_p (coding_system)))
+    return;
 
   setup_coding_system (coding_system, &coding);
   coding.src_multibyte = 0;
@@ -5971,68 +5909,26 @@
 
 
 static char *
-mac_to_x_fontname (name, size, style, scriptcode)
+mac_to_x_fontname (name, size, style, charset)
      char *name;
      int size;
      Style style;
-#if TARGET_API_MAC_CARBON
-     int scriptcode;
-#else
-     short scriptcode;
-#endif
+     char *charset;
 {
   char foundry[32], family[32], cs[32];
   char xf[256], *result, *p;
 
-  if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3)
+  if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) == 3)
+    charset = cs;
+  else
     {
       strcpy(foundry, "Apple");
       strcpy(family, name);
-
-      switch (scriptcode)
-      {
-      case smTradChinese:	/* == kTextEncodingMacChineseTrad */
-        strcpy(cs, "big5-0");
-        break;
-      case smSimpChinese:	/* == kTextEncodingMacChineseSimp */
-        strcpy(cs, "gb2312.1980-0");
-        break;
-      case smJapanese:		/* == kTextEncodingMacJapanese */
-        strcpy(cs, "jisx0208.1983-sjis");
-        break;
-      case -smJapanese:
-	/* Each Apple Japanese font is entered into the font table
-	   twice: once as a jisx0208.1983-sjis font and once as a
-	   jisx0201.1976-0 font.  The latter can be used to display
-	   the ascii charset and katakana-jisx0201 charset.  A
-	   negative script code signals that the name of this latter
-	   font is being built.  */
-	strcpy(cs, "jisx0201.1976-0");
-	break;
-      case smKorean:		/* == kTextEncodingMacKorean */
-        strcpy(cs, "ksc5601.1989-0");
-        break;
-#if TARGET_API_MAC_CARBON
-      case kTextEncodingMacCyrillic:
-	strcpy(cs, "mac-cyrillic");
-	break;
-      case kTextEncodingMacCentralEurRoman:
-	strcpy(cs, "mac-centraleurroman");
-	break;
-      case kTextEncodingMacSymbol:
-      case kTextEncodingMacDingbats:
-	strcpy(cs, "adobe-fontspecific");
-	break;
-#endif
-      default:
-	strcpy(cs, "mac-roman");
-	break;
-      }
     }
 
   sprintf(xf, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
           foundry, family, style & bold ? "bold" : "medium",
-	  style & italic ? 'i' : 'r', size, size * 10, size * 10, cs);
+	  style & italic ? 'i' : 'r', size, size * 10, size * 10, charset);
 
   result = (char *) xmalloc (strlen (xf) + 1);
   strcpy (result, xf);
@@ -6050,10 +5946,13 @@
    "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc.  Both types of font
    names are handled accordingly.  */
 static void
-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;
+x_font_name_to_mac_font_name (xf, mf, mf_decoded, style, cs)
+     char *xf, *mf, *mf_decoded;
+     Style *style;
+     char *cs;
+{
+  char foundry[32], family[32], weight[20], slant[2], *p;
+  Lisp_Object charset_info, coding_system = Qnil;
   struct coding_system coding;
 
   strcpy (mf, "");
@@ -6064,30 +5963,36 @@
               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 = Qcn_gb;
-  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
-	   || strcmp (cs, "mac-cyrillic") == 0
-	   || strcmp (cs, "mac-centraleurroman") == 0
-	   || strcmp (cs, "adobe-fontspecific") == 0)
-    strcpy (mf, family);
+  *style = normal;
+  if (strcmp (weight, "bold") == 0)
+    *style |= bold;
+  if (*slant == 'i')
+    *style |= italic;
+
+  charset_info = Fassoc (build_string (cs), Vmac_charset_info_alist);
+  if (!NILP (charset_info))
+    {
+      strcpy (mf_decoded, family);
+      coding_system = Fcar (Fcdr (Fcdr (charset_info)));
+    }
   else
-    sprintf (mf, "%s-%s-%s", foundry, family, cs);
-
-  if (!NILP (coding_system))
+    sprintf (mf_decoded, "%s-%s-%s", foundry, family, cs);
+
+  for (p = mf_decoded; *p; p++)
+    if (!isascii (*p) || iscntrl (*p))
+      break;
+
+  if (*p == '\0'
+      || NILP (coding_system) || NILP (Fcoding_system_p (coding_system)))
+    strcpy (mf, mf_decoded);
+  else
     {
       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);
+      encode_coding (&coding, mf_decoded, mf,
+		     strlen (mf_decoded), sizeof (Str32) - 1);
       mf[coding.produced] = '\0';
     }
 }
@@ -6122,181 +6027,180 @@
 init_font_name_table ()
 {
 #if TARGET_API_MAC_CARBON
-  SInt32 sv;
-
-  if (Gestalt (gestaltSystemVersion, &sv) == noErr && sv >= 0x1000)
-    {
-      FMFontFamilyIterator ffi;
-      FMFontFamilyInstanceIterator ffii;
-      FMFontFamily ff;
-
-      /* Create a dummy instance iterator here to avoid creating and
-	 destroying it in the loop.  */
-      if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr)
-	return;
-      /* Create an iterator to enumerate the font families.  */
-      if (FMCreateFontFamilyIterator (NULL, NULL, kFMDefaultOptions, &ffi)
-	  != noErr)
-	{
-	  FMDisposeFontFamilyInstanceIterator (&ffii);
-	  return;
-	}
-
-      while (FMGetNextFontFamily (&ffi, &ff) == noErr)
+  FMFontFamilyIterator ffi;
+  FMFontFamilyInstanceIterator ffii;
+  FMFontFamily ff;
+  Lisp_Object text_encoding_info_alist;
+  struct gcpro gcpro1;
+
+  /* Create a dummy instance iterator here to avoid creating and
+     destroying it in the loop.  */
+  if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr)
+    return;
+  /* Create an iterator to enumerate the font families.  */
+  if (FMCreateFontFamilyIterator (NULL, NULL, kFMDefaultOptions, &ffi)
+      != noErr)
+    {
+      FMDisposeFontFamilyInstanceIterator (&ffii);
+      return;
+    }
+
+  text_encoding_info_alist = create_text_encoding_info_alist ();
+
+  GCPRO1 (text_encoding_info_alist);
+
+  while (FMGetNextFontFamily (&ffi, &ff) == noErr)
+    {
+      Str255 name;
+      FMFont font;
+      FMFontStyle style;
+      FMFontSize size;
+      TextEncoding encoding;
+      TextEncodingBase sc;
+      Lisp_Object text_encoding_info;
+
+      if (FMGetFontFamilyName (ff, name) != noErr)
+	break;
+      p2cstr (name);
+      if (*name == '.')
+	continue;
+
+      if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
+	break;
+      sc = GetTextEncodingBase (encoding);
+      text_encoding_info = assq_no_quit (make_number (sc),
+					 text_encoding_info_alist);
+      if (!NILP (text_encoding_info))
+	decode_mac_font_name (name, sizeof (name),
+			      XCAR (XCDR (text_encoding_info)));
+      else
+	text_encoding_info = assq_no_quit (make_number (kTextEncodingMacRoman),
+					   text_encoding_info_alist);
+
+      /* Point the instance iterator at the current font family.  */
+      if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
+	break;
+
+      while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
+	     == noErr)
 	{
-	  Str255 name;
-	  FMFont font;
-	  FMFontStyle style;
-	  FMFontSize size;
-	  TextEncoding encoding;
-	  TextEncodingBase sc;
-
-	  if (FMGetFontFamilyName (ff, name) != noErr)
-	    break;
-	  p2cstr (name);
-	  if (*name == '.')
-	    continue;
-
-	  if (FMGetFontFamilyTextEncoding (ff, &encoding) != noErr)
-	    break;
-	  sc = GetTextEncodingBase (encoding);
-	  decode_mac_font_name (name, sizeof (name), sc);
-
-	  /* Point the instance iterator at the current font family.  */
-	  if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
-	    break;
-
-	  while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
-		 == noErr)
+	  Lisp_Object rest = XCDR (XCDR (text_encoding_info));
+
+	  for (; !NILP (rest); rest = XCDR (rest))
 	    {
-	      /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
-		 contained in Apple Japanese (SJIS) font.  */
-	    again:
+	      char *cs = SDATA (XCAR (rest));
+
 	      if (size == 0)
 		{
 		  add_font_name_table_entry (mac_to_x_fontname (name, size,
-								style, sc));
+								style, cs));
 		  add_font_name_table_entry (mac_to_x_fontname (name, size,
-								italic, sc));
+								italic, cs));
 		  add_font_name_table_entry (mac_to_x_fontname (name, size,
-								bold, sc));
+								bold, cs));
 		  add_font_name_table_entry (mac_to_x_fontname (name, size,
 								italic | bold,
-								sc));
+								cs));
 		}
 	      else
-		add_font_name_table_entry (mac_to_x_fontname (name, size,
-							      style, sc));
-	      if (sc == smJapanese)
 		{
-		  sc = -smJapanese;
-		  goto again;
+		  add_font_name_table_entry (mac_to_x_fontname (name, size,
+								style, cs));
 		}
-	      else if (sc == -smJapanese)
-		sc = smJapanese;
 	    }
 	}
-
-      /* Dispose of the iterators.  */
-      FMDisposeFontFamilyIterator (&ffi);
-      FMDisposeFontFamilyInstanceIterator (&ffii);
-    }
-  else
-    {
-#endif  /* TARGET_API_MAC_CARBON */
-      GrafPtr port;
-      SInt16 fontnum, old_fontnum;
-      int num_mac_fonts = CountResources('FOND');
-      int i, j;
-      Handle font_handle, font_handle_2;
-      short id, scriptcode;
-      ResType type;
-      Str32 name;
-      struct FontAssoc *fat;
-      struct AsscEntry *assc_entry;
-
-      GetPort (&port);  /* save the current font number used */
-#if TARGET_API_MAC_CARBON
-      old_fontnum = GetPortTextFont (port);
-#else
-      old_fontnum = port->txFont;
-#endif
-
-      for (i = 1; i <= num_mac_fonts; i++)  /* get all available fonts */
+    }
+
+  UNGCPRO;
+
+  /* Dispose of the iterators.  */
+  FMDisposeFontFamilyIterator (&ffi);
+  FMDisposeFontFamilyInstanceIterator (&ffii);
+#else  /* !TARGET_API_MAC_CARBON */
+  GrafPtr port;
+  SInt16 fontnum, old_fontnum;
+  int num_mac_fonts = CountResources('FOND');
+  int i, j;
+  Handle font_handle, font_handle_2;
+  short id, scriptcode;
+  ResType type;
+  Str32 name;
+  struct FontAssoc *fat;
+  struct AsscEntry *assc_entry;
+  Lisp_Object text_encoding_info_alist, text_encoding_info;
+  struct gcpro gcpro1;
+
+  GetPort (&port);  /* save the current font number used */
+  old_fontnum = port->txFont;
+
+  text_encoding_info_alist = create_text_encoding_info_alist ();
+
+  GCPRO1 (text_encoding_info_alist);
+
+  for (i = 1; i <= num_mac_fonts; i++)  /* get all available fonts */
+    {
+      font_handle = GetIndResource ('FOND', i);
+      if (!font_handle)
+	continue;
+
+      GetResInfo (font_handle, &id, &type, name);
+      GetFNum (name, &fontnum);
+      p2cstr (name);
+      if (fontnum == 0)
+	continue;
+
+      TextFont (fontnum);
+      scriptcode = FontToScript (fontnum);
+      text_encoding_info = assq_no_quit (make_number (scriptcode),
+					 text_encoding_info_alist);
+      if (!NILP (text_encoding_info))
+	decode_mac_font_name (name, sizeof (name),
+			      XCAR (XCDR (text_encoding_info)));
+      else
+	text_encoding_info = assq_no_quit (make_number (smRoman),
+					   text_encoding_info_alist);
+      do
 	{
-	  font_handle = GetIndResource ('FOND', i);
-	  if (!font_handle)
-	    continue;
-
-	  GetResInfo (font_handle, &id, &type, name);
-	  GetFNum (name, &fontnum);
-	  p2cstr (name);
-	  if (fontnum == 0)
-	    continue;
-
-	  TextFont (fontnum);
-	  scriptcode = FontToScript (fontnum);
-	  decode_mac_font_name (name, sizeof (name), scriptcode);
-	  do
+	  HLock (font_handle);
+
+	  if (GetResourceSizeOnDisk (font_handle)
+	      >= sizeof (struct FamRec))
 	    {
-	      HLock (font_handle);
-
-	      if (GetResourceSizeOnDisk (font_handle)
-		  >= sizeof (struct FamRec))
+	      fat = (struct FontAssoc *) (*font_handle
+					  + sizeof (struct FamRec));
+	      assc_entry
+		= (struct AsscEntry *) (*font_handle
+					+ sizeof (struct FamRec)
+					+ sizeof (struct FontAssoc));
+
+	      for (j = 0; j <= fat->numAssoc; j++, assc_entry++)
 		{
-		  fat = (struct FontAssoc *) (*font_handle
-					      + sizeof (struct FamRec));
-		  assc_entry
-		    = (struct AsscEntry *) (*font_handle
-					    + sizeof (struct FamRec)
-					    + sizeof (struct FontAssoc));
-
-		  for (j = 0; j <= fat->numAssoc; j++, assc_entry++)
+		  Lisp_Object rest = XCDR (XCDR (text_encoding_info));
+
+		  for (; !NILP (rest); rest = XCDR (rest))
 		    {
-		      if (font_name_table_size == 0)
-			{
-			  font_name_table_size = 16;
-			  font_name_table = (char **)
-			    xmalloc (font_name_table_size * sizeof (char *));
-			}
-		      else if (font_name_count >= font_name_table_size)
-			{
-			  font_name_table_size += 16;
-			  font_name_table = (char **)
-			    xrealloc (font_name_table,
-				      font_name_table_size * sizeof (char *));
-			}
-		      font_name_table[font_name_count++]
-			= mac_to_x_fontname (name,
-					     assc_entry->fontSize,
-					     assc_entry->fontStyle,
-					     scriptcode);
-		      /* Both jisx0208.1983-sjis and jisx0201.1976-0
-			 parts are contained in Apple Japanese (SJIS)
-			 font.  */
-		      if (smJapanese == scriptcode)
-			{
-			  font_name_table[font_name_count++]
-			    = mac_to_x_fontname (name,
-						 assc_entry->fontSize,
-						 assc_entry->fontStyle,
-						 -smJapanese);
-			}
+		      char *cs = SDATA (XCAR (rest));
+
+		      add_font_name_table_entry (mac_to_x_fontname (name,
+								    assc_entry->fontSize,
+								    assc_entry->fontStyle,
+								    cs));
 		    }
 		}
-
-	      HUnlock (font_handle);
-	      font_handle_2 = GetNextFOND (font_handle);
-	      ReleaseResource (font_handle);
-	      font_handle = font_handle_2;
 	    }
-	  while (ResError () == noErr && font_handle);
+
+	  HUnlock (font_handle);
+	  font_handle_2 = GetNextFOND (font_handle);
+	  ReleaseResource (font_handle);
+	  font_handle = font_handle_2;
 	}
-
-      TextFont (old_fontnum);
-#if TARGET_API_MAC_CARBON
-    }
-#endif  /* TARGET_API_MAC_CARBON */
+      while (ResError () == noErr && font_handle);
+    }
+
+  UNGCPRO;
+
+  TextFont (old_fontnum);
+#endif  /* !TARGET_API_MAC_CARBON */
 }
 
 
@@ -6384,7 +6288,7 @@
 	ptr++;
 	if (i == *field)
 	  {
-	    if ('1' <= *ptr && *ptr <= '9')
+	    if ('0' <= *ptr && *ptr <= '9')
 	      {
 		*val = *ptr++ - '0';
 		while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
@@ -6402,21 +6306,21 @@
 
   if (i == 14 && ptr == NULL)
     {
-      if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
-	{
-	  scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
-	  scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
-	}
-      else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
-	{
-	  scl_val[XLFD_SCL_POINT_SIZE] =
-	    scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
-	}
-      else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
-	{
-	  scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
-	  scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
-	}
+      if (scl_val[XLFD_SCL_PIXEL_SIZE] < 0)
+	scl_val[XLFD_SCL_PIXEL_SIZE] =
+	  (scl_val[XLFD_SCL_POINT_SIZE] > 0 ? scl_val[XLFD_SCL_POINT_SIZE] / 10
+	   : (scl_val[XLFD_SCL_AVGWIDTH] > 0 ? scl_val[XLFD_SCL_AVGWIDTH] / 10
+	      : -1));
+      if (scl_val[XLFD_SCL_POINT_SIZE] < 0)
+	scl_val[XLFD_SCL_POINT_SIZE] =
+	  (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 ? scl_val[XLFD_SCL_PIXEL_SIZE] * 10
+	   : (scl_val[XLFD_SCL_AVGWIDTH] > 0 ? scl_val[XLFD_SCL_AVGWIDTH]
+	      : -1));
+      if (scl_val[XLFD_SCL_AVGWIDTH] < 0)
+	scl_val[XLFD_SCL_AVGWIDTH] =
+	  (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 ? scl_val[XLFD_SCL_PIXEL_SIZE] * 10
+	   : (scl_val[XLFD_SCL_POINT_SIZE] > 0 ? scl_val[XLFD_SCL_POINT_SIZE]
+	      : -1));
     }
   else
     scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
@@ -6507,49 +6411,62 @@
   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
-   calling mac_font_pattern_match (slow).  Return as many matching
-   fonts as possible if MAXNAMES = -1.  */
+/* Return a list of names of available fonts matching PATTERN on frame F.
+
+   Frame F null means we have not yet created any frame on Mac, and
+   consult the first display in x_display_list.  MAXNAMES sets a limit
+   on how many fonts to match.  */
 
 Lisp_Object
-x_list_fonts (struct frame *f,
-              Lisp_Object pattern,
-              int size,
-              int maxnames)
-{
-  Lisp_Object newlist = Qnil, tem, key;
-  struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
-
-  if (dpyinfo)
-    {
+x_list_fonts (f, pattern, size, maxnames)
+     struct frame *f;
+     Lisp_Object pattern;
+     int size, maxnames;
+{
+  Lisp_Object list = Qnil, patterns, tem, key;
+  struct mac_display_info *dpyinfo
+    = f ? FRAME_MAC_DISPLAY_INFO (f) : x_display_list;
+
+  xassert (size <= 0);
+
+  patterns = Fassoc (pattern, Valternate_fontname_alist);
+  if (NILP (patterns))
+    patterns = Fcons (pattern, Qnil);
+
+  for (; CONSP (patterns); patterns = XCDR (patterns))
+    {
+      pattern = XCAR (patterns);
+
+      if (!STRINGP (pattern))
+        continue;
+
       tem = XCAR (XCDR (dpyinfo->name_list_element));
       key = Fcons (pattern, make_number (maxnames));
 
-      newlist = Fassoc (key, tem);
-      if (!NILP (newlist))
+      list = Fassoc (key, tem);
+      if (!NILP (list))
 	{
-	  newlist = Fcdr_safe (newlist);
+	  list = Fcdr_safe (list);
+	  /* We have a cashed list.  Don't have to get the list again.  */
 	  goto label_cached;
 	}
-    }
-
-  BLOCK_INPUT;
-  newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
-  UNBLOCK_INPUT;
-
-  /* MAC_TODO: add code for matching outline fonts here */
-
-  if (dpyinfo)
-    {
+
+      BLOCK_INPUT;
+      list = mac_do_list_fonts (SDATA (pattern), maxnames);
+      UNBLOCK_INPUT;
+
+      /* MAC_TODO: add code for matching outline fonts here */
+
+      /* Now store the result in the cache.  */
       XSETCAR (XCDR (dpyinfo->name_list_element),
-	       Fcons (Fcons (key, newlist),
+	       Fcons (Fcons (key, list),
 		      XCAR (XCDR (dpyinfo->name_list_element))));
-    }
- label_cached:
-
-  return newlist;
+
+    label_cached:
+      if (NILP (list)) continue; /* Try the remaining alternatives.  */
+    }
+
+  return list;
 }
 
 
@@ -6668,7 +6585,7 @@
 }
 
 
-const int kDefaultFontSize = 9;
+const int kDefaultFontSize = 12;
 
 
 /* XLoadQueryFont creates and returns an internal representation for a
@@ -6680,17 +6597,25 @@
 static MacFontStruct *
 XLoadQueryFont (Display *dpy, char *fontname)
 {
-  int i, size, is_two_byte_font, char_width;
+  int i, size, point_size, avgwidth, is_two_byte_font, char_width;
   char *name;
   GrafPtr port;
   SInt16 old_fontnum, old_fontsize;
   Style old_fontface;
-  Str32 mfontname;
+  Str32 mfontname, mfontname_decoded, charset;
   SInt16 fontnum;
-  Style fontface = normal;
+  Style fontface;
+#if TARGET_API_MAC_CARBON
+  TextEncoding encoding;
+  int scriptcode;
+#else
+  short scriptcode;
+#endif
   MacFontStruct *font;
   FontInfo the_fontinfo;
-  char s_weight[7], c_slant;
+#ifdef MAC_OSX
+  UInt32 old_flags, new_flags;
+#endif
 
   if (is_fully_specified_xlfd (fontname))
     name = fontname;
@@ -6715,46 +6640,50 @@
   old_fontface = port->txFace;
 #endif
 
-  if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size) != 1)
+  if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%*s", &size, &point_size, &avgwidth) != 3)
+    size = 0;
+  else
+    {
+      if (size == 0)
+	if (point_size > 0)
+	  size = point_size / 10;
+	else if (avgwidth > 0)
+	  size = avgwidth / 10;
+    }
+  if (size == 0)
     size = kDefaultFontSize;
 
-  if (sscanf (name, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight) == 1)
-    if (strcmp (s_weight, "bold") == 0)
-      fontface |= bold;
-
-  if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant) == 1)
-    if (c_slant == 'i')
-      fontface |= italic;
-
-  x_font_name_to_mac_font_name (name, mfontname);
+  x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded,
+				&fontface, charset);
   c2pstr (mfontname);
+#if TARGET_API_MAC_CARBON
+  fontnum = FMGetFontFamilyFromName (mfontname);
+  if (fontnum == kInvalidFontFamily
+      || FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr)
+    return NULL;
+  scriptcode = GetTextEncodingBase (encoding);
+#else
   GetFNum (mfontname, &fontnum);
   if (fontnum == 0)
     return NULL;
+  scriptcode = FontToScript (fontnum);
+#endif
 
   font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct));
 
-  font->fontname = (char *) xmalloc (strlen (name) + 1);
-  bcopy (name, font->fontname, strlen (name) + 1);
-
   font->mac_fontnum = fontnum;
   font->mac_fontsize = size;
   font->mac_fontface = fontface;
-  font->mac_scriptcode = FontToScript (fontnum);
+  font->mac_scriptcode = scriptcode;
 
   /* Apple Japanese (SJIS) font is listed as both
      "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
      (Roman script) in init_font_name_table ().  The latter should be
      treated as a one-byte font.  */
-  {
-    char cs[32];
-
-    if (sscanf (name,
-		"-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
-		cs) == 1
-	&& 0 == strcmp (cs, "jisx0201.1976-0"))
-      font->mac_scriptcode = smRoman;
-  }
+  if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0)
+    font->mac_scriptcode = smRoman;
+
+  font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset);
 
   is_two_byte_font = font->mac_scriptcode == smJapanese ||
                      font->mac_scriptcode == smTradChinese ||
@@ -6879,7 +6808,7 @@
      struct mac_display_info *dpyinfo;
      XFontStruct *font;
 {
-  xfree (font->fontname);
+  xfree (font->full_name);
   if (font->per_char)
     xfree (font->per_char);
   xfree (font);
@@ -6919,6 +6848,8 @@
 			      SDATA (XCAR (tail)))))
 	    return (dpyinfo->font_table + i);
     }
+  else
+    return NULL;
 
   /* Load the font and add it to the table.  */
   {
@@ -6928,13 +6859,7 @@
     unsigned long value;
     int i;
 
-    /* If we have found fonts by x_list_font, load one of them.  If
-       not, we still try to load a font by the name given as FONTNAME
-       because XListFonts (called in x_list_font) of some X server has
-       a bug of not finding a font even if the font surely exists and
-       is loadable by XLoadQueryFont.  */
-    if (size > 0 && !NILP (font_names))
-      fontname = (char *) SDATA (XCAR (font_names));
+    fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
     font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
@@ -6967,8 +6892,8 @@
     bzero (fontp, sizeof (*fontp));
     fontp->font = font;
     fontp->font_idx = i;
-    fontp->name = (char *) xmalloc (strlen (font->fontname) + 1);
-    bcopy (font->fontname, fontp->name, strlen (font->fontname) + 1);
+    fontp->name = (char *) xmalloc (strlen (fontname) + 1);
+    bcopy (fontname, fontp->name, strlen (fontname) + 1);
 
     if (font->min_bounds.width == font->max_bounds.width)
       {
@@ -6999,7 +6924,8 @@
 	  fontp->average_width = FONT_WIDTH (font);
       }
 
-    fontp->full_name = fontp->name;
+    fontp->full_name = (char *) xmalloc (strlen (font->full_name) + 1);
+    bcopy (font->full_name, fontp->full_name, strlen (font->full_name) + 1);
 
     fontp->size = font->max_bounds.width;
     fontp->height = FONT_HEIGHT (font);
@@ -9810,18 +9736,6 @@
   Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
   staticpro (&Qmac_ready_for_drag_n_drop);
 
-  Qbig5 = intern ("big5");
-  staticpro (&Qbig5);
-
-  Qcn_gb = intern ("cn-gb");
-  staticpro (&Qcn_gb);
-
-  Qsjis = intern ("sjis");
-  staticpro (&Qsjis);
-
-  Qeuc_kr = intern ("euc-kr");
-  staticpro (&Qeuc_kr);
-
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
 	       doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
   Vx_toolkit_scroll_bars = Qt;
@@ -9888,6 +9802,22 @@
 The text will be rendered using Core Graphics text rendering which
 may anti-alias the text.  */);
   Vmac_use_core_graphics = Qnil;
+
+  /* Register an entry for `mac-roman' so that it can be used when
+     creating the terminal frame on Mac OS 9 before loading
+     term/mac-win.elc.  */
+  DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist,
+               doc: /* Alist linking Emacs character sets to Mac text encoding and Emacs coding system.
+Each entry should be of the form:
+
+   (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
+
+where CHARSET-NAME is a string used in font names to identify the
+charset, TEXT-ENCODING is a TextEncodingBase value, and CODING_SYSTEM
+is a coding system corresponding to TEXT-ENCODING.  */);
+  Vmac_charset_info_alist =
+    Fcons (list3 (build_string ("mac-roman"),
+		  make_number (smRoman), Qnil), Qnil);
 }
 
 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b