Change a lot of `(if .. (progn ..)' to `(when ..)'.
[bpt/emacs.git] / src / xfaces.c
index 0251310..df303e4 100644 (file)
@@ -1,6 +1,6 @@
 /* xfaces.c -- "Face" primitives.
-   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation.
+   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -274,6 +274,10 @@ Boston, MA 02110-1301, USA.  */
 
 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
 
+/* Non-zero if face attribute ATTR is `ignore-defface'.  */
+
+#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), Qignore_defface)
+
 /* Value is the number of elements of VECTOR.  */
 
 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
@@ -312,6 +316,7 @@ Lisp_Object Qultra_expanded;
 Lisp_Object Qreleased_button, Qpressed_button;
 Lisp_Object QCstyle, QCcolor, QCline_width;
 Lisp_Object Qunspecified;
+Lisp_Object Qignore_defface;
 
 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
 
@@ -790,7 +795,10 @@ x_create_gc (f, mask, xgcv)
      XGCValues *xgcv;
 {
   GC gc;
+  BLOCK_INPUT;
   gc = XCreateGC (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), mask, xgcv);
+  UNBLOCK_INPUT;
+  IF_DEBUG (++ngcs);
   return gc;
 }
 
@@ -799,7 +807,10 @@ x_free_gc (f, gc)
      struct frame *f;
      GC gc;
 {
+  BLOCK_INPUT;
+  IF_DEBUG (xassert (--ngcs >= 0));
   XFreeGC (FRAME_MAC_DISPLAY (f), gc);
+  UNBLOCK_INPUT;
 }
 
 #endif  /* MAC_OS */
@@ -835,7 +846,10 @@ xstrlwr (s)
   unsigned char *p = s;
 
   for (p = s; *p; ++p)
-    *p = tolower (*p);
+    /* On Mac OS X 10.3, tolower also converts non-ASCII characters
+       for some locales.  */
+    if (isascii (*p))
+      *p = tolower (*p);
 
   return s;
 }
@@ -1474,7 +1488,9 @@ tty_color_name (f, idx)
 
 
 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
-   black) on frame F.  The algorithm is taken from 20.2 faces.el.  */
+   black) on frame F.
+
+   The criterion implemented here is not a terribly sophisticated one.  */
 
 static int
 face_color_gray_p (f, color_name)
@@ -1485,12 +1501,15 @@ face_color_gray_p (f, color_name)
   int gray_p;
 
   if (defined_color (f, color_name, &color, 0))
-    gray_p = ((abs (color.red - color.green)
-              < max (color.red, color.green) / 20)
-             && (abs (color.green - color.blue)
-                 < max (color.green, color.blue) / 20)
-             && (abs (color.blue - color.red)
-                 < max (color.blue, color.red) / 20));
+    gray_p = (/* Any color sufficiently close to black counts as grey.  */
+             (color.red < 5000 && color.green < 5000 && color.blue < 5000)
+             ||
+             ((abs (color.red - color.green)
+               < max (color.red, color.green) / 20)
+              && (abs (color.green - color.blue)
+                  < max (color.green, color.blue) / 20)
+              && (abs (color.blue - color.red)
+                  < max (color.blue, color.red) / 20)));
   else
     gray_p = 0;
 
@@ -3090,48 +3109,64 @@ check_lface_attrs (attrs)
      Lisp_Object *attrs;
 {
   xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
           || STRINGP (attrs[LFACE_FAMILY_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
           || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_AVGWIDTH_INDEX])
           || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
           || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
           || FLOATP (attrs[LFACE_HEIGHT_INDEX])
           || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
           || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
           || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
           || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
           || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
           || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
           || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
           || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
           || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
           || SYMBOLP (attrs[LFACE_BOX_INDEX])
           || STRINGP (attrs[LFACE_BOX_INDEX])
           || INTEGERP (attrs[LFACE_BOX_INDEX])
           || CONSP (attrs[LFACE_BOX_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
           || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
           || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
           || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
           || NILP (attrs[LFACE_INHERIT_INDEX])
           || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
           || CONSP (attrs[LFACE_INHERIT_INDEX]));
 #ifdef HAVE_WINDOW_SYSTEM
   xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
           || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
           || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
   xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
+          || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
           || NILP (attrs[LFACE_FONT_INDEX])
           || STRINGP (attrs[LFACE_FONT_INDEX]));
 #endif
@@ -3326,7 +3361,7 @@ lface_fully_specified_p (attrs)
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
        && i != LFACE_AVGWIDTH_INDEX)
