Index: fonts.c
===================================================================
--- fonts.c	(revision 2353)
+++ fonts.c	(working copy)
@@ -31,6 +31,14 @@
 
 static const char bad_font_warning[] = "%s called with null font argument, expect ugly output";
 
+typedef struct  _PangoFontDescriptionDomain
+{
+  GQuark quark;
+  gpointer data;
+  GBoxedCopyFunc data_copy_func;
+  GBoxedFreeFunc data_free_func;
+} PangoFontDescriptionDomain;
+
 struct _PangoFontDescription
 {
   char *family_name;
@@ -44,8 +52,11 @@ struct _PangoFontDescription
   guint16 mask;
   guint static_family : 1;
   guint size_is_absolute : 1;
+  guint static_domain : 1;
 
   int size;
+
+  PangoFontDescriptionDomain *domain;
 };
 
 GType
@@ -74,8 +85,11 @@ static const PangoFontDescription pfd_de
   0,			/* mask */
   0,			/* static_family */
   FALSE,		/* size_is_absolute */
+  0,			/* static_domain */
 
   0,			/* size */
+
+  NULL			/* domain */
 };
 
 /**
@@ -476,6 +490,99 @@ pango_font_description_get_gravity (cons
   return desc->gravity;
 }
 
+static PangoFontDescriptionDomain *
+pango_font_description_domain_new (GQuark         quark,
+				   gpointer       data,
+				   GBoxedCopyFunc dcopyfunc,
+				   GBoxedFreeFunc dfreefunc)
+{
+  PangoFontDescriptionDomain *domain;
+
+  if (!quark)
+    return NULL;
+
+  if (data && dcopyfunc)
+    data = dcopyfunc (data);
+    
+  domain = g_slice_new (PangoFontDescriptionDomain);
+
+  domain->quark = quark;
+  domain->data = data;
+  domain->data_copy_func = dcopyfunc;
+  domain->data_free_func = dfreefunc;
+
+  return domain;
+}
+
+static PangoFontDescriptionDomain *
+pango_font_description_domain_copy (PangoFontDescriptionDomain *domain)
+{
+  if (G_LIKELY (!domain))
+    return NULL;
+
+  return pango_font_description_domain_new (domain->quark,
+					    domain->data,
+					    domain->data_copy_func,
+					    domain->data_free_func);
+}
+
+static void
+pango_font_description_domain_free (PangoFontDescriptionDomain *domain)
+{
+  if (G_LIKELY (!domain))
+    return;
+
+  if (domain->data && domain->data_free_func)
+    domain->data_free_func (domain->data);
+
+  g_slice_free (PangoFontDescriptionDomain, domain);
+}
+
+static gboolean
+pango_font_description_domain_equal (const PangoFontDescriptionDomain *domain1,
+				     const PangoFontDescriptionDomain *domain2)
+{
+  if (domain1 == NULL || domain2 == NULL)
+    return domain1 == domain2;
+
+  return domain1->quark == domain2->quark && domain1->data == domain2->data;
+}
+
+static guint
+pango_font_description_domain_hash (const PangoFontDescriptionDomain *domain)
+{
+  if (G_LIKELY (domain == NULL))
+    return 0;
+
+  return domain->quark ^ GPOINTER_TO_INT (domain->data);
+}
+
+void
+pango_font_description_set_domain (PangoFontDescription *desc,
+				   GQuark                quark,
+				   gpointer              data,
+				   GBoxedCopyFunc        dcopyfunc,
+				   GBoxedFreeFunc        dfreefunc)
+{
+  g_return_if_fail (desc != NULL);
+
+  pango_font_description_domain_free (desc->domain);
+  desc->domain = pango_font_description_domain_new (quark, data,
+						    dcopyfunc, dfreefunc);
+  desc->static_domain = FALSE;
+
+  desc->mask |= PANGO_FONT_MASK_DOMAIN;
+}
+
+GQuark
+pango_font_description_get_domain (const PangoFontDescription *desc,
+				   gpointer                   *data)
+{
+  g_return_val_if_fail (desc != NULL, 0);
+
+  return desc->domain ? desc->domain->quark : 0;
+}
+
 /**
  * pango_font_description_get_set_fields:
  * @desc: a #PangoFontDescription
@@ -517,6 +624,53 @@ pango_font_description_unset_fields (Pan
   desc->mask &= ~to_unset;
 }
 
+static void
+pango_font_description_merge_internal (PangoFontDescription       *desc,
+				       const PangoFontDescription *desc_to_merge,
+				       gboolean                    replace_existing,
+				       gboolean                    deep)
+{
+  PangoFontMask new_mask;
+
+  if (replace_existing)
+    new_mask = desc_to_merge->mask;
+  else
+    new_mask = desc_to_merge->mask & ~desc->mask;
+
+  if (new_mask & PANGO_FONT_MASK_FAMILY)
+    {
+      if (deep)
+        pango_font_description_set_family (desc, desc_to_merge->family_name);
+      else
+        pango_font_description_set_family_static (desc, desc_to_merge->family_name);
+    }
+  if (new_mask & PANGO_FONT_MASK_STYLE)
+    desc->style = desc_to_merge->style;
+  if (new_mask & PANGO_FONT_MASK_VARIANT)
+    desc->variant = desc_to_merge->variant;
+  if (new_mask & PANGO_FONT_MASK_WEIGHT)
+    desc->weight = desc_to_merge->weight;
+  if (new_mask & PANGO_FONT_MASK_STRETCH)
+    desc->stretch = desc_to_merge->stretch;
+  if (new_mask & PANGO_FONT_MASK_SIZE)
+    {
+      desc->size = desc_to_merge->size;
+      desc->size_is_absolute = desc_to_merge->size_is_absolute;
+    }
+  if (new_mask & PANGO_FONT_MASK_GRAVITY)
+    desc->gravity = desc_to_merge->gravity;
+  if (new_mask & PANGO_FONT_MASK_DOMAIN)
+    {
+      if (!desc->static_domain)
+        pango_font_description_domain_free (desc->domain);
+      if (deep)
+	desc->domain = pango_font_description_domain_copy (desc_to_merge->domain);
+      else
+	desc->domain = desc_to_merge->domain;
+    }
+
+  desc->mask |= new_mask;
+}
 /**
  * pango_font_description_merge:
  * @desc: a #PangoFontDescription
@@ -535,20 +689,10 @@ pango_font_description_merge (PangoFontD
 			      const PangoFontDescription *desc_to_merge,
 			      gboolean                    replace_existing)
 {
-  gboolean family_merged;
-
   g_return_if_fail (desc != NULL);
   g_return_if_fail (desc_to_merge != NULL);
 
-  family_merged = desc_to_merge->family_name && (replace_existing || !desc->family_name);
-
-  pango_font_description_merge_static (desc, desc_to_merge, replace_existing);
-
-  if (family_merged)
-    {
-      desc->family_name = g_strdup (desc->family_name);
-      desc->static_family = FALSE;
-    }
+  pango_font_description_merge_internal (desc, desc_to_merge, replace_existing, TRUE);
 }
 
 /**
@@ -569,35 +713,10 @@ pango_font_description_merge_static (Pan
 				     const PangoFontDescription *desc_to_merge,
 				     gboolean                    replace_existing)
 {
-  PangoFontMask new_mask;
-
   g_return_if_fail (desc != NULL);
   g_return_if_fail (desc_to_merge != NULL);
 
-  if (replace_existing)
-    new_mask = desc_to_merge->mask;
-  else
-    new_mask = desc_to_merge->mask & ~desc->mask;
-
-  if (new_mask & PANGO_FONT_MASK_FAMILY)
-    pango_font_description_set_family_static (desc, desc_to_merge->family_name);
-  if (new_mask & PANGO_FONT_MASK_STYLE)
-    desc->style = desc_to_merge->style;
-  if (new_mask & PANGO_FONT_MASK_VARIANT)
-    desc->variant = desc_to_merge->variant;
-  if (new_mask & PANGO_FONT_MASK_WEIGHT)
-    desc->weight = desc_to_merge->weight;
-  if (new_mask & PANGO_FONT_MASK_STRETCH)
-    desc->stretch = desc_to_merge->stretch;
-  if (new_mask & PANGO_FONT_MASK_SIZE)
-    {
-      desc->size = desc_to_merge->size;
-      desc->size_is_absolute = desc_to_merge->size_is_absolute;
-    }
-  if (new_mask & PANGO_FONT_MASK_GRAVITY)
-    desc->gravity = desc_to_merge->gravity;
-
-  desc->mask |= new_mask;
+  pango_font_description_merge_internal (desc, desc_to_merge, replace_existing, FALSE);
 }
 
 static gint
@@ -680,6 +799,12 @@ pango_font_description_copy  (const Pang
       result->static_family = FALSE;
     }
 
+  if (result->domain)
+    {
+      result->domain = pango_font_description_domain_copy (result->domain);
+      result->static_domain = FALSE;
+    }
+
   return result;
 }
 
@@ -707,6 +832,8 @@ pango_font_description_copy_static (cons
   *result = *desc;
   if (result->family_name)
     result->static_family = TRUE;
+  if (result->domain)
+    result->static_domain = TRUE;
 
   return result;
 }
@@ -740,7 +867,10 @@ pango_font_description_equal (const Pang
 	 desc1->size_is_absolute == desc2->size_is_absolute &&
 	 desc1->gravity == desc2->gravity &&
 	 (desc1->family_name == desc2->family_name ||
-	  (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, desc2->family_name) == 0));
+	  (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, desc2->family_name) == 0)) &&
+	 (G_LIKELY (desc1->domain == desc2->domain) ||
+	  pango_font_description_domain_equal (desc1->domain, desc2->domain));
+
 }
 
 #define TOLOWER(c) \
@@ -787,6 +917,7 @@ pango_font_description_hash (const Pango
   hash ^= desc->weight << 16;
   hash ^= desc->stretch << 26;
   hash ^= desc->gravity << 28;
+  hash ^= pango_font_description_domain_hash (desc->domain);
 
   return hash;
 }
@@ -805,6 +936,9 @@ pango_font_description_free  (PangoFontD
       if (desc->family_name && !desc->static_family)
 	g_free (desc->family_name);
 
+      if (G_UNLIKELY (desc->domain && !desc->static_domain))
+	pango_font_description_domain_free (desc->domain);
+
       g_slice_free (PangoFontDescription, desc);
     }
 }
@@ -1107,11 +1241,20 @@ pango_font_description_to_string (const 
 
   result = g_string_new (NULL);
 
-  if (desc->family_name && desc->mask & PANGO_FONT_MASK_FAMILY)
+  if (desc->domain)
+    {
+      g_string_append (result, g_quark_to_string (desc->domain->quark));
+      g_string_append_c (result, ':');
+    }
+
+  if (desc->family_name)
     {
       const char *p;
       size_t wordlen;
 
+      if (result->len > 0)
+	g_string_append_c (result, ' ');
+
       g_string_append (result, desc->family_name);
 
       /* We need to add a trailing comma if the family name ends
Index: pango-font.h
===================================================================
--- pango-font.h	(revision 2348)
+++ pango-font.h	(working copy)
@@ -80,7 +80,8 @@ typedef enum {
   PANGO_FONT_MASK_WEIGHT  = 1 << 3,
   PANGO_FONT_MASK_STRETCH = 1 << 4,
   PANGO_FONT_MASK_SIZE    = 1 << 5,
-  PANGO_FONT_MASK_GRAVITY = 1 << 6
+  PANGO_FONT_MASK_GRAVITY = 1 << 6,
+  PANGO_FONT_MASK_DOMAIN  = 1 << 7
 } PangoFontMask;
 
 /* CSS scale factors (1.2 factor between each size) */
