[pangofc] Add a "fontmap" property to PangoFcFont
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 10 Mar 2009 12:08:19 +0000 (08:08 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Fri, 13 Mar 2009 22:03:42 +0000 (18:03 -0400)
Gecko uses its own PangoFcFontMap subclass with its own PangoFontSet.
Previously we were setting font->fontmap in our own private
PangoFcFontSet.  Now it's up to the PangoFcFont subclass to set it
when creating the new font object.

Also adds the following backend-public symbol:

pango_fc_font_map_find_decoder()

docs/pango-sections.txt
docs/tmpl/pangofc-font.sgml
docs/tmpl/pangofc-fontmap.sgml
pango/pangocairo-fcfont.c
pango/pangofc-font.c
pango/pangofc-fontmap.c
pango/pangofc-fontmap.h
pango/pangoft2.c
pango/pangoft2.def
pango/pangoxft-font.c

index 7ed853c..0fbdc22 100644 (file)
@@ -919,6 +919,7 @@ PangoFcFontMapClass
 pango_fc_font_map_create_context
 PangoFcDecoderFindFunc
 pango_fc_font_map_add_decoder_find_func
+pango_fc_font_map_find_decoder
 pango_fc_font_map_cache_clear
 pango_fc_font_map_shutdown
 pango_fc_font_description_from_pattern
index 95ac1dd..a1b055c 100644 (file)
@@ -40,6 +40,11 @@ Fontconfig-based backend involves deriving from both
 </para>
 
 
+<!-- ##### ARG PangoFcFont:fontmap ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG PangoFcFont:pattern ##### -->
 <para>
 
index bcfae81..ee6cca0 100644 (file)
@@ -86,6 +86,16 @@ Fontconfig-based backend involves deriving from both
 @dnotify: 
 
 
+<!-- ##### FUNCTION pango_fc_font_map_find_decoder ##### -->
+<para>
+
+</para>
+
+@fcfontmap: 
+@pattern: 
+@Returns: 
+
+
 <!-- ##### FUNCTION pango_fc_font_map_cache_clear ##### -->
 <para>
 
index 3039f9f..3ac166e 100644 (file)
@@ -223,6 +223,7 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
 
   cffont = g_object_new (PANGO_TYPE_CAIRO_FC_FONT,
                         "pattern", pattern,
+                        "fontmap", cffontmap,
                         NULL);
 
   size = get_font_size (pattern) /
index 133a4df..9c5b9ed 100644 (file)
@@ -34,7 +34,8 @@
 
 enum {
   PROP_0,
-  PROP_PATTERN
+  PROP_PATTERN,
+  PROP_FONTMAP
 };
 
 typedef struct _GUnicharToGlyphCacheEntry GUnicharToGlyphCacheEntry;
@@ -121,6 +122,13 @@ pango_fc_font_class_init (PangoFcFontClass *class)
                                                         "The fontconfig pattern for this font",
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_FONTMAP,
+                                  g_param_spec_object ("fontmap",
+                                                       "Font Map",
+                                                       "The PangoFc font map this font is associated with (Since: 1.26)",
+                                                       PANGO_TYPE_FC_FONT_MAP,
+                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                                       G_PARAM_STATIC_STRINGS));
 
   g_type_class_add_private (object_class, sizeof (PangoFcFontPrivate));
 }
