mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
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,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user