}
#endif
+static void check_context_changed (PangoLayout *layout);
+static void layout_changed (PangoLayout *layout);
+
static void pango_layout_clear_lines (PangoLayout *layout);
static void pango_layout_check_lines (PangoLayout *layout);
static void
pango_layout_init (PangoLayout *layout)
{
+ layout->serial = 1;
layout->attrs = NULL;
layout->font_desc = NULL;
layout->text = NULL;
layout = g_object_new (PANGO_TYPE_LAYOUT, NULL);
layout->context = context;
+ layout->context_serial = pango_context_get_serial (context);
g_object_ref (context);
return layout;
{
g_return_if_fail (layout != NULL);
+ if (width < 0)
+ width = -1;
+
if (width != layout->width)
{
layout->width = width;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (layout->ellipsize != PANGO_ELLIPSIZE_NONE &&
!(layout->lines && layout->is_ellipsized == FALSE &&
height < 0 && layout->line_count <= (guint) -height))
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
layout->wrap = wrap;
if (layout->width != -1)
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (indent != layout->indent)
{
layout->indent = indent;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (spacing != layout->spacing)
{
layout->spacing = spacing;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
layout->attrs = attrs;
if (layout->attrs)
pango_attr_list_ref (layout->attrs);
- pango_layout_clear_lines (layout);
+
+ layout_changed (layout);
if (old_attrs)
pango_attr_list_unref (old_attrs);
layout->font_desc = desc ? pango_font_description_copy (desc) : NULL;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
layout->tab_width = -1;
}
}
layout->justify = justify;
if (layout->is_ellipsized || layout->is_wrapped)
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (auto_dir != layout->auto_dir)
{
layout->auto_dir = auto_dir;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (alignment != layout->alignment)
{
layout->alignment = alignment;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
layout->tabs = tabs ? pango_tab_array_copy (tabs) : NULL;
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
if (layout->single_paragraph != setting)
{
layout->single_paragraph = setting;
-
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
layout->ellipsize = ellipsize;
if (layout->is_ellipsized || layout->is_wrapped)
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
}
}
layout->n_chars = pango_utf8_strlen (layout->text, -1);
- pango_layout_clear_lines (layout);
+ layout_changed (layout);
g_free (old_text);
}
return count;
}
+static void
+check_context_changed (PangoLayout *layout)
+{
+ int old_serial = layout->context_serial;
+
+ layout->context_serial = pango_context_get_serial (layout->context);
+
+ if (old_serial != layout->context_serial)
+ pango_layout_context_changed (layout);
+}
+
+static void
+layout_changed (PangoLayout *layout)
+{
+ layout->serial++;
+ if (layout->serial == 0)
+ layout->serial++;
+ pango_layout_clear_lines (layout);
+}
+
/**
* pango_layout_context_changed:
* @layout: a #PangoLayout
void
pango_layout_context_changed (PangoLayout *layout)
{
- pango_layout_clear_lines (layout);
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
+
+ layout_changed (layout);
layout->tab_width = -1;
}
/**
+ * pango_layout_get_serial:
+ * @layout: a #PangoLayout
+ *
+ * Returns the current serial number of @layout. The serial number is
+ * initialized to an small number larger than zero when a new layout
+ * is created and is increased whenever the layout is changed using any
+ * of the setter functions, or the #PangoContext it uses 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 #PangoLayout, and
+ * is useful for example to decide whether a layout needs redrawing.
+ * To force the serial to be increased, use pango_layout_context_changed().
+ *
+ * Return value: The current serial number of @layout.
+ *
+ * Since: 1.32.4
+ **/
+guint
+pango_layout_get_serial (PangoLayout *layout)
+{
+ check_context_changed (layout);
+ return layout->serial;
+}
+
+/**
* pango_layout_get_log_attrs:
* @layout: a #PangoLayout
* @attrs: (out)(array length=n_attrs)(transfer container):
g_return_if_fail (layout != NULL);
+ pango_layout_check_lines (layout);
+
if (ink_rect && layout->ink_rect_cached)
{
*ink_rect = layout->ink_rect;
if (!ink_rect && !logical_rect && !line_extents)
return;
- pango_layout_check_lines (layout);
-
/* When we are not wrapping, we need the overall width of the layout to
* figure out the x_offsets of each line. However, we only need the
* x_offsets if we are computing the ink_rect or individual line extents.
PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL;
ParaBreakState state;
+ check_context_changed (layout);
+
if (G_LIKELY (layout->lines))
return;