-      if (UNSPECIFIEDP (attrs[i])
+      if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
 #ifdef MAC_OS
         /* MAC_TODO: No stipple support on Mac OS yet, this index is
            always unspecified.  */
@@ -3907,7 +3942,7 @@ Value is a vector of face attributes.  */)
 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
        Sinternal_lisp_face_p, 1, 2, 0,
        doc: /* Return non-nil if FACE names a face.
-If optional second parameter FRAME is non-nil, check for the
+If optional second argument FRAME is non-nil, check for the
 existence of a frame-local face with name FACE on that frame.
 Otherwise check for the existence of a global face.  */)
      (face, frame)
@@ -4017,7 +4052,18 @@ FRAME 0 means change the face on all frames, and change the default
 
   /* Set lface to the Lisp attribute vector of FACE.  */
   if (EQ (frame, Qt))
-    lface = lface_from_face_name (NULL, face, 1);
+    {
+      lface = lface_from_face_name (NULL, face, 1);
+
+      /* When updating face-new-frame-defaults, we put :ignore-defface
+        where the caller wants `unspecified'.  This forces the frame
+        defaults to ignore the defface value.  Otherwise, the defface
+        will take effect, which is generally not what is intended.
+        The value of that attribute will be inherited from some other
+        face during face merging.  See internal_merge_in_global_face. */
+      if (UNSPECIFIEDP (value))
+       value = Qignore_defface;
+    }
   else
     {
       if (NILP (frame))
@@ -4033,7 +4079,7 @@ FRAME 0 means change the face on all frames, and change the default
 
   if (EQ (attr, QCfamily))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          CHECK_STRING (value);
          if (SCHARS (value) == 0)
@@ -4045,7 +4091,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCheight))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          Lisp_Object test;
 
@@ -4066,7 +4112,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCweight))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          CHECK_SYMBOL (value);
          if (face_numeric_weight (value) < 0)
@@ -4078,7 +4124,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCslant))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          CHECK_SYMBOL (value);
          if (face_numeric_slant (value) < 0)
@@ -4090,7 +4136,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCunderline))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        if ((SYMBOLP (value)
             && !EQ (value, Qt)
             && !EQ (value, Qnil))
@@ -4104,7 +4150,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCoverline))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        if ((SYMBOLP (value)
             && !EQ (value, Qt)
             && !EQ (value, Qnil))
@@ -4118,7 +4164,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCstrike_through))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        if ((SYMBOLP (value)
             && !EQ (value, Qt)
             && !EQ (value, Qnil))
@@ -4139,7 +4185,7 @@ FRAME 0 means change the face on all frames, and change the default
       if (EQ (value, Qt))
        value = make_number (1);
 
-      if (UNSPECIFIEDP (value))
+      if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
        valid_p = 1;
       else if (NILP (value))
        valid_p = 1;
@@ -4196,7 +4242,7 @@ FRAME 0 means change the face on all frames, and change the default
   else if (EQ (attr, QCinverse_video)
           || EQ (attr, QCreverse_video))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          CHECK_SYMBOL (value);
          if (!EQ (value, Qt) && !NILP (value))
@@ -4207,7 +4253,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCforeground))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          /* Don't check for valid color names here because it depends
             on the frame (display) whether the color will be valid
@@ -4221,7 +4267,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCbackground))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          /* Don't check for valid color names here because it depends
             on the frame (display) whether the color will be valid
@@ -4236,7 +4282,7 @@ FRAME 0 means change the face on all frames, and change the default
   else if (EQ (attr, QCstipple))
     {
 #ifdef HAVE_X_WINDOWS
-      if (!UNSPECIFIEDP (value)
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
          && !NILP (value)
          && NILP (Fbitmap_spec_p (value)))
        signal_error ("Invalid stipple attribute", value);
@@ -4246,7 +4292,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCwidth))
     {
-      if (!UNSPECIFIEDP (value))
+      if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
        {
          CHECK_SYMBOL (value);
          if (face_numeric_swidth (value) < 0)
@@ -4271,7 +4317,7 @@ FRAME 0 means change the face on all frames, and change the default
          else
            f = check_x_frame (frame);
 
-         if (!UNSPECIFIEDP (value))
+         if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
            {
              CHECK_STRING (value);
 
@@ -4319,7 +4365,7 @@ FRAME 0 means change the face on all frames, and change the default
     signal_error ("Invalid face attribute name", attr);
 
   if (font_related_attr_p
-      && !UNSPECIFIEDP (value))
+      && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
     /* If a font-related attribute other than QCfont is specified, the
        original `font' attribute nor that of default face is useless
        to determine a new font.  Thus, we set it to nil so that font
@@ -4340,7 +4386,7 @@ FRAME 0 means change the face on all frames, and change the default
       ++windows_or_buffers_changed;
     }
 
-  if (!UNSPECIFIEDP (value)
+  if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
       && NILP (Fequal (old_value, value)))
     {
       Lisp_Object param;
@@ -4641,7 +4687,7 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource",
       if (SYMBOLP (boolean_value))
        value = boolean_value;
     }
-  else if (EQ (attr, QCbox))
+  else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
     value = Fcar (Fread_from_string (value, Qnil, Qnil));
 
   return Finternal_set_lisp_face_attribute (face, attr, value, frame);
@@ -4757,7 +4803,7 @@ DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
      (attribute, value)
      Lisp_Object attribute, value;
 {
-  if (EQ (value, Qunspecified))
+  if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
     return Qt;
   else if (EQ (attribute, QCheight))
     return INTEGERP (value) ? Qnil : Qt;
@@ -4773,7 +4819,7 @@ the result will be absolute, otherwise it will be relative.  */)
      (attribute, value1, value2)
      Lisp_Object attribute, value1, value2;
 {
-  if (EQ (value1, Qunspecified))
+  if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
     return value2;
   else if (EQ (attribute, QCheight))
     return merge_face_heights (value1, value2, value1);
@@ -4843,6 +4889,9 @@ frames).  If FRAME is omitted or nil, use the selected frame.  */)
   else
     signal_error ("Invalid face attribute name", keyword);
 
