[pango] Track changes in PangoContext via a serial



commit 3070717bc6e4c2a7bf83508ae5bf7a03eb77bf4b
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Dec 5 13:56:06 2012 +0100

    Track changes in PangoContext via a serial
    
    Whenever a PangoContext or its fontmap changes we bump the
    contexts serial, you can get it via pango_context_get_serial()
    to see find out if the context changed since the last time and
    you need to relayout.
    
    You can also force the context to be "changed" by calling
    pango_context_changed().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=340066

 docs/pango-sections.txt    |    2 +
 docs/tmpl/main.sgml        |   17 +++++++
 pango/pango-context.c      |  106 ++++++++++++++++++++++++++++++++++++++++++-
 pango/pango-context.h      |    3 +-
 pango/pango.def            |    2 +
 pango/pangocairo-context.c |   16 ++++---
 6 files changed, 135 insertions(+), 11 deletions(-)
---
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index bce6cf4..ec004bd 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -17,6 +17,8 @@ pango_item_split
 pango_reorder_items
 <SUBSECTION>
 pango_context_new
+pango_context_changed
+pango_context_get_serial
 pango_context_set_font_map
 pango_context_get_font_map
 pango_context_get_font_description
diff --git a/docs/tmpl/main.sgml b/docs/tmpl/main.sgml
index 419340f..ea6c2a7 100644
--- a/docs/tmpl/main.sgml
+++ b/docs/tmpl/main.sgml
@@ -155,6 +155,23 @@ The #GObject type for #PangoDirection.
 @Returns: 
 
 
+<!-- ##### FUNCTION pango_context_changed ##### -->
+<para>
+
+</para>
+
+ context: 
+
+
+<!-- ##### FUNCTION pango_context_get_serial ##### -->
+<para>
+
+</para>
+
+ context: 
+ Returns: 
+
+
 <!-- ##### FUNCTION pango_context_set_font_map ##### -->
 <para>
 
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 341f92a..0477a95 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -34,6 +34,8 @@
 struct _PangoContext
 {
   GObject parent_instance;
+  guint serial;
+  guint fontmap_serial;
 
   PangoLanguage *set_language;
   PangoLanguage *language;
@@ -55,7 +57,8 @@ struct _PangoContextClass
 
 };
 
-static void pango_context_finalize    (GObject           *object);
+static void pango_context_finalize    (GObject       *object);
+static void context_changed           (PangoContext  *context);
 
 G_DEFINE_TYPE (PangoContext, pango_context, G_TYPE_OBJECT)
 
@@ -66,6 +69,7 @@ pango_context_init (PangoContext *context)
   context->resolved_gravity = context->base_gravity = PANGO_GRAVITY_SOUTH;
   context->gravity_hint = PANGO_GRAVITY_HINT_NATURAL;
 
+  context->serial = 1;
   context->set_language = NULL;
   context->language = pango_language_get_default ();
   context->font_map = NULL;
