struct _PangoContext
{
GObject parent_instance;
+ guint serial;
+ guint fontmap_serial;
PangoLanguage *set_language;
PangoLanguage *language;
};
-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)
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;
{
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)
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);
g_object_unref (context->font_map);
context->font_map = font_map;
+ context->fontmap_serial = pango_font_map_get_serial (font_map);
}
/**
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);
}
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);
+ }
}
/**
{
g_return_if_fail (context != NULL);
+ if (language != context->language)
+ context_changed (context);
+
context->set_language = language;
if (language)
context->language = language;
{
g_return_if_fail (context != NULL);
+ if (direction != context->base_dir)
+ context_changed (context);
+
context->base_dir = direction;
}
{
g_return_if_fail (context != NULL);
+ if (gravity != context->base_gravity)
+ context_changed (context);
+
context->base_gravity = gravity;
update_resolved_gravity (context);
{
g_return_if_fail (context != NULL);
+ if (hint != context->gravity_hint)
+ context_changed (context);
+
context->gravity_hint = hint;
}
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;
+}
return info;
}
-static gboolean
+static void
_pango_cairo_update_context (cairo_t *cr,
PangoContext *context)
{
pango_context_set_matrix (context, &pango_matrix);
-
- return changed;
+ if (changed)
+ pango_context_changed (context);
}
/**
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);
}
/**
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)
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));
}