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:
commit
425fa78a27
@ -86,9 +86,12 @@ struct _LayoutCache
|
|||||||
*/
|
*/
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
|
|
||||||
/* The width that used to generate this layout */
|
/* The width that was used to generate this layout */
|
||||||
ClutterUnit width;
|
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
|
/* A number representing the age of this cache (so that when a
|
||||||
* new layout is needed the last used cache is replaced)
|
* new layout is needed the last used cache is replaced)
|
||||||
*/
|
*/
|
||||||
@ -237,7 +240,8 @@ clutter_text_clear_selection (ClutterText *self)
|
|||||||
|
|
||||||
static PangoLayout *
|
static PangoLayout *
|
||||||
clutter_text_create_layout_no_cache (ClutterText *text,
|
clutter_text_create_layout_no_cache (ClutterText *text,
|
||||||
ClutterUnit allocation_width)
|
ClutterUnit allocation_width,
|
||||||
|
ClutterUnit allocation_height)
|
||||||
{
|
{
|
||||||
ClutterTextPrivate *priv = text->priv;
|
ClutterTextPrivate *priv = text->priv;
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
@ -281,32 +285,35 @@ clutter_text_create_layout_no_cache (ClutterText *text,
|
|||||||
pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode);
|
pango_layout_set_single_paragraph_mode (layout, priv->single_line_mode);
|
||||||
pango_layout_set_justify (layout, priv->justify);
|
pango_layout_set_justify (layout, priv->justify);
|
||||||
|
|
||||||
if (allocation_width > 0 &&
|
/* Cases, assuming ellipsize != NONE on actor:
|
||||||
(priv->ellipsize != PANGO_ELLIPSIZE_NONE || priv->wrap))
|
*
|
||||||
{
|
* Width request: ellipsization can be set or not on layout,
|
||||||
int layout_width, layout_height;
|
* doesn't matter.
|
||||||
|
*
|
||||||
pango_layout_get_size (layout, &layout_width, &layout_height);
|
* Height request: ellipsization must never be set on layout
|
||||||
|
* if wrap=true, because we need to measure the wrapped
|
||||||
/* no need to set ellipsize or wrap if we already have enough
|
* height. It must always be set if wrap=false.
|
||||||
* space, since we don't want to make the layout wider than it
|
*
|
||||||
* would be otherwise.
|
* Allocate: ellipsization must always be set.
|
||||||
|
*
|
||||||
|
* See http://bugzilla.gnome.org/show_bug.cgi?id=560931
|
||||||
*/
|
*/
|
||||||
|
if (priv->ellipsize != PANGO_ELLIPSIZE_NONE)
|
||||||
if (CLUTTER_UNITS_FROM_PANGO_UNIT (layout_width) > allocation_width)
|
|
||||||
{
|
{
|
||||||
if (!priv->editable && priv->ellipsize != PANGO_ELLIPSIZE_NONE)
|
if (allocation_height < 0 && priv->wrap)
|
||||||
|
; /* must not set ellipsization on wrap=true height request */
|
||||||
|
else
|
||||||
{
|
{
|
||||||
gint width;
|
if (!priv->editable)
|
||||||
|
|
||||||
width = allocation_width > 0
|
|
||||||
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
pango_layout_set_ellipsize (layout, priv->ellipsize);
|
pango_layout_set_ellipsize (layout, priv->ellipsize);
|
||||||
pango_layout_set_width (layout, width);
|
|
||||||
}
|
}
|
||||||
else if (priv->wrap)
|
}
|
||||||
|
|
||||||
|
/* 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;
|
gint width;
|
||||||
|
|
||||||
@ -314,10 +321,30 @@ clutter_text_create_layout_no_cache (ClutterText *text,
|
|||||||
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
|
? CLUTTER_UNITS_TO_PANGO_UNIT (allocation_width)
|
||||||
: -1;
|
: -1;
|
||||||
|
|
||||||
pango_layout_set_wrap (layout, priv->wrap_mode);
|
|
||||||
pango_layout_set_width (layout, width);
|
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;
|
return layout;
|
||||||
@ -350,6 +377,7 @@ clutter_text_font_changed_cb (ClutterText *text)
|
|||||||
* clutter_text_create_layout:
|
* clutter_text_create_layout:
|
||||||
* @text: a #ClutterText
|
* @text: a #ClutterText
|
||||||
* @allocation_width: the allocation width
|
* @allocation_width: the allocation width
|
||||||
|
* @allocation_height: the allocation height
|
||||||
*
|
*
|
||||||
* Like clutter_text_create_layout_no_cache(), but will also ensure
|
* Like clutter_text_create_layout_no_cache(), but will also ensure
|
||||||
* the glyphs cache. If a previously cached layout generated using the
|
* the glyphs cache. If a previously cached layout generated using the
|
||||||
@ -358,15 +386,17 @@ clutter_text_font_changed_cb (ClutterText *text)
|
|||||||
*/
|
*/
|
||||||
static PangoLayout *
|
static PangoLayout *
|
||||||
clutter_text_create_layout (ClutterText *text,
|
clutter_text_create_layout (ClutterText *text,
|
||||||
ClutterUnit allocation_width)
|
ClutterUnit allocation_width,
|
||||||
|
ClutterUnit allocation_height)
|
||||||
{
|
{
|
||||||
ClutterTextPrivate *priv = text->priv;
|
ClutterTextPrivate *priv = text->priv;
|
||||||
LayoutCache *oldest_cache = priv->cached_layouts;
|
LayoutCache *oldest_cache = priv->cached_layouts;
|
||||||
gboolean found_free_cache = FALSE;
|
gboolean found_free_cache = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Search for a cached layout with the same width and keep track of
|
/* Search for a cached layout with the same width and keep
|
||||||
the oldest one */
|
* track of the oldest one
|
||||||
|
*/
|
||||||
for (i = 0; i < N_CACHED_LAYOUTS; i++)
|
for (i = 0; i < N_CACHED_LAYOUTS; i++)
|
||||||
{
|
{
|
||||||
if (priv->cached_layouts[i].layout == NULL)
|
if (priv->cached_layouts[i].layout == NULL)
|
||||||
@ -375,13 +405,16 @@ clutter_text_create_layout (ClutterText *text,
|
|||||||
found_free_cache = TRUE;
|
found_free_cache = TRUE;
|
||||||
oldest_cache = priv->cached_layouts + i;
|
oldest_cache = priv->cached_layouts + i;
|
||||||
}
|
}
|
||||||
/* If this cached layout is using the same width then we can
|
else if (priv->cached_layouts[i].width == allocation_width &&
|
||||||
just return that directly */
|
priv->cached_layouts[i].height == allocation_height)
|
||||||
else if (priv->cached_layouts[i].width == allocation_width)
|
|
||||||
{
|
{
|
||||||
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,
|
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;
|
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,
|
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
|
/* If we make it here then we didn't have a cached version so we
|
||||||
need to recreate the layout */
|
need to recreate the layout */
|
||||||
@ -402,13 +436,16 @@ clutter_text_create_layout (ClutterText *text,
|
|||||||
g_object_unref (oldest_cache->layout);
|
g_object_unref (oldest_cache->layout);
|
||||||
|
|
||||||
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);
|
cogl_pango_ensure_glyph_cache_for_layout (oldest_cache->layout);
|
||||||
|
|
||||||
/* Mark the 'time' this cache was created and advance the time */
|
/* Mark the 'time' this cache was created and advance the time */
|
||||||
oldest_cache->age = priv->cache_age++;
|
oldest_cache->age = priv->cache_age++;
|
||||||
oldest_cache->width = allocation_width;
|
oldest_cache->width = allocation_width;
|
||||||
|
oldest_cache->height = allocation_height;
|
||||||
|
|
||||||
return oldest_cache->layout;
|
return oldest_cache->layout;
|
||||||
}
|
}
|
||||||
@ -1270,7 +1307,9 @@ clutter_text_paint (ClutterActor *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (self, &alloc);
|
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)
|
if (priv->editable && priv->cursor_visible)
|
||||||
clutter_text_ensure_cursor_position (text);
|
clutter_text_ensure_cursor_position (text);
|
||||||
@ -1360,7 +1399,7 @@ clutter_text_get_preferred_width (ClutterActor *self,
|
|||||||
gint logical_width;
|
gint logical_width;
|
||||||
ClutterUnit layout_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);
|
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
@ -1409,7 +1448,7 @@ clutter_text_get_preferred_height (ClutterActor *self,
|
|||||||
gint logical_height;
|
gint logical_height;
|
||||||
ClutterUnit layout_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);
|
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);
|
layout_height = CLUTTER_UNITS_FROM_PANGO_UNIT (logical_height);
|
||||||
|
|
||||||
if (min_height_p)
|
if (min_height_p)
|
||||||
|
{
|
||||||
|
if (text->priv->ellipsize)
|
||||||
|
*min_height_p = -1;
|
||||||
|
else
|
||||||
*min_height_p = layout_height;
|
*min_height_p = layout_height;
|
||||||
|
}
|
||||||
|
|
||||||
if (natural_height_p)
|
if (natural_height_p)
|
||||||
*natural_height_p = layout_height;
|
*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
|
/* 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
|
* 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 = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
|
||||||
parent_class->allocate (self, box, origin_changed);
|
parent_class->allocate (self, box, origin_changed);
|
||||||
@ -3219,13 +3265,13 @@ clutter_text_set_markup (ClutterText *self,
|
|||||||
PangoLayout *
|
PangoLayout *
|
||||||
clutter_text_get_layout (ClutterText *self)
|
clutter_text_get_layout (ClutterText *self)
|
||||||
{
|
{
|
||||||
ClutterUnit width;
|
ClutterUnit width, height;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user