changeset 4426:515b91f904c1

Fix specifier inheritance behavior This patch ensures that no fallback is used if so requested, when the specifier instantiation process involves inheritance (for instance, a face [property] inheriting from another face [property]).
author Didier Verna <didier@xemacs.org>
date Tue, 26 Feb 2008 18:02:34 +0100
parents bfb8a26de3cb
children cff4ad0ab682
files src/ChangeLog src/glyphs.c src/objects.c src/specifier.c
diffstat 4 files changed, 138 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Feb 23 14:32:19 2008 +0100
+++ b/src/ChangeLog	Tue Feb 26 18:02:34 2008 +0100
@@ -1,6 +1,20 @@
+2008-02-26  Didier Verna  <didier@xemacs.org>
+
+	* specifier.c (CHECK_INSTANCE_ENTRY): See below.
+	* specifier.c (specifier_instance_1): Propagate the no_fallback
+	flag to ...
+	* specifier.c (specifier_instance_from_inst_list): ... here, and
+	in turn propagate it to the <specifier>_instantiate methods.
+	* glyphs.c (image_instantiate): Handle the no_fallback flag.
+	* objects.c (color_instantiate): Ditto.
+	* objects.c (font_instantiate): Ditto.
+	* objects.c (face_boolean_instantiate): Ditto.
+	* specifier.c (specifier_matching_foo_from_inst_list): Update call
+	to specifier_instance_from_inst_list accordingly.
+
 2008-02-11  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* search.c (search_buffer): 
+	* search.c (search_buffer):
 	In the event that a character is not representable in the buffer,
 	fail immediately. Prevents an assertion failure in the code to
 	deal with whether Boyer-Moore search can be used for such
@@ -21,16 +35,16 @@
 
 2008-01-30  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* search.c (debug-xemacs-searches): 
+	* search.c (debug-xemacs-searches):
 	New variable, available on debug builds. Used in
-	tests/automated/case-tests.el. 
+	tests/automated/case-tests.el.
 	(search_buffer): Only store the charset_base for characters with
 	translations. Correct some comments, correct some checks. If
-	debug_xemacs_searches is non-zero, record which search was used. 
+	debug_xemacs_searches is non-zero, record which search was used.
 	(boyer_moore): Remove an assertion that was incorrect. Remove its
 	documentation. Correct an assertion dealing with equivalence
 	tables; we may end up looking through the equivalence table if a
-	non-ASCII non-case character was searched for. 
+	non-ASCII non-case character was searched for.
 
 2008-01-25  Michael Sperber  <mike@xemacs.org>
 
@@ -43,13 +57,13 @@
 
 2008-01-21  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* elhash.c (Fputhash): Document the return value. 
-	(Fclrhash): Ditto. 
+	* elhash.c (Fputhash): Document the return value.
+	(Fclrhash): Ditto.
 
 2007-12-26  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* casetab.c:
-	Extend and correct some case table documentation. 
+	Extend and correct some case table documentation.
 	* search.c (search_buffer):
 	Correct a bug where only the first entry for a character in the
 	case equivalence table was examined in determining if the
@@ -64,7 +78,7 @@
 	* search.c (boyer_moore):
 	Assert that we haven't been passed a string with varying
 	characters sets or rows within character sets. That's what
-	simple_search is for. 
+	simple_search is for.
 
 	In the very rare event that a character in the search string has a
 	canonical case mapping that is not in the same character set and
@@ -74,14 +88,14 @@
 
 	Do not search for any character case mappings that cannot possibly
 	occur in the buffer, given the buffer metadata about its
-	contents. 
+	contents.
 
 2008-01-19  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* dired.c (Ffile_attributes): If bignums are available, use them
 	for the file size when necessary. If they are not, be clearer
 	about the check for whether the file size can fit in a Lisp
-	integer. 
+	integer.
 
 2008-01-18  Jerry James  <james@xemacs.org>
 
@@ -99,30 +113,30 @@
 
 	* print.c (prin1_to_string): New.
 	The guts of Fprin1_to_string, without resetting
-	Vprint_gensym_alist. 
-	(Fprin1_to_string): 
+	Vprint_gensym_alist.
+	(Fprin1_to_string):
 	Call prin1_to_string, wrapped with RESET_PRINT_GENSYM calls.