@@ -203,11 +211,12 @@ pango_fc_font_set_property (GObject       *object,
                            const GValue  *value,
                            GParamSpec    *pspec)
 {
+  PangoFcFont *fcfont = PANGO_FC_FONT (object);
+
   switch (prop_id)
     {
     case PROP_PATTERN:
       {
-       PangoFcFont *fcfont = PANGO_FC_FONT (object);
        FcPattern *pattern = g_value_get_pointer (value);
 
        g_return_if_fail (pattern != NULL);
@@ -219,11 +228,30 @@ pango_fc_font_set_property (GObject       *object,
        fcfont->is_hinted = pattern_is_hinted (pattern);
        fcfont->is_transformed = pattern_is_transformed (pattern);
       }
-      break;
+      goto set_decoder;
+
+    case PROP_FONTMAP:
+      {
+       PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (g_value_get_object (value));
+
+       g_return_if_fail (fcfont->fontmap == NULL);
+       fcfont->fontmap = (PangoFontMap *) fcfontmap;
+       if (fcfont->fontmap)
+         g_object_add_weak_pointer (G_OBJECT (fcfont->fontmap), (gpointer *) (gpointer) &fcfont->fontmap);
+      }
+      goto set_decoder;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+      return;
     }
+
+set_decoder:
+  /* set decoder if both pattern and fontmap are set now */
+  if (fcfont->font_pattern && fcfont->fontmap)
+    _pango_fc_font_set_decoder (fcfont,
+                               pango_fc_font_map_find_decoder  ((PangoFcFontMap *) fcfont->fontmap,
+                                                                fcfont->font_pattern));
 }
 
 static void
@@ -240,6 +268,12 @@ pango_fc_font_get_property (GObject       *object,
        g_value_set_pointer (value, fcfont->font_pattern);
       }
       break;
+    case PROP_FONTMAP:
+      {
+       PangoFcFont *fcfont = PANGO_FC_FONT (object);
+       g_value_set_object (value, fcfont->fontmap);
+      }
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 07328b6..c3786e1 100644 (file)
@@ -1058,9 +1058,13 @@ pango_fc_font_map_add_decoder_find_func (PangoFcFontMap        *fcfontmap,
                                         gpointer               user_data,
                                         GDestroyNotify         dnotify)
 {
-  PangoFcFontMapPrivate *priv = fcfontmap->priv;
+  PangoFcFontMapPrivate *priv;
   PangoFcFindFuncInfo *info;
 
+  g_return_val_if_fail (PANGO_IS_FC_FONT_MAP (fcfontmap), NULL);
+
+  priv = fcfontmap->priv;
+
   info = g_slice_new (PangoFcFindFuncInfo);
 
   info->findfunc = findfunc;
@@ -1070,6 +1074,41 @@ pango_fc_font_map_add_decoder_find_func (PangoFcFontMap        *fcfontmap,
   priv->findfuncs = g_slist_append (priv->findfuncs, info);
 }
 
+/**
+ * pango_fc_font_map_find_decoder:
+ * @fcfontmap: The #PangoFcFontMap to use.
+ * @pattern: The #FcPattern to find the decoder for.
+ *
+ * Finds the decoder to use for @pattern.  Decoders can be added to
+ * a font map using pango_fc_font_map_add_decoder_find_func().
+ *
+ * Returns: a newly created #PangoFcDecoder object or %NULL if
+ *          no decoder is set for @pattern.
+ *
+ * Since: 1.26.
+ **/
+PangoFcDecoder *
+pango_fc_font_map_find_decoder  (PangoFcFontMap *fcfontmap,
+                                FcPattern      *pattern)
+{
+  GSList *l;
+
+  g_return_val_if_fail (PANGO_IS_FC_FONT_MAP (fcfontmap), NULL);
+  g_return_val_if_fail (pattern != NULL, NULL);
+
+  for (l = fcfontmap->priv->findfuncs; l && l->data; l = l->next)
+    {
+      PangoFcFindFuncInfo *info = l->data;
+      PangoFcDecoder *decoder;
+
+      decoder = info->findfunc (pattern, info->user_data);
+      if (decoder)
+       return decoder;
+    }
+
+  return NULL;
+}
+
 static void
 pango_fc_font_map_finalize (GObject *object)
 {
@@ -1089,13 +1128,6 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
   PangoFcFontMapPrivate *priv = fcfontmap->priv;
   PangoFcFontKey *key_copy;
 
-  g_assert (fcfont->fontmap == NULL);
-  fcfont->fontmap = (PangoFontMap *) fcfontmap;
-  /* In other fontmaps we add a weak pointer on ->fontmap so the
-   * field is unset when fontmap is finalized.  We don't need it
-   * here though as PangoFcFontMap already cleans up fcfont->fontmap
-   * as part of it's caching scheme. */
-
   key_copy = pango_fc_font_key_copy (key);
   _pango_fc_font_set_font_key (fcfont, key_copy);
   g_hash_table_insert (priv->font_hash, key_copy, fcfont);
@@ -1109,8 +1141,6 @@ _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
   PangoFcFontMapPrivate *priv = fcfontmap->priv;
   PangoFcFontKey *key;
 
-  fcfont->fontmap = NULL;
-
   key = _pango_fc_font_get_font_key (fcfont);
   if (key)
     {
@@ -1411,7 +1441,6 @@ pango_fc_font_map_new_font (PangoFcFontMap    *fcfontmap,
   PangoFcFontMapPrivate *priv = fcfontmap->priv;
   FcPattern *pattern;
   PangoFcFont *fcfont;
-  GSList *l;
   PangoFcFontKey key;
 
   if (priv->closed)
@@ -1462,25 +1491,9 @@ pango_fc_font_map_new_font (PangoFcFontMap    *fcfontmap,
 
   fcfont->matrix = key.matrix;
 
+  /* cache it on fontmap */
   pango_fc_font_map_add (fcfontmap, &key, fcfont);
 
-  /*
-   * Give any custom decoders a crack at this font now that it's been
-   * created.
-   */
-  for (l = priv->findfuncs; l && l->data; l = l->next)
-    {
-      PangoFcFindFuncInfo *info = l->data;
-      PangoFcDecoder *decoder;
-
-      decoder = info->findfunc (match, info->user_data);
-      if (decoder)
-       {
-         _pango_fc_font_set_decoder (fcfont, decoder);
-         break;
-       }
-    }
-
   return (PangoFont *)fcfont;
 }
 
@@ -1825,9 +1838,15 @@ pango_fc_font_map_create_context (PangoFcFontMap *fcfontmap)
 
 static void
 shutdown_font (gpointer        key G_GNUC_UNUSED,
-              PangoFcFont    *fcfont)
+              PangoFcFont    *fcfont,
+              PangoFcFontMap *fcfontmap)
 {
   _pango_fc_font_shutdown (fcfont);
+
+  /* While _pango_fc_font_shutdown() tries to call the following
+   * function, it's too late as the fontmap weakref has already
+   * NULL'ed fcfont->fontmap, so we do it ourselves. */
+  _pango_fc_font_map_remove (fcfontmap, fcfont);
 }
 
 /**
@@ -1852,7 +1871,7 @@ pango_fc_font_map_shutdown (PangoFcFontMap *fcfontmap)
   if (priv->closed)
     return;
 
-  g_hash_table_foreach (priv->font_hash, (GHFunc) shutdown_font, NULL);
+  g_hash_table_foreach (priv->font_hash, (GHFunc) shutdown_font, fcfontmap);
   for (i = 0; i < priv->n_families; i++)
     priv->families[i]->fontmap = NULL;
 
index d3f113a..8d496eb 100644 (file)
@@ -213,6 +213,8 @@ void pango_fc_font_map_add_decoder_find_func (PangoFcFontMap        *fcfontmap,
                                              PangoFcDecoderFindFunc findfunc,
                                              gpointer               user_data,
                                              GDestroyNotify         dnotify);
+PangoFcDecoder *pango_fc_font_map_find_decoder (PangoFcFontMap *fcfontmap,
+                                               FcPattern      *pattern);
 
 PangoFontDescription *pango_fc_font_description_from_pattern (FcPattern *pattern,
                                                              gboolean   include_size);
index d13dc69..224f6a0 100644 (file)
@@ -73,6 +73,7 @@ _pango_ft2_font_new (PangoFT2FontMap *ft2fontmap,
 
   ft2font = (PangoFT2Font *)g_object_new (PANGO_TYPE_FT2_FONT,
                                          "pattern", pattern,
+                                         "fontmap", fontmap,
                                          NULL);
 
   if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &d) == FcResultMatch)
index ba78cd4..4cfa0d1 100644 (file)
@@ -17,6 +17,7 @@ EXPORTS
        pango_fc_font_map_add_decoder_find_func
        pango_fc_font_map_cache_clear
        pango_fc_font_map_create_context
+       pango_fc_font_map_find_decoder
        pango_fc_font_map_get_type
        pango_fc_font_map_shutdown
        pango_fc_font_unlock_face
index ce633f7..6865490 100644 (file)
@@ -92,6 +92,7 @@ _pango_xft_font_new (PangoXftFontMap *xftfontmap,
 
   xfont = (PangoXftFont *)g_object_new (PANGO_TYPE_XFT_FONT,
                                        "pattern", pattern,
+                                       "fontmap", fontmap,
                                        NULL);
 
   /* Hack to force hinting of vertical metrics; hinting off for