PangoLayoutRun *run; /* FIXME nuke this, just keep the link */
int index;
- /* layout extents in layout coordinates */
- PangoRectangle logical_rect;
-
/* list of Extents for each line in layout coordinates */
GSList *line_extents;
GSList *line_extents_link;
CACHED,
LEAKED
} cache_status;
-
PangoRectangle ink_rect;
PangoRectangle logical_rect;
};
pango_layout_get_extents_internal (PangoLayout *layout,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect,
- GSList **line_extents,
- int *real_width)
+ GSList **line_extents)
{
GSList *line_list;
int y_offset = 0;
int width;
gboolean need_width = FALSE;
- PangoRectangle logical_rect_local;
g_return_if_fail (layout != NULL);
+ if (ink_rect && layout->ink_rect_cached)
+ {
+ *ink_rect = layout->ink_rect;
+ ink_rect = NULL;
+ }
+ if (logical_rect && layout->logical_rect_cached)
+ {
+ *logical_rect = layout->logical_rect;
+ logical_rect = NULL;
+ }
+ 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
{
PangoRectangle overall_logical;
- pango_layout_get_extents (layout, NULL, &overall_logical);
+ pango_layout_get_extents_internal (layout, NULL, &overall_logical, NULL);
width = overall_logical.width;
}
- /* if user asked for real width and we don't have the width so far, make
- * sure we compute the logical_rect so we get the width at the end of the
- * function. This way we don't have to call a second get_extents().
- */
- if (width == -1 && real_width && !logical_rect)
- logical_rect = &logical_rect_local;
-
if (logical_rect)
{
logical_rect->x = 0;
line_list = line_list->next;
}
+ if (ink_rect)
+ {
+ layout->ink_rect = *ink_rect;
+ layout->ink_rect_cached = TRUE;
+ }
+ if (logical_rect)
+ {
+ layout->logical_rect = *logical_rect;
+ layout->logical_rect_cached = TRUE;
+ }
if (line_extents)
*line_extents = g_slist_reverse (*line_extents);
-
- if (real_width)
- *real_width = width == -1 ? logical_rect->width : width;
}
/**
{
g_return_if_fail (layout != NULL);
- pango_layout_get_extents_internal (layout, ink_rect, logical_rect, NULL, NULL);
+ pango_layout_get_extents_internal (layout, ink_rect, logical_rect, NULL);
}
/**
g_free (layout->log_attrs);
layout->log_attrs = NULL;
}
+ layout->logical_rect_cached = FALSE;
+ layout->ink_rect_cached = FALSE;
}
static void
PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
private->cache_status = LEAKED;
+
+ if (line->layout)
+ {
+ line->layout->logical_rect_cached = FALSE;
+ line->layout->ink_rect_cached = FALSE;
+ }
}
\f
if (!LINE_IS_VALID (line))
return;
+ if (G_UNLIKELY (!ink_rect && !logical_rect))
+ return;
+
switch (private->cache_status)
{
case CACHED:
new->run = iter->run;
new->index = iter->index;
- new->logical_rect = iter->logical_rect;
-
new->line_extents = NULL;
new->line_extents_link = NULL;
for (l = iter->line_extents; l; l = l->next)
{
int run_start_index;
PangoLayoutIter *iter;
+ PangoRectangle logical_rect;
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
iter->line_extents = NULL;
pango_layout_get_extents_internal (layout,
NULL,
- &iter->logical_rect,
- &iter->line_extents,
- &iter->layout_width);
+ &logical_rect,
+ &iter->line_extents);
+ iter->layout_width = layout->width == -1 ? logical_rect.width : layout->width;
iter->line_extents_link = iter->line_extents;
if (ITER_IS_INVALID (iter))
return;
- if (ink_rect)
- {
- /* expensive recomputation, woo-hoo */
- pango_layout_get_extents (iter->layout,
- ink_rect,
- NULL);
- }
-
- if (logical_rect)
- *logical_rect = iter->logical_rect;
+ pango_layout_get_extents (iter->layout, ink_rect, logical_rect);
}