-	* doprnt.c (emacs_doprnt_1): 
+	* doprnt.c (emacs_doprnt_1):
 	Call prin1_to_string, not Fprin1_to_string (dos veces). Avoids an
-	inappropriate reset of print-gensym-alist. 
+	inappropriate reset of print-gensym-alist.
 
 2008-01-12  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* rangetab.c (Fmap_range_table): 
+	* rangetab.c (Fmap_range_table):
 	Clarify docstring. (If FUNCTION doesn't touch any range-table
 	entry, things will also be correct.)
 
 2008-01-09  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* config.h.in: 
+	* config.h.in:
 	Check that __STDC_VERSION__ is defined before examining its
-	value. Eliminates a Cygwin warning. 
+	value. Eliminates a Cygwin warning.
 
 2008-01-08  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* text.h (MAX_XETCHAR_SIZE): Remove, eliminating a redefinition
 	warning on Win32.
-	* dumper.c (pdump_load): 
+	* dumper.c (pdump_load):
 	Don't use PATH_MAX_EXTERNAL, instead allocate enough for the path
 	+ DUMP_SLACK (space for .dmp and version information), already
 	used on Win32 and #defined to be 100.
@@ -138,7 +152,7 @@
 2008-01-03  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* fileio.c (Fmake_temp_name): Correct the comment to cross
-	reference to make-temp-file, and not to this function. 
+	reference to make-temp-file, and not to this function.
 
 2008-01-03  Stephen J. Turnbull  <stephen@xemacs.org>
 
@@ -146,8 +160,8 @@
 
 2008-01-02  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* emacs.c (main_1): 
-	Call the new vars_of_console_gtk function. 
+	* emacs.c (main_1):
+	Call the new vars_of_console_gtk function.
 	* console-gtk.c (vars_of_console_gtk): New.
 	* console-gtk.c (gtk_perhaps_init_unseen_key_defaults):
 	Correct the initialisation of the hash table, on the model of the
@@ -157,7 +171,7 @@
 
 	* doc.c (Fbuilt_in_symbol_file):
 	Don't check is fun zero in the condition, check that it's not
-	nil. Fixes the union build; thank you Stephen. 
+	nil. Fixes the union build; thank you Stephen.
 
 2008-01-02  Mike Sperber  <mike@xemacs.org>
 
@@ -176,31 +190,31 @@
 
 2007-12-24  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* event-xlike-inc.c (x_keysym_to_character): 
+	* event-xlike-inc.c (x_keysym_to_character):
 	* event-xlike-inc.c (gtk_keysym_to_character):
 	Unify the typed character if possible, following the current value
-	for the unicode precedence list. 
+	for the unicode precedence list.
 
 2007-12-24  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* symbols.c (Fintern_soft): 
+	* symbols.c (Fintern_soft):
 	Provide a new optional third argument, DEFAULT, for those who want
 	to check if "nil" is a symbol or not. (More realistically, general
 	code that may get handed "nil" should probably use this argument.)
 
 2007-12-23  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* objects-tty.c (tty_find_charset_font): 
+	* objects-tty.c (tty_find_charset_font):
 	* objects-msw.c (mswindows_font_spec_matches_charset_stage_2):
 	* objects-msw.c (mswindows_font_spec_matches_charset_stage_1):
-	* objects-xlike-inc.c (x_font_spec_matches_charset): 
+	* objects-xlike-inc.c (x_font_spec_matches_charset):
 	* objects-xlike-inc.c (gtk_font_spec_matches_charset):
 	If the charset is not specified when calling the
 	font_spec_matches_charset device method, its value is Qnil, not
 	Qunbound. See
 	http://mid.gmane.org/E1EfbmW-00029r-5G@iwi191.iwi.uni-sb.de and
 	Ben Wing's patch of
-	http://mid.gmane.org/439FA06B.3090007@xemacs.org. 
+	http://mid.gmane.org/439FA06B.3090007@xemacs.org.
 
 2007-12-22  Aidan Kehoe  <kehoea@parhasard.net>
 