@@ -135,6 +136,13 @@ gboolean             pango_font_descript
 void                 pango_font_description_set_gravity       (PangoFontDescription *desc,
 							       PangoGravity          gravity);
 PangoGravity         pango_font_description_get_gravity       (const PangoFontDescription *desc) G_GNUC_PURE;
+void                 pango_font_description_set_domain        (PangoFontDescription *desc,
+							       GQuark                domain,
+							       gpointer              data,
+							       GBoxedCopyFunc        dcopyfunc,
+							       GBoxedFreeFunc        dfreefunc);
+GQuark               pango_font_description_get_domain        (const PangoFontDescription *desc,
+							       gpointer                   *data);
 
 PangoFontMask pango_font_description_get_set_fields (const PangoFontDescription *desc) G_GNUC_PURE;
 void          pango_font_description_unset_fields   (PangoFontDescription       *desc,
Index: pangocairo-fontmap.c
===================================================================
--- pangocairo-fontmap.c	(revision 2348)
+++ pangocairo-fontmap.c	(working copy)
@@ -231,6 +231,44 @@ pango_cairo_font_map_create_context (Pan
 }
 
 /**
+ * pango_cairo_font_map_create_font_description_for_font_face:
+ * @fontmap: a #PangoCairoFontMap
+ * @fontface: a #cairo_font_face_t
+ *
+ * Create a #PangoContext for the given fontmap.
+ * Creates a special kind of #PangoFontDescription that when
+ * used to render text with @fontmap, will use @fontface.
+ *
+ * Return value: the newly created font descrption, or %NULL if @fontface
+ *   cannot be used with @fontmap; free with pango_font_description_free().
+ *
+ * Since: 1.18
+ **/
+PangoFontDescription *
+pango_cairo_font_map_create_font_description_for_font_face (PangoCairoFontMap *fontmap,
+							    cairo_font_face_t *fontface)
+{
+  PangoFontDescription *desc;
+
+  g_return_val_if_fail (fontmap != NULL, NULL);
+  g_return_val_if_fail (fontface != NULL, NULL);
+
+  if (cairo_font_face_get_type (fontface) !=
+      pango_cairo_font_map_get_font_type (fontmap))
+    return NULL;
+
+  desc = pango_font_description_new ();
+
+  pango_font_description_set_domain (desc,
+				     _pango_cairo_get_font_face_desc_quark (),
+				     fontface,
+				     (GBoxedCopyFunc) cairo_font_face_reference,
+				     (GBoxedFreeFunc) cairo_font_face_destroy);
+
+  return desc;
+}
+
+/**
  * pango_cairo_font_map_get_font_type:
  * @fontmap: a #PangoCairoFontMap
  *
@@ -247,3 +285,16 @@ pango_cairo_font_map_get_font_type (Pang
 
   return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_font_type) (fontmap);
 }
+
+GQuark
+_pango_cairo_get_font_face_desc_quark (void)
+{
+  static GQuark quark = 0;
+
+  if (G_UNLIKELY (!quark))
+    {
+      quark = g_quark_from_string ("cairo_font_face_t");
+    }
+
+  return quark;
+}
Index: pangocairo-private.h
===================================================================
--- pangocairo-private.h	(revision 2348)
+++ pangocairo-private.h	(working copy)
@@ -83,6 +83,7 @@ struct _PangoCairoFontPrivate
    
   PangoCairoFontPrivateScaledFontData *data;
 
+  cairo_font_face_t *font_face;
   cairo_scaled_font_t *scaled_font;
   PangoCairoFontHexBoxInfo *hbi;
 
@@ -147,6 +148,8 @@ struct _PangoCairoWarningHistory {
 
 extern PangoCairoWarningHistory _pango_cairo_warning_history;
 
+GQuark _pango_cairo_get_font_face_desc_quark (void) G_GNUC_CONST;
+
 G_END_DECLS
 
 #endif /* __PANGOCAIRO_PRIVATE_H__ */
Index: pangocairo-font.c
===================================================================
--- pangocairo-font.c	(revision 2354)
+++ pangocairo-font.c	(working copy)
@@ -85,8 +85,6 @@ _pango_cairo_font_private_scaled_font_da
 cairo_scaled_font_t *
 _pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *cf_priv)
 {
-  cairo_font_face_t *font_face;
-
   if (G_LIKELY (cf_priv->scaled_font))
     return cf_priv->scaled_font;
 
@@ -98,17 +96,16 @@ _pango_cairo_font_private_get_scaled_fon
       return NULL;
     }
 
