summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2012-12-05 13:56:06 +0100
committerAlexander Larsson <alexl@redhat.com>2012-12-06 16:36:19 +0100
commit3070717bc6e4c2a7bf83508ae5bf7a03eb77bf4b (patch)
tree271e308ecba228326aa3126f0719936f8d73904b
parent3f3a095a1809375ef600dc3a947b3ff2df08f22c (diff)
downloadpango-3070717bc6e4c2a7bf83508ae5bf7a03eb77bf4b.tar.gz
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
-rw-r--r--docs/pango-sections.txt2
-rw-r--r--docs/tmpl/main.sgml17
-rw-r--r--pango/pango-context.c106
-rw-r--r--pango/pango-context.h3
-rw-r--r--pango/pango.def2
-rw-r--r--pango/pangocairo-context.c16
6 files changed, 135 insertions, 11 deletions
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index bce6cf48..ec004bdc 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 419340f0..ea6c2a74 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 341f92a6..0477a957 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 d85928a5..65b1d245 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 66e70d3b..3b4252f3 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 65223b66..32b4ef1e 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));
}