@@ -212,7 +226,7 @@
 	that's a great idea.
 	* database.c (print_database):
 	Give the coding system used for text conversion when printing a
-	database object. 
+	database object.
 
 2007-12-20  Jerry James  <james@xemacs.org>
 
@@ -228,11 +242,11 @@
 
 	* symbols.c (Fspecial_form_p):
 	Following commentary from Jerry James, don't error if not passed a
-	subr. 
+	subr.
 
 	Flesh out the docstring; give details of what a subr is, what a
 	special form is, and why one should probably not write special
-	forms oneself. 
+	forms oneself.
 
 2007-12-18  Aidan Kehoe  <kehoea@parhasard.net>
 
@@ -246,9 +260,9 @@
 	Add support for formatted printing of both longs and bignums as
 	base 2.
 	* editfns.c (Fformat):
-	Document the new %b escape for #'format. 
-	* lisp.h:
-	Make ulong_to_bit_string available beside long_to_string. 
+	Document the new %b escape for #'format.
+	* lisp.h:
+	Make ulong_to_bit_string available beside long_to_string.
 	* lread.c:
 	Fix a bug where the integer base was being ignored in certain
 	contexts; thank you Sebastian Freundt. This is necessary for
@@ -256,18 +270,18 @@
 	#'bit-vector-to-integer, just added to subr.el
 	* print.c (ulong_to_bit_string): New.
 	Analagous to long_to_string, but used all the time when %b is
-	encountered, since we can't pass that to sprintf. 	
+	encountered, since we can't pass that to sprintf.
 
 2007-12-12  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* config.h.in:
-	Make the results of the checks for 
+	Make the results of the checks for
 	FcConfigGetRescanInterval, FcConfigSetRescanInterval
 	available.
 	* font-mgr.h:
 	If FcConfigSetRescanInterval and FcConfigGetRescanInterval are not
 	available as functions, #define them to map to their old
-	misspelled names. 	
+	misspelled names.
 	* font-mgr.c (Ffc_config_get_rescan_interval):
 	* font-mgr.c (Ffc_config_set_rescan_interval):
 	Use the correct spelling in
@@ -275,7 +289,7 @@
 
 2007-12-11  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* glyphs-eimage.c: 
+	* glyphs-eimage.c:
 	Merge Ron Isaacson's patch of
 	3ggprxj7ifh.wl_Ron.Isaacson@morganstanley.com , originally from
 	Gennady Khokhorin. Prevents library incompatibilities on Win32.
@@ -314,7 +328,7 @@
 	coding systems) and make_coding_system_1 (which has to).
 	* file-coding.c (Ffind_coding_system):
 	Move the implementation to find_coding_system; call that function
-	with a do_autoloads argument of 1. 
+	with a do_autoloads argument of 1.
 	* file-coding.c (Fautoload_coding_system):
 	New.
 	* file-coding.c (add_coding_system_to_list_mapper):
@@ -331,21 +345,21 @@
 	system as its argument.
 
 	This is also tied in with the POSIX locale infrastructure by means
-	of posix-charset-to-coding-system-hash. 
+	of posix-charset-to-coding-system-hash.
 
 2007-11-29  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* mule-ccl.c (ccl_driver):
-	Take out a static variable I was using for debugging. 
+	Take out a static variable I was using for debugging.
 
 2007-11-26  Aidan Kehoe  <kehoea@parhasard.net>
 
-	* doprnt.c: 
+	* doprnt.c:
 	Default to a buffer size of 350 for the sprintf call, but increase
 	it if the precision and minwidth indicate that it should be
 	bigger. Issue reported by Hans de Graaff; bug originally fixed by
 	Sebastian Freundt in SXEmacs following the change I merged on
-	2006-11-28. Forks have their disadvantages. 
+	2006-11-28. Forks have their disadvantages.
 
 2007-11-11  Mats Lidell  <matsl@xemacs.org>
 
@@ -367,18 +381,18 @@
 
 	* lread.c (read_unicode_escape):
 	Correct the range check for Unicode characters specified with
-	source-level escapes. 
+	source-level escapes.
 	* unicode.c:
 	* unicode.c (unicode_to_ichar):
 	* unicode.c (coding_system_type_create_unicode):
 	Correct the dump behaviour for just-in-time Unicode code
 	points. Update the docstring for #'unicode-to-char to indicate