+  if (IGNORE_DEFFACE_P (value))
+    return Qunspecified;
+
   return value;
 }
 
@@ -4925,7 +4974,12 @@ Default face attributes override any local face attributes.  */)
   gvec = XVECTOR (global_lface)->contents;
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (! UNSPECIFIEDP (gvec[i]))
-      lvec[i] = gvec[i];
+      {
+       if (IGNORE_DEFFACE_P (gvec[i]))
+         lvec[i] = Qunspecified;
+       else
+         lvec[i] = gvec[i];
+      }
 
   return Qnil;
 }
@@ -5807,6 +5861,7 @@ lookup_derived_face (f, symbol, c, face_id, signal_p)
      Lisp_Object symbol;
      int c;
      int face_id;
+     int signal_p;
 {
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
@@ -6328,6 +6383,12 @@ better_font_p (values, font1, font2, compare_pt_p, avgwidth)
 {
   int i;
 
+  /* Any font is better than no font.  */
+  if (! font1)
+    return 0;
+  if (! font2)
+    return 1;
+
   for (i = 0; i < DIM (font_sort_order); ++i)
     {
       int xlfd_idx = font_sort_order[i];
@@ -6572,29 +6633,19 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
   if (needs_overstrike)
     *needs_overstrike = 0;
 
-  /* Start with the first non-scalable font in the list.  */
-  for (i = 0; i < nfonts; ++i)
-    if (!font_scalable_p (fonts + i))
-      break;
+  best = NULL;
 
   /* Find the best match among the non-scalable fonts.  */
-  if (i < nfonts)
-    {
-      best = fonts + i;
-
-      for (i = 1; i < nfonts; ++i)
-       if (!font_scalable_p (fonts + i)
-           && better_font_p (specified, fonts + i, best, 1, avgwidth))
-         {
-           best = fonts + i;
+  for (i = 0; i < nfonts; ++i)
+    if (!font_scalable_p (fonts + i)
+       && better_font_p (specified, fonts + i, best, 1, avgwidth))
+      {
+       best = fonts + i;
 
-           exact_p = exact_face_match_p (specified, best, avgwidth);
-           if (exact_p)
-             break;
-         }
-    }
-  else
-    best = NULL;
+       exact_p = exact_face_match_p (specified, best, avgwidth);
+       if (exact_p)
+         break;
+      }
 
   /* Unless we found an exact match among non-scalable fonts, see if
      we can find a better match among scalable fonts.  */
@@ -6618,8 +6669,7 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
       for (i = 0; i < nfonts; ++i)
        if (font_scalable_p (fonts + i))
          {
-           if (best == NULL
-               || better_font_p (specified, fonts + i, best, 0, 0)
+           if (better_font_p (specified, fonts + i, best, 0, 0)
                || (!non_scalable_has_exact_height_p
                    && !better_font_p (specified, best, fonts + i, 0, 0)))
              {
@@ -6627,23 +6677,27 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
                best = fonts + i;
              }
          }
+    }
 
-      if (needs_overstrike)
-       {
-         enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
-         enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+  /* We should have found SOME font.  */
+  if (best == NULL)
+    abort ();
 
-         if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
-           {
-             /* We want a bold font, but didn't get one; try to use
-                overstriking instead to simulate bold-face.  However,
-                don't overstrike an already-bold fontn unless the
-                desired weight grossly exceeds the available weight.  */
-             if (got_weight > XLFD_WEIGHT_MEDIUM)
-               *needs_overstrike = (got_weight - want_weight) > 2;
-             else
-               *needs_overstrike = 1;
-           }
+  if (! exact_p && needs_overstrike)
+    {
+      enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
+      enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+
+      if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
+       {
+         /* We want a bold font, but didn't get one; try to use
+            overstriking instead to simulate bold-face.  However,
+            don't overstrike an already-bold fontn unless the
+            desired weight grossly exceeds the available weight.  */
+         if (got_weight > XLFD_WEIGHT_MEDIUM)
+           *needs_overstrike = (got_weight - want_weight) > 2;
+         else
+           *needs_overstrike = 1;
        }
     }
 
@@ -6744,20 +6798,22 @@ try_font_list (f, attrs, family, registry, fonts, prefer_face_family)
 
 #ifdef MAC_OS
   if (nfonts == 0 && STRINGP (try_family) && STRINGP (registry))
-    if (xstricmp (SDATA (registry), "mac-roman") == 0)
-      /* When realizing the default face and a font spec does not
-        matched exactly, Emacs looks for ones with the same registry
-        as the default font.  On the Mac, this is mac-roman, which
-        does not work if the family is -etl-fixed, e.g.  The
-        following widens the choices and fixes that problem.  */
-      nfonts = try_alternative_families (f, try_family, Qnil, fonts);
-    else if (SBYTES (try_family) > 0
-            && SREF (try_family, SBYTES (try_family) - 1) != '*')
-      /* Some Central European/Cyrillic font family names have the
-        Roman counterpart name as their prefix.  */
-      nfonts = try_alternative_families (f, concat2 (try_family,
-                                                    build_string ("*")),
-                                        registry, fonts);
+    {
+      if (xstricmp (SDATA (registry), "mac-roman") == 0)
+       /* When realizing the default face and a font spec does not
+          matched exactly, Emacs looks for ones with the same registry
+          as the default font.  On the Mac, this is mac-roman, which
+          does not work if the family is -etl-fixed, e.g.  The
+          following widens the choices and fixes that problem.  */
+       nfonts = try_alternative_families (f, try_family, Qnil, fonts);
+      else if (SBYTES (try_family) > 0
+              && SREF (try_family, SBYTES (try_family) - 1) != '*')
+       /* Some Central European/Cyrillic font family names have the
+          Roman counterpart name as their prefix.  */
+       nfonts = try_alternative_families (f, concat2 (try_family,
+                                                      build_string ("*")),
+                                          registry, fonts);
+    }
 #endif
 
   if (EQ (try_family, family))
@@ -7015,6 +7071,16 @@ realize_default_face (f)
   check_lface (lface);
   bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
   face = realize_face (c, attrs, 0, NULL, DEFAULT_FACE_ID);
+
+#ifdef HAVE_WINDOW_SYSTEM
+#ifdef HAVE_X_WINDOWS
+  if (face->font != FRAME_FONT (f))
+    /* As the font specified for the frame was not acceptable as a
+       font for the default face (perhaps because auto-scaled fonts
+       are rejected), we must adjust the frame font.  */
+    x_set_font (f, build_string (face->font_name), Qnil);
+#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
   return 1;
 }
 
@@ -7997,6 +8063,8 @@ syms_of_xfaces ()
   staticpro (&Qforeground_color);
   Qunspecified = intern ("unspecified");
   staticpro (&Qunspecified);
+  Qignore_defface = intern (":ignore-defface");
+  staticpro (&Qignore_defface);
 
   Qface_alias = intern ("face-alias");
   staticpro (&Qface_alias);