? bar.diff
? baz.diff
? foo.diff
? pango/a.out
? pango/test.c
Index: docs/pango_markup.sgml
===================================================================
RCS file: /cvs/gnome/pango/docs/pango_markup.sgml,v
retrieving revision 1.3
diff -u -p -u -r1.3 pango_markup.sgml
--- docs/pango_markup.sgml	11 Dec 2002 19:26:16 -0000	1.3
+++ docs/pango_markup.sgml	29 Feb 2004 20:00:19 -0000
@@ -135,6 +135,16 @@ subscript, positive for superscript.
 </para></listitem>
 </varlistentry>
 
+<varlistentry><term>fallback</term>
+<listitem><para>
+'true' or 'false' whether to enable fallback. If disabled, then characters
+will only be used from the closest matching font on the system. No fallback
+will be done to other fonts on the system that might contain the characters
+in the text.  Fallback is enabled by default. Most applications should not
+disable fallback.
+</para></listitem>
+</varlistentry>
+
 <varlistentry><term>lang</term>
 <listitem><para>
 A language code, indicating the text language
Index: docs/tmpl/text-attributes.sgml
===================================================================
RCS file: /cvs/gnome/pango/docs/tmpl/text-attributes.sgml,v
retrieving revision 1.26
diff -u -p -u -r1.26 text-attributes.sgml
--- docs/tmpl/text-attributes.sgml	25 Jun 2003 19:14:24 -0000	1.26
+++ docs/tmpl/text-attributes.sgml	29 Feb 2004 20:00:19 -0000
@@ -43,6 +43,7 @@ attribute is listed in parentheses after
 @PANGO_ATTR_RISE: baseline displacement (#PangoAttrInt)
 @PANGO_ATTR_SHAPE: shape (#PangoAttrShape)
 @PANGO_ATTR_SCALE: font size scale factor (#PangoAttrScale)
+@PANGO_ATTR_FALLBACK: whether fallback is enabled (#PangoAttrInt)
 
 <!-- ##### MACRO PANGO_TYPE_ATTR_TYPE ##### -->
 <para>
Index: pango/pango-attributes.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-attributes.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 pango-attributes.c
--- pango/pango-attributes.c	9 Feb 2004 14:55:11 -0000	1.39
+++ pango/pango-attributes.c	29 Feb 2004 20:00:20 -0000
@@ -643,6 +643,33 @@ pango_attr_scale_new (double scale_facto
   return pango_attr_float_new (&klass, scale_factor);
 }
 
+/**
+ * pango_attr_fallback_new:
+ * @enable_fallback: %TRUE if we should fall back on other fonts 
+ *                   for characters the active font is missing.
+ * 
+ * Create a new font fallback attribute.
+ *
+ * If fallback is disabled, characters will only be used from the
+ * closest matching font on the system. No fallback will be done to
+ * other fonts on the system that might contain the characters in the
+ * text.
+ * 
+ * Return value: the new #PangoAttribute.
+ **/
+PangoAttribute *
+pango_attr_fallback_new (gboolean enable_fallback)
+{
+  static const PangoAttrClass klass = {
+    PANGO_ATTR_FALLBACK,
+    pango_attr_int_copy,
+    pango_attr_int_destroy,
+    pango_attr_int_equal,
+  };
+
+  return pango_attr_int_new (&klass, (int)enable_fallback);
+}
+
 static PangoAttribute *
 pango_attr_shape_copy (const PangoAttribute *attr)
 {
Index: pango/pango-attributes.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-attributes.h,v
retrieving revision 1.20
diff -u -p -u -r1.20 pango-attributes.h
--- pango/pango-attributes.h	10 Dec 2002 23:45:26 -0000	1.20
+++ pango/pango-attributes.h	29 Feb 2004 20:00:20 -0000
@@ -80,7 +80,8 @@ typedef enum
   PANGO_ATTR_STRIKETHROUGH,	/* PangoAttrInt */
   PANGO_ATTR_RISE,		/* PangoAttrInt */
   PANGO_ATTR_SHAPE,		/* PangoAttrShape */
-  PANGO_ATTR_SCALE              /* PangoAttrFloat */
+  PANGO_ATTR_SCALE,             /* PangoAttrFloat */
+  PANGO_ATTR_FALLBACK,          /* PangoAttrInt */
 } PangoAttrType;
 
 typedef enum {
@@ -179,6 +180,7 @@ PangoAttribute *pango_attr_rise_new     
 PangoAttribute *pango_attr_shape_new         (const PangoRectangle       *ink_rect,
 					      const PangoRectangle       *logical_rect);
 PangoAttribute *pango_attr_scale_new         (double                      scale_factor);
+PangoAttribute *pango_attr_fallback_new      (gboolean                    enable_fallback);
 
 GType              pango_attr_list_get_type      (void) G_GNUC_CONST;
 PangoAttrList *    pango_attr_list_new           (void);
Index: pango/pango-context.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.c,v
retrieving revision 1.63
diff -u -p -u -r1.63 pango-context.c
--- pango/pango-context.c	27 Feb 2004 14:48:53 -0000	1.63
+++ pango/pango-context.c	29 Feb 2004 20:00:20 -0000
@@ -515,6 +515,7 @@ struct _ItemizeState
   
   PangoFontset *current_fonts;
   ShaperFontCache *cache;
+  PangoFont *base_font;
   
   GSList *exact_engines;
   GSList *fallback_engines;
@@ -639,6 +640,7 @@ itemize_state_init (ItemizeState      *s
   state->cache = NULL;
   state->exact_engines = NULL;
   state->fallback_engines = NULL;
+  state->base_font = NULL;
   
   state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED;
 }
@@ -813,6 +815,19 @@ get_shaper_and_font_foreach (PangoFontse
   return FALSE;
 }
 
+static PangoAttribute *
+find_attribute (GSList        *attr_list,
+                PangoAttrType  type)
+{
+  GSList *node;
+  
+  for (node = attr_list; node; node = node->next)
+    if (((PangoAttribute *) node->data)->klass->type == type)
+      return (PangoAttribute *) node->data;
+
+  return NULL;
+}
+
 static gboolean
 get_shaper_and_font (ItemizeState      *state,
 		     gunichar           wc,
@@ -820,8 +835,10 @@ get_shaper_and_font (ItemizeState      *
 		     PangoFont        **font)
 {
   GetShaperFontInfo info;
+  PangoAttribute *fallback = find_attribute (state->extra_attrs, PANGO_ATTR_FALLBACK);
+  gboolean enable_fallback = (fallback == NULL || ((PangoAttrInt *)fallback)->value);
 
-  if (shaper_font_cache_get (state->cache, wc, shape_engine, font))
+  if (enable_fallback && shaper_font_cache_get (state->cache, wc, shape_engine, font))
     return *shape_engine != NULL;
 
   if (!state->exact_engines && !state->fallback_engines)
@@ -834,7 +851,11 @@ get_shaper_and_font (ItemizeState      *
   info.font = NULL;
 
   info.engines = state->exact_engines;
-  pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
+  if (enable_fallback)
+    pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
+  else 
+    get_shaper_and_font_foreach (NULL, state->base_font, &info);
+
   if (info.shape_engine)
     {
       *shape_engine = info.shape_engine;
@@ -846,12 +867,16 @@ get_shaper_and_font (ItemizeState      *
     }
 
   info.engines = state->fallback_engines;
-  pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
+  if (enable_fallback)
+    pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info);
+  else 
+    get_shaper_and_font_foreach (NULL, state->base_font, &info);
 
   *shape_engine = info.shape_engine;
   *font = info.font;
 
-  shaper_font_cache_insert (state->cache, wc, *shape_engine, *font);
+  if (enable_fallback)
+    shaper_font_cache_insert (state->cache, wc, *shape_engine, *font);
       
   return *shape_engine != NULL;
 }
@@ -945,6 +970,17 @@ itemize_state_update_for_new_run (Itemiz
 							  state->derived_lang);
       state->cache = get_shaper_font_cache (state->current_fonts);
     }
+
+  if ((state->changed & FONT_CHANGED) && state->base_font)
+    {
+      g_object_unref (state->base_font);
+      state->base_font = NULL;
+    }
+
+  if (!state->base_font)
+    state->base_font = pango_font_map_load_font (state->context->font_map,
+                                                 state->context,
+                                                 state->font_desc);
 }
 
 static void
Index: pango/pango-markup.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-markup.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 pango-markup.c
--- pango/pango-markup.c	10 Feb 2004 19:36:52 -0000	1.18
+++ pango/pango-markup.c	29 Feb 2004 20:00:20 -0000
@@ -858,6 +858,7 @@ span_parse_func     (MarkupData         
   const char *strikethrough = NULL;
   const char *rise = NULL;
   const char *lang = NULL;
+  const char *fallback = NULL;
   
   g_markup_parse_context_get_position (context,
                                        &line_number, &char_number);
@@ -932,6 +933,11 @@ span_parse_func     (MarkupData         
           CHECK_DUPLICATE (lang);
           lang = values[i];
         }
+      else if (strcmp (names[i], "fallback") == 0)
+        {
+          CHECK_DUPLICATE (fallback);
+          fallback = values[i];
+        }
       else
         {
           g_set_error (error, G_MARKUP_ERROR,
@@ -1182,6 +1188,25 @@ span_parse_func     (MarkupData         
         }
     }
 
+  if (fallback)
+    {
+      if (strcmp (fallback, "true") == 0)
+        add_attribute (tag, pango_attr_fallback_new (TRUE));
+      else if (strcmp (fallback, "false") == 0)
+        add_attribute (tag, pango_attr_fallback_new (FALSE));
+      else
+        {
+          g_set_error (error,
+                       G_MARKUP_ERROR,
+                       G_MARKUP_ERROR_INVALID_CONTENT,
+                       _("'fallback' attribute on <span> tag "
+                         "line %d should have one of the values "
+                         "'true' or 'false': '%s' is not valid"),
+                       line_number, fallback);
+          goto error;
+        }
+    }
+
   if (rise)
     {
       char *end = NULL;