-	that code points will run out above around 400,000 in a session. 
+	that code points will run out above around 400,000 in a session.
 
 2007-11-14  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* editfns.c (vars_of_editfns):
-	Correct the docstring of user-full-name. 
+	Correct the docstring of user-full-name.
 	* fileio.c:
 	* fileio.c (Fmake_temp_name):
 	Document that make-temp-file is available and the best approach to
@@ -387,10 +401,10 @@
 	Take a new arg, MUSTBENEW, to error if the file to be written
 	already exists.
 	* fileio.c (auto_save_1):
-	Update a call to Fwrite_region_internal to pass the new argument. 
+	Update a call to Fwrite_region_internal to pass the new argument.
 	* fileio.c (syms_of_fileio):
 	Provide 'excl as a symbol, for the calls to
-	write-region-internal. 
+	write-region-internal.
 
 2007-11-05  Didier Verna  <didier@xemacs.org>
 
--- a/src/glyphs.c	Sat Feb 23 14:32:19 2008 +0100
+++ b/src/glyphs.c	Tue Feb 26 18:02:34 2008 +0100
@@ -3259,7 +3259,7 @@
 static Lisp_Object
 image_instantiate (Lisp_Object specifier, Lisp_Object UNUSED (matchspec),
 		   Lisp_Object domain, Lisp_Object instantiator,
-		   Lisp_Object depth)
+		   Lisp_Object depth, int no_fallback)
 {
   Lisp_Object glyph = IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier));
   int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier);
@@ -3298,7 +3298,7 @@
       assert (XVECTOR_LENGTH (instantiator) == 3);
       return (FACE_PROPERTY_INSTANCE
 	      (Fget_face (XVECTOR_DATA (instantiator)[2]),
-	       Qbackground_pixmap, domain, 1, depth));
+	       Qbackground_pixmap, domain, no_fallback, depth));
     }
   else
     {
--- a/src/objects.c	Sat Feb 23 14:32:19 2008 +0100
+++ b/src/objects.c	Tue Feb 26 18:02:34 2008 +0100
@@ -103,7 +103,7 @@
   Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj);
   if (print_readably)
     printing_unreadable_object ("#<color-instance 0x%x>",
-           c->header.uid);
+	   c->header.uid);
   write_fmt_string_lisp (printcharfun, "#<color-instance %s", 1, c->name);
   write_fmt_string_lisp (printcharfun, " on %s", 1, c->device);
   if (!NILP (c->device)) /* Vthe_null_color_instance */
@@ -153,7 +153,7 @@
 			       0, /*dumpable-flag*/
 			       mark_color_instance, print_color_instance,
 			       finalize_color_instance, color_instance_equal,
-			       color_instance_hash, 
+			       color_instance_hash,
 			       color_instance_description,
 			       Lisp_Color_Instance);
 
@@ -295,7 +295,7 @@
   { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, truename)},
   { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, device)},
   { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, charset)},
-  { XD_UNION, offsetof (Lisp_Font_Instance, data), 
+  { XD_UNION, offsetof (Lisp_Font_Instance, data),
     XD_INDIRECT (0, 0), { &font_instance_data_description } },
   { XD_END }
 };