-  font_face = (* PANGO_CAIRO_FONT_GET_IFACE (cf_priv->cfont)->create_font_face) (cf_priv->cfont);
-  if (G_UNLIKELY (font_face == NULL))
+  if (cf_priv->font_face == NULL)
+    cf_priv->font_face = (* PANGO_CAIRO_FONT_GET_IFACE (cf_priv->cfont)->create_font_face) (cf_priv->cfont);
+  if (G_UNLIKELY (cf_priv->font_face == NULL))
     goto done;
 
-  cf_priv->scaled_font = cairo_scaled_font_create (font_face,
+  cf_priv->scaled_font = cairo_scaled_font_create (cf_priv->font_face,
 						   &cf_priv->data->font_matrix,
 						   &cf_priv->data->ctm,
 						   cf_priv->data->options);
 
-  cairo_font_face_destroy (font_face);
-
 done:
   _pango_cairo_font_private_scaled_font_data_destroy (cf_priv->data);
   cf_priv->data = NULL;
@@ -130,7 +127,7 @@ done:
 	  pango_font_description_free (desc);
 
 	  g_warning ("failed to create cairo %s, expect ugly output. the offending font is '%s'",
-		     font_face ? "scaled font" : "font face",
+		     cf_priv->font_face ? "scaled font" : "font face",
 		     s);
 
 	  g_free (s);
@@ -500,6 +497,7 @@ _pango_cairo_font_private_initialize (Pa
   const cairo_font_options_t *font_options;
   cairo_matrix_t gravity_matrix;
   const PangoMatrix *pango_ctm;
+  gpointer domain_data;
 
   cf_priv->cfont = cfont;
   cf_priv->gravity = pango_font_description_get_gravity (desc);
@@ -531,10 +529,17 @@ _pango_cairo_font_private_initialize (Pa
   cf_priv->data->options = cairo_font_options_copy (font_options);
   cf_priv->is_hinted = cairo_font_options_get_hint_metrics (font_options) != CAIRO_HINT_METRICS_OFF;
 
+  cf_priv->font_face = NULL;
   cf_priv->scaled_font = NULL;
   cf_priv->hbi = NULL;
   cf_priv->glyph_extents_cache = NULL;
   cf_priv->metrics_by_lang = NULL;
+
+  if (pango_font_description_get_domain (desc, &domain_data) ==
+      _pango_cairo_get_font_face_desc_quark ())
+    {
+      cf_priv->font_face = cairo_font_face_reference ((cairo_font_face_t *) domain_data);
+    }
 }
 
 static void
@@ -549,6 +554,9 @@ _pango_cairo_font_private_finalize (Pang
 {
   _pango_cairo_font_private_scaled_font_data_destroy (cf_priv->data);
 
+  if (cf_priv->font_face)
+    cairo_font_face_destroy (cf_priv->font_face);
+
   if (cf_priv->scaled_font)
     cairo_scaled_font_destroy (cf_priv->scaled_font);
 
Index: pangocairo.h
===================================================================
--- pangocairo.h	(revision 2348)
+++ pangocairo.h	(working copy)
@@ -62,7 +62,10 @@ cairo_font_type_t pango_cairo_font_map_g
 void          pango_cairo_font_map_set_resolution (PangoCairoFontMap *fontmap,
 						   double             dpi);
 double        pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap);
+
 PangoContext *pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap);
+PangoFontDescription *pango_cairo_font_map_create_font_description_for_font_face (PangoCairoFontMap *fontmap,
+										  cairo_font_face_t *fontface);
 
 /*
  * PangoFont methods available to PangoCairo fonts
