From: Alexander Larsson Date: Wed, 5 Dec 2012 12:56:06 +0000 (+0100) Subject: Track changes in PangoContext via a serial X-Git-Tag: 1.32.4~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3070717bc6e4c2a7bf83508ae5bf7a03eb77bf4b;p=platform%2Fupstream%2Fpango.git 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 --- 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 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: + + + + + +@context: + + + + + + + +@context: +@Returns: + + 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)); }