@@ -596,7 +596,7 @@
 static Lisp_Object
 color_instantiate (Lisp_Object specifier, Lisp_Object UNUSED (matchspec),
 		   Lisp_Object domain, Lisp_Object instantiator,
-		   Lisp_Object depth)
+		   Lisp_Object depth, int no_fallback)
 {
   /* When called, we're inside of call_with_suspended_errors(),
      so we can freely error. */
@@ -606,10 +606,10 @@
   if (COLOR_INSTANCEP (instantiator))
     {
       /* If we are on the same device then we're done.  Otherwise change
-         the instantiator to the name used to generate the pixel and let the
-         STRINGP case deal with it. */
+	 the instantiator to the name used to generate the pixel and let the
+	 STRINGP case deal with it. */
       if (NILP (device) /* Vthe_null_color_instance */
-          || EQ (device, XCOLOR_INSTANCE (instantiator)->device))
+	  || EQ (device, XCOLOR_INSTANCE (instantiator)->device))
 	return instantiator;
       else
 	instantiator = Fcolor_instance_name (instantiator);
@@ -647,13 +647,15 @@
 				 instantiator);
 	  return (FACE_PROPERTY_INSTANCE_1
 		  (Fget_face (XVECTOR_DATA (instantiator)[0]),
-		   COLOR_SPECIFIER_FACE_PROPERTY (XCOLOR_SPECIFIER (specifier)),
-		   domain, ERROR_ME, 0, depth));
+		   COLOR_SPECIFIER_FACE_PROPERTY
+		   (XCOLOR_SPECIFIER (specifier)),
+		   domain, ERROR_ME, no_fallback, depth));
 
 	case 2:
 	  return (FACE_PROPERTY_INSTANCE_1
 		  (Fget_face (XVECTOR_DATA (instantiator)[0]),
-		   XVECTOR_DATA (instantiator)[1], domain, ERROR_ME, 0, depth));
+		   XVECTOR_DATA (instantiator)[1], domain, ERROR_ME,
+		   no_fallback, depth));
 
 	default:
 	  ABORT ();
@@ -830,11 +832,11 @@
       hash_table = Fgethash (charset, d->charset_font_cache_stage_1,
 			     Qunbound);
       if (!UNBOUNDP (hash_table))
-        Fclrhash (hash_table);
+	Fclrhash (hash_table);
       hash_table = Fgethash (charset, d->charset_font_cache_stage_2,
 			     Qunbound);
       if (!UNBOUNDP (hash_table))
-        Fclrhash (hash_table);
+	Fclrhash (hash_table);
     }
 }
 
@@ -845,7 +847,7 @@
 font_instantiate (Lisp_Object UNUSED (specifier),
 		  Lisp_Object USED_IF_MULE (matchspec),
 		  Lisp_Object domain, Lisp_Object instantiator,
-		  Lisp_Object depth)
+		  Lisp_Object depth, int no_fallback)
 {
   /* When called, we're inside of call_with_suspended_errors(),
      so we can freely error. */
@@ -877,7 +879,7 @@
   if (FONT_INSTANCEP (instantiator))
     {
       if (NILP (device)
-          || EQ (device, XFONT_INSTANCE (instantiator)->device))
+	  || EQ (device, XFONT_INSTANCE (instantiator)->device))
 	{
 #ifdef MULE
 	  if (font_spec_matches_charset (d, charset, 0,
@@ -895,7 +897,7 @@
 #ifdef MULE
       /* #### rename these caches. */
       Lisp_Object cache = stage ? d->charset_font_cache_stage_2 :
-        d->charset_font_cache_stage_1;
+	d->charset_font_cache_stage_1;
 #else
       Lisp_Object cache = d->font_instance_cache;
 #endif
@@ -926,9 +928,9 @@
 	    {
 	      /* make sure we cache the failures, too. */
 	      matching_font =
-                DEVMETH_OR_GIVEN (d, find_charset_font,
-                                  (device, instantiator, charset, stage),
-                                  instantiator);
+		DEVMETH_OR_GIVEN (d, find_charset_font,
+				  (device, instantiator, charset, stage),
+				  instantiator);
 	      Fputhash (instantiator, matching_font, hash_table);
 	    }
 	  if (NILP (matching_font))
@@ -956,13 +958,13 @@
 
       match_inst = face_property_matching_instance
 	(Fget_face (XVECTOR_DATA (instantiator)[0]), Qfont,
-	 charset, domain, ERROR_ME, 0, depth, initial);
+	 charset, domain, ERROR_ME, no_fallback, depth, initial);
 
-      if (UNBOUNDP(match_inst)) 
+      if (UNBOUNDP(match_inst))
 	{
 	  match_inst = face_property_matching_instance
 	    (Fget_face (XVECTOR_DATA (instantiator)[0]), Qfont,
-	     charset, domain, ERROR_ME, 0, depth, final);
+	     charset, domain, ERROR_ME, no_fallback, depth, final);
 	}
 
       return match_inst;
@@ -1067,7 +1069,7 @@
 face_boolean_instantiate (Lisp_Object specifier,
 			  Lisp_Object UNUSED (matchspec),
 			  Lisp_Object domain, Lisp_Object instantiator,
-			  Lisp_Object depth)
+			  Lisp_Object depth, int no_fallback)
 {
   /* When called, we're inside of call_with_suspended_errors(),
      so we can freely error. */
@@ -1094,7 +1096,7 @@
 
       retval = (FACE_PROPERTY_INSTANCE_1
 		(Fget_face (XVECTOR_DATA (instantiator)[0]),
-		 prop, domain, ERROR_ME, 0, depth));
+		 prop, domain, ERROR_ME, no_fallback, depth));
 
       if (instantiator_len == 3 && !NILP (XVECTOR_DATA (instantiator)[2]))
 	retval = NILP (retval) ? Qt : Qnil;
