diff options
author | Alexander Larsson <alexl@redhat.com> | 2012-12-05 13:56:06 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2012-12-06 16:36:19 +0100 |
commit | 3070717bc6e4c2a7bf83508ae5bf7a03eb77bf4b (patch) | |
tree | 271e308ecba228326aa3126f0719936f8d73904b | |
parent | 3f3a095a1809375ef600dc3a947b3ff2df08f22c (diff) | |
download | pango-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.txt | 2 | ||||
-rw-r--r-- | docs/tmpl/main.sgml | 17 | ||||
-rw-r--r-- | pango/pango-context.c | 106 | ||||
-rw-r--r-- | pango/pango-context.h | 3 | ||||
-rw-r--r-- | pango/pango.def | 2 | ||||
-rw-r--r-- | 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 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)); } |