Merge branch 'text-actor-layout-height'

* text-actor-layout-height:
  [clutter-text] Fix ellipsizing
  Support pango_layout_set_height() in ClutterText

Conflicts:
	clutter/clutter-text.c
This commit is contained in:
Emmanuele Bassi 2009-04-15 18:08:14 +01:00
commit 425fa78a27

View File

@ -86,13 +86,16 @@ struct _LayoutCache
*/
PangoLayout *layout;
/* The width that used to generate this layout */
ClutterUnit width;
/* The width that was used to generate this layout */
ClutterUnit width;
/* The height that was used to generate this layout */
ClutterUnit height;
/* A number representing the age of this cache (so that when a
* new layout is needed the last used cache is replaced)
*/
guint age;
guint age;
};
struct _ClutterTextPrivate
@ -237,7 +240,8 @@ clutter_text_clear_selection (ClutterText *self)
static PangoLayout *
clutter_text_create_layout_no_cache (ClutterText *text,
ClutterUnit allocation_width)
ClutterUnit allocation_width,
ClutterUnit allocation_height)
{
ClutterTextPrivate *priv = text->priv;
PangoLayout *layout;
@ -281,45 +285,68 @@ clutter_text_create_layout_no_cache (ClutterText *text,
pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode);
pango_layout_set_justify (layout, priv->justify);
if (allocation_width > 0 &&
(priv->ellipsize != PANGO_ELLIPSIZE_NONE || priv->wrap))
/* Cases, assuming ellipsize != NONE on actor:
*
* Width request: ellipsization can be set or not on layout,
* doesn't matter.
*
* Height request: ellipsization must never be set on layout
* if wrap=true, because we need to measure the wrapped
* height. It must always be set if wrap=false.
*
* Allocate: ellipsization must always be set.
*
* See http://bugzilla.gnome.org/show_bug.cgi?id=560931
*/
if (priv->ellipsize != PANGO_ELLIPSIZE_NONE)
{
int layout_width, layout_height;
pango_layout_get_size (layout, &layout_width, &layout_height);
/* no need to set ellipsize or wrap if we already have enough
* space, since we don't want to make the layout wider than it
* would be otherwise.
*/
if (CLUTTER_UNITS_FROM_PANGO_UNIT (layout_width) > allocation_width)
if (allocation_height < 0 && priv->wrap)
; /* must not set ellipsization on wrap=true height request */
else
{
if (!priv->editable && priv->ellipsize != PANGO_ELLIPSIZE_NONE)
{
gint width;
width = allocation_width > 0
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
: -1;
pango_layout_set_ellipsize (layout, priv->ellipsize);
pango_layout_set_width (layout, width);
}
else if (priv->wrap)
{
gint width;
width = allocation_width > 0
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
: -1;
pango_layout_set_wrap (layout, priv->wrap_mode);
pango_layout_set_width (layout, width);
}
if (!priv->editable)
pango_layout_set_ellipsize (layout, priv->ellipsize);
}
}
/* we only limit the layout when in multi-line mode since the
* single line mode will take care of scrolling to accomodate
* the allocation width
*/
if (allocation_width > 0 && !priv->single_line_mode)
{
gint width;
width = allocation_width > 0
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
: -1;
pango_layout_set_width (layout, width);
}
/* Pango only uses height if ellipsization is enabled, so don't set
* height if ellipsize isn't set. Pango implicitly enables wrapping
* if height is set, so don't set height if wrapping is disabled.
* In other words, only set height if we want to both wrap then
* ellipsize and we're not in single line mode.
*
* See http://bugzilla.gnome.org/show_bug.cgi?id=560931 if this
* seems odd.
*/
if (allocation_height > 0 &&
priv->wrap &&
priv->ellipsize != PANGO_ELLIPSIZE_NONE &&
!priv->single_line_mode)
{
gint height;
height = allocation_height > 0
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_height)
: -1;
pango_layout_set_height (layout, height);
}
return layout;
}
@ -350,6 +377,7 @@ clutter_text_font_changed_cb (ClutterText *text)
* clutter_text_create_layout:
* @text: a #ClutterText
* @allocation_width: the allocation width
* @allocation_height: the allocation height
*
* Like clutter_text_create_layout_no_cache(), but will also ensure
* the glyphs cache. If a previously cached layout generated using the
@ -358,15 +386,17 @@ clutter_text_font_changed_cb (ClutterText *text)
*/
static PangoLayout *
clutter_text_create_layout (ClutterText *text,
ClutterUnit allocation_width)
ClutterUnit allocation_width,
ClutterUnit allocation_height)
{
ClutterTextPrivate *priv = text->priv;
LayoutCache *oldest_cache = priv->cached_layouts;
gboolean found_free_cache = FALSE;
int i;
/* Search for a cached layout with the same width and keep track of
the oldest one */
/* Search for a cached layout with the same width and keep
* track of the oldest one
*/
for (i = 0; i < N_CACHED_LAYOUTS; i++)
{
if (priv->cached_layouts[i].layout == NULL)
@ -375,13 +405,16 @@ clutter_text_create_layout (ClutterText *text,
found_free_cache = TRUE;
oldest_cache = priv->cached_layouts + i;
}
/* If this cached layout is using the same width then we can
just return that directly */
else if (priv->cached_layouts[i].width == allocation_width)
else if (priv->cached_layouts[i].width == allocation_width &&
priv->cached_layouts[i].height == allocation_height)
{
CLUTTER_NOTE (ACTOR, "ClutterText: %p: cache hit for width %i",
/* If this cached layout is using the same size then we can
* just return that directly
*/
CLUTTER_NOTE (ACTOR, "ClutterText: %p: cache hit for size %i x %i",
text,
CLUTTER_UNITS_TO_DEVICE (allocation_width));
CLUTTER_UNITS_TO_DEVICE (allocation_width),
CLUTTER_UNITS_TO_DEVICE (allocation_height));
return priv->cached_layouts[i].layout;
}
@ -392,9 +425,10 @@ clutter_text_create_layout (ClutterText *text,
}
}
CLUTTER_NOTE (ACTOR, "ClutterText: %p: cache miss for width %i",
CLUTTER_NOTE (ACTOR, "ClutterText: %p: cache miss for size %i x %i",
text,
CLUTTER_UNITS_TO_DEVICE (allocation_width));
CLUTTER_UNITS_TO_DEVICE (allocation_width),
CLUTTER_UNITS_TO_DEVICE (allocation_height));
/* If we make it here then we didn't have a cached version so we
need to recreate the layout */
@ -402,13 +436,16 @@ clutter_text_create_layout (ClutterText *text,
g_object_unref (oldest_cache->layout);
oldest_cache->layout =
clutter_text_create_layout_no_cache (text, allocation_width);
clutter_text_create_layout_no_cache (text,
allocation_width,
allocation_height);
cogl_pango_ensure_glyph_cache_for_layout (oldest_cache->layout);
/* Mark the 'time' this cache was created and advance the time */
oldest_cache->age = priv->cache_age++;
oldest_cache->width = allocation_width;
oldest_cache->height = allocation_height;
return oldest_cache->layout;
}
@ -1270,7 +1307,9 @@ clutter_text_paint (ClutterActor *self)
}
clutter_actor_get_allocation_box (self, &alloc);
layout = clutter_text_create_layout (text, alloc.x2 - alloc.x1);
layout = clutter_text_create_layout (text,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
if (priv->editable && priv->cursor_visible)
clutter_text_ensure_cursor_position (text);
@ -1360,7 +1399,7 @@ clutter_text_get_preferred_width (ClutterActor *self,
gint logical_width;
ClutterUnit layout_width;
layout = clutter_text_create_layout (text, -1);
layout = clutter_text_create_layout (text, -1, -1);
pango_layout_get_extents (layout, NULL, &logical_rect);
@ -1409,7 +1448,7 @@ clutter_text_get_preferred_height (ClutterActor *self,
gint logical_height;
ClutterUnit layout_height;
layout = clutter_text_create_layout (text, for_width);
layout = clutter_text_create_layout (text, for_width, -1);
pango_layout_get_extents (layout, NULL, &logical_rect);
@ -1422,7 +1461,12 @@ clutter_text_get_preferred_height (ClutterActor *self,
layout_height = CLUTTER_UNITS_FROM_PANGO_UNIT (logical_height);
if (min_height_p)
*min_height_p = layout_height;
{
if (text->priv->ellipsize)
*min_height_p = -1;
else
*min_height_p = layout_height;
}
if (natural_height_p)
*natural_height_p = layout_height;
@ -1440,7 +1484,9 @@ clutter_text_allocate (ClutterActor *self,
/* Ensure that there is a cached layout with the right width so
* that we don't need to create the text during the paint run
*/
clutter_text_create_layout (text, box->x2 - box->x1);
clutter_text_create_layout (text,
box->x2 - box->x1,
box->y2 - box->y1);
parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
parent_class->allocate (self, box, origin_changed);
@ -3219,13 +3265,13 @@ clutter_text_set_markup (ClutterText *self,
PangoLayout *
clutter_text_get_layout (ClutterText *self)
{
ClutterUnit width;
ClutterUnit width, height;
g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL);
width = clutter_actor_get_widthu (CLUTTER_ACTOR (self));
clutter_actor_get_sizeu (CLUTTER_ACTOR (self), &width, &height);
return clutter_text_create_layout (self, width);
return clutter_text_create_layout (self, width, height);
}
/**