--- a/src/specifier.c	Sat Feb 23 14:32:19 2008 +0100
+++ b/src/specifier.c	Tue Feb 26 18:02:34 2008 +0100
@@ -247,7 +247,7 @@
 	{
 	  Lisp_Specifier* sp = XSPECIFIER (rest);
 	  /* A bit of assertion that we're removing both parts of the
-             magic one altogether */
+	     magic one altogether */
 	  assert (!MAGIC_SPECIFIER_P(sp)
 		  || (BODILY_SPECIFIER_P(sp) && marked_p (sp->fallback))
 		  || (GHOST_SPECIFIER_P(sp) && marked_p (sp->magic_parent)));
@@ -386,10 +386,10 @@
 };
 
 #ifdef NEW_GC
-DEFINE_LRECORD_IMPLEMENTATION ("specifier-caching", 
+DEFINE_LRECORD_IMPLEMENTATION ("specifier-caching",
 			       specifier_caching,
 			       1, /*dumpable-flag*/
-                               0, 0, 0, 0, 0, 
+			       0, 0, 0, 0, 0,
 			       specifier_caching_description_1,
 			       struct specifier_caching);
 #else /* not NEW_GC */
@@ -695,7 +695,7 @@
     ? Qt : Qnil;
 }
 
-DEFUN ("valid-specifier-locale-type-p", Fvalid_specifier_locale_type_p, 1, 
+DEFUN ("valid-specifier-locale-type-p", Fvalid_specifier_locale_type_p, 1,
        1, 0, /*
 Given a specifier LOCALE-TYPE, return non-nil if it is valid.
 Valid locale types are `global', `device', `frame', `window', and `buffer'.
@@ -983,8 +983,8 @@
 
 static int
 charset_matches_specifier_tag_set_p (Lisp_Object charset,
-				     Lisp_Object tag_set, 
-				     enum font_specifier_matchspec_stages 
+				     Lisp_Object tag_set,
+				     enum font_specifier_matchspec_stages
 				     stage)
 {
   Lisp_Object rest;
@@ -998,20 +998,20 @@
       Lisp_Object assoc;
 
       /* In the event that, during the creation of a charset, no specifier
-         tags exist for which CHARSET-PREDICATE has been specified, then
-         that charset's entry in Vcharset_tag_lists will be nil, and this
-         charset shouldn't match. */
-
-      if (NILP (XVECTOR_DATA(Vcharset_tag_lists)[XCHARSET_LEADING_BYTE(charset) 
-                                                 - MIN_LEADING_BYTE]))
-        {
-          return 0;
-        }
+	 tags exist for which CHARSET-PREDICATE has been specified, then
+	 that charset's entry in Vcharset_tag_lists will be nil, and this
+	 charset shouldn't match. */
+
+      if (NILP (XVECTOR_DATA(Vcharset_tag_lists)[XCHARSET_LEADING_BYTE(charset)
+						 - MIN_LEADING_BYTE]))
+	{
+	  return 0;
+	}
 
       /* Now, find out what the pre-calculated value is. */
       assoc = assq_no_quit(tag,
 			   XVECTOR_DATA(Vcharset_tag_lists)
-			   [XCHARSET_LEADING_BYTE(charset) 
+			   [XCHARSET_LEADING_BYTE(charset)
 			    - MIN_LEADING_BYTE]);
 
       if (!(NILP(assoc)) && !(NILP(XCDR(assoc))))
@@ -1060,18 +1060,18 @@
 }
 
 Lisp_Object
-define_specifier_tag(Lisp_Object tag, Lisp_Object device_predicate, 
+define_specifier_tag(Lisp_Object tag, Lisp_Object device_predicate,
 		     Lisp_Object charset_predicate)
 {
-  Lisp_Object assoc = assq_no_quit (tag, Vuser_defined_tags), 
+  Lisp_Object assoc = assq_no_quit (tag, Vuser_defined_tags),
     concons, devcons, charpres = Qnil;
   int recompute_devices = 0, recompute_charsets = 0, i, max_args = -1;
 
   if (NILP (assoc))
     {
       recompute_devices = recompute_charsets = 1;
-      Vuser_defined_tags = Fcons (list3 (tag, device_predicate, 
-					 charset_predicate), 
+      Vuser_defined_tags = Fcons (list3 (tag, device_predicate,
+					 charset_predicate),
 				  Vuser_defined_tags);
       DEVICE_LOOP_NO_BREAK (devcons, concons)
 	{
@@ -1105,7 +1105,7 @@
 	  invalid_argument
 	    ("Charset predicate must be able to take an argument", tag);
 	}
-      
+
       /* If there exists a charset_predicate for the tag currently (even if
 	 the new charset_predicate is nil), or if we're adding one, we need
 	 to recompute.  This contrasts with the device predicates, where we
@@ -1139,7 +1139,7 @@
 	}
     }
 
-  if (recompute_charsets) 
+  if (recompute_charsets)
     {
       if (NILP(charset_predicate))
 	{
@@ -1158,8 +1158,8 @@
 
 	  if (!NILP(charset_predicate))
 	    {
-	      struct gcpro gcpro1; 
-	      charpres = make_vector(impossible, Qnil); 
+	      struct gcpro gcpro1;
+	      charpres = make_vector(impossible, Qnil);
 	      GCPRO1 (charpres);
 
 	      /* If you want to extend the number of stages available, here
@@ -1212,8 +1212,8 @@
 	    }
 	  else
 	    {
-	      XVECTOR_DATA(Vcharset_tag_lists)[i] 
-		= Fcons(Fcons(tag, charpres), 
+	      XVECTOR_DATA(Vcharset_tag_lists)[i]
+		= Fcons(Fcons(tag, charpres),
 			XVECTOR_DATA (Vcharset_tag_lists)[i]);
 	    }
 	}
@@ -1310,15 +1310,15 @@
       assert(3 == list_len);
 
       device_predicate = XCADR(XCAR (rest));
-					   
+
       if (NILP (device_predicate))
 	{
-	  XCDR (XCAR (rest2)) = Qt; 
+	  XCDR (XCAR (rest2)) = Qt;
 	}
       else
 	{
-	  device_predicate = !NILP (call_critical_lisp_code 
-				    (d, device_predicate, device)) 
+	  device_predicate = !NILP (call_critical_lisp_code
+				    (d, device_predicate, device))
 	    ? Qt : Qnil;
 	  XCDR (XCAR (rest2)) = device_predicate;
 	}
@@ -1329,7 +1329,7 @@
 setup_charset_initial_specifier_tags (Lisp_Object charset)
 {
   Lisp_Object rest, charset_predicate, tag, new_value;
-  Lisp_Object charset_tag_list = Qnil; 
+  Lisp_Object charset_tag_list = Qnil;
 
   LIST_LOOP (rest, Vuser_defined_tags)
     {
@@ -1362,7 +1362,7 @@
 									\
       } while (0)
 
-      SETUP_CHARSET_TAGS_FROB (initial); 
+      SETUP_CHARSET_TAGS_FROB (initial);
       SETUP_CHARSET_TAGS_FROB (final);
       /* More later?  */
 
@@ -2325,10 +2325,10 @@
 where
   LOCALE := a window, a buffer, a frame, a device, or `global'
   TAG-SET := an unordered list of zero or more TAGS, each of which
-             is a symbol
+	     is a symbol
   TAG := a device class (see `valid-device-class-p'), a device type
-         (see `valid-console-type-p'), or a tag defined with
-         `define-specifier-tag'
+	 (see `valid-console-type-p'), or a tag defined with
+	 `define-specifier-tag'
   INSTANTIATOR := format determined by the type of specifier
 
 The pair (TAG-SET . INSTANTIATOR) is called an `inst-pair'.
@@ -2804,7 +2804,8 @@
 				   Lisp_Object inst_list,
 				   Error_Behavior errb, int no_quit,
 				   Lisp_Object depth,
-				   Lisp_Object *instantiator)
+				   Lisp_Object *instantiator,
+				   int no_fallback)
 {
   /* This function can GC */
   Lisp_Specifier *sp;
@@ -2866,7 +2867,7 @@
 
       if (!device_matches_specifier_tag_set_p (device, tag_set))
 	{
-	  continue; 
+	  continue;
 	}
 
       val = XCDR (tagged_inst);
@@ -2883,7 +2884,7 @@
 	val = call_with_suspended_errors
 	  ((lisp_fn_t) RAW_SPECMETH (sp, instantiate),
 	   Qunbound, Qspecifier, errb, 5, specifier,
-	   matchspec, domain, val, depth);
+	   matchspec, domain, val, depth, no_fallback);
 
       if (!UNBOUNDP (val))
 	{
@@ -2922,7 +2923,7 @@
 
       if (!device_matches_specifier_tag_set_p (device, tag_set))
 	{
-	  continue; 
+	  continue;
 	}
 
       val = XCDR (tagged_inst);
@@ -2932,7 +2933,7 @@
 	val = call_with_suspended_errors
 	  ((lisp_fn_t) RAW_SPECMETH (sp, instantiate),
 	   Qunbound, Qspecifier, errb, 5, specifier,
-	   matchspec, domain, val, depth);
+	   matchspec, domain, val, depth, no_fallback);
 
       if (!UNBOUNDP (val))
 	{
@@ -2963,7 +2964,7 @@
 	  specifier_instance_from_inst_list (specifier, matchspec,	\
 					     domain, *CIE_inst_list,	\
 					     errb, no_quit, depth,	\
-					     instantiator);		\
+					     instantiator, no_fallback); \
 	if (!UNBOUNDP (CIE_val))					\
 	  return CIE_val;						\
       }									\
@@ -3075,7 +3076,8 @@
   assert (CONSP (sp->fallback));
   return specifier_instance_from_inst_list (specifier, matchspec, domain,
 					    sp->fallback, errb, no_quit,
-					    depth, instantiator);
+					    depth, instantiator,
+					    no_fallback);
 }
 #undef CHECK_INSTANCE_ENTRY
 
@@ -3245,7 +3247,7 @@
    display table is not there. (Chartable specifiers are not yet
    implemented.)
 
--- For font specifiers, MATCHSPEC should be a cons (CHARSET . STAGE).  
+-- For font specifiers, MATCHSPEC should be a cons (CHARSET . STAGE).
    The defined stages are currently `initial' and `final'.  On X11, 'initial
    is used when the font matching process is looking for fonts that match
    the desired registries of the charset--see the `charset-registries'
@@ -3308,7 +3310,7 @@
   if (!NILP (built_up_list))
     val = specifier_instance_from_inst_list (specifier, matchspec, domain,
 					     built_up_list, ERROR_ME,
-					     0, Qzero, &instantiator);
+					     0, Qzero, &instantiator, 0);
   UNGCPRO;
   return UNBOUNDP (val) ? default_ : want_instantiator ? instantiator : val;
 
@@ -3329,7 +3331,7 @@
 						0);
 }
 
-DEFUN ("specifier-instantiator-from-inst-list", 
+DEFUN ("specifier-instantiator-from-inst-list",
        Fspecifier_instantiator_from_inst_list, 3, 4, 0, /*
 Attempt to convert an inst-list into an instance; return instantiator.
 This is identical to `specifier-instance-from-inst-list' but returns
@@ -3923,5 +3925,5 @@
   staticpro (&Vunlock_ghost_specifiers);
 
   Vcharset_tag_lists = make_vector(NUM_LEADING_BYTES, Qnil);
-  staticpro (&Vcharset_tag_lists); 
+  staticpro (&Vcharset_tag_lists);
 }