@@ -164,6 +168,9 @@ pango_context_set_matrix (PangoContext       *context,
 {
   g_return_if_fail (PANGO_IS_CONTEXT (context));
 
+  if (context->matrix || matrix)
+    context_changed (context);
+
   if (context->matrix)
     pango_matrix_free (context->matrix);
   if (matrix)
@@ -212,6 +219,11 @@ pango_context_set_font_map (PangoContext *context,
   g_return_if_fail (PANGO_IS_CONTEXT (context));
   g_return_if_fail (!font_map || PANGO_IS_FONT_MAP (font_map));
 
+  if (font_map == context->font_map)
+    return;
+
+  context_changed (context);
+
   if (font_map)
     g_object_ref (font_map);
 
@@ -219,6 +231,7 @@ pango_context_set_font_map (PangoContext *context,
     g_object_unref (context->font_map);
 
   context->font_map = font_map;
+  context->fontmap_serial = pango_font_map_get_serial (font_map);
 }
 
 /**
@@ -289,6 +302,7 @@ pango_context_load_font (PangoContext               *context,
 			 const PangoFontDescription *desc)
 {
   g_return_val_if_fail (context != NULL, NULL);
+  g_return_val_if_fail (context->font_map != NULL, NULL);
 
   return pango_font_map_load_font (context->font_map, context, desc);
 }
@@ -329,8 +343,14 @@ pango_context_set_font_description (PangoContext               *context,
   g_return_if_fail (context != NULL);
   g_return_if_fail (desc != NULL);
 
-  pango_font_description_free (context->font_desc);
-  context->font_desc = pango_font_description_copy (desc);
+  if (desc != context->font_desc &&
+      (!desc || !context->font_desc || !pango_font_description_equal(desc, context->font_desc)))
+    {
+      context_changed (context);
+
+      pango_font_description_free (context->font_desc);
+      context->font_desc = pango_font_description_copy (desc);
+    }
 }
 
 /**
@@ -365,6 +385,9 @@ pango_context_set_language (PangoContext *context,
 {
   g_return_if_fail (context != NULL);
 
+  if (language != context->language)
+    context_changed (context);
+
   context->set_language = language;
   if (language)
     context->language = language;
@@ -408,6 +431,9 @@ pango_context_set_base_dir (PangoContext  *context,
 {
   g_return_if_fail (context != NULL);
 
+  if (direction != context->base_dir)
+    context_changed (context);
+
   context->base_dir = direction;
 }
 
@@ -445,6 +471,9 @@ pango_context_set_base_gravity (PangoContext  *context,
 {
   g_return_if_fail (context != NULL);
 
+  if (gravity != context->base_gravity)
+    context_changed (context);
+
   context->base_gravity = gravity;
 
   update_resolved_gravity (context);
@@ -509,6 +538,9 @@ pango_context_set_gravity_hint (PangoContext    *context,
 {
   g_return_if_fail (context != NULL);
 
+  if (hint != context->gravity_hint)
+    context_changed (context);
+
   context->gravity_hint = hint;
 }
 
@@ -1746,3 +1778,71 @@ pango_context_get_metrics (PangoContext                 *context,
 
   return metrics;
 }
+
+static void
+context_changed  (PangoContext *context)
+{
+  context->serial++;
+  if (context->serial == 0)
+    context->serial++;
+}
+
+/**
+ * pango_context_changed:
+ * @context: a #PangoContext
+ *
+ * Forces a change in the context, which will cause any #PangoLayout
+ * using this context to re-layout.
+ *
+ * This function is only useful when implementing a new backend
+ * for Pango, something applications won't do. Backends should
+ * call this function if they have attached extra data to the context
+ * and such data is changed.
+ *
+ * Since: 1.32.4
+ **/
+void
+pango_context_changed  (PangoContext *context)
+{
+  context_changed (context);
+}
+
+static void
+check_fontmap_changed (PangoContext *context)
+{
+  guint old_serial = context->fontmap_serial;
+
+  if (!context->font_map)
+    return;
+
+  context->fontmap_serial = pango_font_map_get_serial (context->font_map);
+
+  if (old_serial != context->fontmap_serial)
+    context_changed (context);
+}
+
+/**
+ * pango_context_get_serial:
+ * @context: a #PangoContext
+ *
+ * Returns the current serial number of @context.  The serial number is
+ * initialized to an small number larger than zero when a new context
+ * is created and is increased whenever the context is changed using any
+ * of the setter functions, or the #PangoFontMap it uses to find fonts has
+ * changed. The serial may wrap, but will never have the value 0. Since it
+ * can wrap, never compare it with "less than", always use "not equals".
+ *
+ * This can be used to automatically detect changes to a #PangoContext, and
+ * is only useful when implementing objects that need update when their
+ * #PangoContext changes, like #PangoLayout.
+ *
+ * Return value: The current serial number of @context.
+ *
+ * Since: 1.32.4
+ **/
+guint
+pango_context_get_serial (PangoContext *context)
+{
+  check_fontmap_changed (context);
+  return context->serial;
+}
diff --git a/pango/pango-context.h b/pango/pango-context.h
index d85928a..65b1d24 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -50,10 +50,11 @@ typedef struct _PangoContextClass PangoContextClass;
 GType         pango_context_get_type      (void) G_GNUC_CONST;
 
 PangoContext *pango_context_new           (void);
+void          pango_context_changed       (PangoContext                 *context);
 void          pango_context_set_font_map  (PangoContext                 *context,
 					   PangoFontMap                 *font_map);
 PangoFontMap *pango_context_get_font_map  (PangoContext                 *context);
-
+guint         pango_context_get_serial    (PangoContext                 *context);
 void          pango_context_list_families (PangoContext                 *context,
 					   PangoFontFamily            ***families,
 					   int                          *n_families);
diff --git a/pango/pango.def b/pango/pango.def
index 66e70d3..3b4252f 100644
--- a/pango/pango.def
+++ b/pango/pango.def
@@ -58,6 +58,7 @@ EXPORTS
 	pango_color_to_string
 	pango_config_key_get
 	pango_config_key_get_system
+	pango_context_changed
 	pango_context_get_base_dir
 	pango_context_get_base_gravity
 	pango_context_get_font_description
@@ -67,6 +68,7 @@ EXPORTS
 	pango_context_get_language
 	pango_context_get_matrix
 	pango_context_get_metrics
+	pango_context_get_serial
 	pango_context_get_type
 	pango_context_list_families
 	pango_context_load_font
diff --git a/pango/pangocairo-context.c b/pango/pangocairo-context.c
index 65223b6..32b4ef1 100644
--- a/pango/pangocairo-context.c
+++ b/pango/pangocairo-context.c
@@ -88,7 +88,7 @@ retry:
   return info;
 }
 
-static gboolean
+static void
 _pango_cairo_update_context (cairo_t      *cr,
 			     PangoContext *context)
 {
@@ -144,8 +144,8 @@ _pango_cairo_update_context (cairo_t      *cr,
 
   pango_context_set_matrix (context, &pango_matrix);
 
-
-  return changed;
+  if (changed)
+    pango_context_changed (context);
 }
 
 /**
@@ -168,7 +168,7 @@ pango_cairo_update_context (cairo_t      *cr,
   g_return_if_fail (cr != NULL);
   g_return_if_fail (PANGO_IS_CONTEXT (context));
 
-  (void) _pango_cairo_update_context (cr, context);
+  _pango_cairo_update_context (cr, context);
 }
 
 /**
@@ -237,7 +237,10 @@ pango_cairo_context_set_font_options (PangoContext               *context,
 
   info  = get_context_info (context, TRUE);
 
-  if (info->set_options)
+  if (info->set_options || options)
+    pango_context_changed (context);
+
+ if (info->set_options)
     cairo_font_options_destroy (info->set_options);
 
   if (options)
@@ -474,7 +477,6 @@ pango_cairo_update_layout (cairo_t     *cr,
   g_return_if_fail (cr != NULL);
   g_return_if_fail (PANGO_IS_LAYOUT (layout));
 
-  if (_pango_cairo_update_context (cr, pango_layout_get_context (layout)))
-    pango_layout_context_changed (layout);
+  _pango_cairo_update_context (cr, pango_layout_get_context (layout));
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]