summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2017-09-02 03:57:28 +0200
committerMarco Trevisan <mail@3v1n0.net>2019-03-01 17:46:49 +0000
commitaf3662775eddc32bbc7265b5c176704563e676e9 (patch)
tree3b28d56bb8d99834056180929a4762129dda579c
parent9234777e36212eeb7a676bd2787d5e87bfea6079 (diff)
downloadmutter-af3662775eddc32bbc7265b5c176704563e676e9.tar.gz
clutter/text: Generate resource scaled text and paint it at proper scaling
When resource scale is set we need to generate a scaled PangoLayout (by adding a new scale attribute, or adjusting the one we already have according the resource scale), then it has to be painted with proper scaling matrix. So everything that has to do with PangoLayout has to be in real coordinates, then clutter logical coords multiplied by resource scaling. While the actual size of the layout is the one of the PangoLayout divided by resource scale. We map the text positions to logical coords by default, while using the pixel coordinates when painting. We fall back to scale 1 when calculating preferred size if no scale is known. The pango layout will not have set a layout scale attribute, meaning it'll be 1, thus we should just assume the layout scale is 1 here. Not doing so might result in the preferred size being 0x0 meaning the actor won't be laid out properly. Fixes https://gitlab.gnome.org/GNOME/mutter/issues/135 https://bugzilla.gnome.org/show_bug.cgi?id=765011 https://gitlab.gnome.org/GNOME/mutter/merge_requests/3
-rw-r--r--clutter/clutter/clutter-canvas.c2
-rw-r--r--clutter/clutter/clutter-text.c365
-rw-r--r--clutter/tests/conform/text.c13
3 files changed, 302 insertions, 78 deletions
diff --git a/clutter/clutter/clutter-canvas.c b/clutter/clutter/clutter-canvas.c
index f49442b16..b0f1f080c 100644
--- a/clutter/clutter/clutter-canvas.c
+++ b/clutter/clutter/clutter-canvas.c
@@ -614,7 +614,7 @@ clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
float scale)
{
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
- g_return_if_fail (scale >= 1.0f);
+ g_return_if_fail (scale > 0.0f);
if (canvas->priv->scale_factor != scale)
{
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index 1642c79f6..b6f054863 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -144,15 +144,17 @@ struct _ClutterTextPrivate
*/
gint x_pos;
- /* the x position of the PangoLayout when in
- * single line mode, to scroll the contents of the
+ /* the x position of the PangoLayout (in both physical and logical pixels)
+ * when in single line mode, to scroll the contents of the
* text actor
*/
gint text_x;
+ gint text_logical_x;
- /* the y position of the PangoLayout, fixed to 0 by
- * default for now */
+ /* the y position of the PangoLayout (in both physical and logical pixels),
+ * fixed to 0 by default for now */
gint text_y;
+ gint text_logical_y;
/* Where to draw the cursor */
ClutterRect cursor_rect;
@@ -185,6 +187,9 @@ struct _ClutterTextPrivate
ClutterInputContentHintFlags input_hints;
ClutterInputContentPurpose input_purpose;
+ /* Signal handler for when the :resource-scale changes */
+ guint resource_scale_changed_id;
+
/* bitfields */
guint alignment : 2;
guint wrap : 1;
@@ -290,6 +295,33 @@ G_DECLARE_FINAL_TYPE (ClutterTextInputFocus, clutter_text_input_focus,
G_DEFINE_TYPE (ClutterTextInputFocus, clutter_text_input_focus,
CLUTTER_TYPE_INPUT_FOCUS)
+/* Utilities pango to (logical) pixels functions */
+static float
+pixels_to_pango (float px)
+{
+ return ceilf (px * (float) PANGO_SCALE);
+}
+
+static float
+logical_pixels_to_pango (float px,
+ float scale)
+{
+ return pixels_to_pango (px * scale);
+}
+
+static float
+pango_to_pixels (float size)
+{
+ return ceilf (size / (float) PANGO_SCALE);
+}
+
+static float
+pango_to_logical_pixels (float size,
+ float scale)
+{
+ return pango_to_pixels (size / scale);
+}
+
static void
clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus)
{
@@ -551,6 +583,41 @@ clutter_text_get_display_text (ClutterText *self)
}
static void
+ensure_effective_pango_scale_attribute (ClutterText *self)
+{
+ float resource_scale;
+ ClutterTextPrivate *priv = self->priv;
+
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale) ||
+ resource_scale == 1.0)
+ return;
+
+ if (priv->effective_attrs != NULL)
+ {
+ PangoAttrIterator *iter;
+ PangoAttribute *scale_attrib;
+ PangoAttrList *old_attributes;
+
+ old_attributes = priv->effective_attrs;
+ priv->effective_attrs = pango_attr_list_copy (priv->effective_attrs);
+ pango_attr_list_unref (old_attributes);
+
+ iter = pango_attr_list_get_iterator (priv->effective_attrs);
+ scale_attrib = pango_attr_iterator_get (iter, PANGO_ATTR_SCALE);
+
+ if (scale_attrib != NULL)
+ resource_scale *= ((PangoAttrFloat *) scale_attrib)->value;
+
+ pango_attr_iterator_destroy (iter);
+ }
+ else
+ priv->effective_attrs = pango_attr_list_new ();
+
+ pango_attr_list_change (priv->effective_attrs,
+ pango_attr_scale_new (resource_scale));
+}
+
+static void
set_effective_pango_attributes (ClutterText *self,
PangoAttrList *attributes)
{
@@ -568,6 +635,8 @@ set_effective_pango_attributes (ClutterText *self,
{
g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref);
}
+
+ ensure_effective_pango_scale_attribute (self);
}
static inline void
@@ -836,6 +905,18 @@ clutter_text_direction_changed_cb (GObject *gobject,
/* no need to queue a relayout: set_text_direction() will do that for us */
}
+static void
+clutter_text_resource_scale_changed_cb (GObject *gobject,
+ GParamSpec *pspec)
+{
+ ClutterText *self = CLUTTER_TEXT (gobject);
+ ClutterTextPrivate *priv = self->priv;
+
+ g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref);
+ clutter_text_dirty_cache (self);
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (gobject));
+}
+
/*
* clutter_text_create_layout:
* @text: a #ClutterText
@@ -903,7 +984,7 @@ clutter_text_create_layout (ClutterText *text,
!((priv->editable && priv->single_line_mode) ||
(priv->ellipsize == PANGO_ELLIPSIZE_NONE && !priv->wrap))))
{
- width = allocation_width * 1024 + 0.5f;
+ width = pixels_to_pango (allocation_width);
}
/* Pango only uses height if ellipsization is enabled, so don't set
@@ -920,7 +1001,7 @@ clutter_text_create_layout (ClutterText *text,
priv->ellipsize != PANGO_ELLIPSIZE_NONE &&
!priv->single_line_mode)
{
- height = allocation_height * 1024 + 0.5f;
+ height = pixels_to_pango (allocation_height);
}
/* Search for a cached layout with the same width and keep
@@ -1017,6 +1098,37 @@ clutter_text_create_layout (ClutterText *text,
return oldest_cache->layout;
}
+static PangoLayout *
+create_text_layout_with_scale (ClutterText *text,
+ gfloat allocation_width,
+ gfloat allocation_height,
+ gfloat scale)
+{
+ if (allocation_width > 0)
+ allocation_width = roundf (allocation_width * scale);
+
+ if (allocation_height > 0)
+ allocation_height = roundf (allocation_height * scale);
+
+ return clutter_text_create_layout (text, allocation_width, allocation_height);
+}
+
+static PangoLayout *
+maybe_create_text_layout_with_resource_scale (ClutterText *text,
+ gfloat allocation_width,
+ gfloat allocation_height)
+{
+ float resource_scale;
+
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (text), &resource_scale))
+ return NULL;
+
+ return create_text_layout_with_scale (text,
+ allocation_width,
+ allocation_height,
+ resource_scale);
+}
+
/**
* clutter_text_coords_to_position:
* @self: a #ClutterText
@@ -1037,14 +1149,18 @@ clutter_text_coords_to_position (ClutterText *self,
gint index_;
gint px, py;
gint trailing;
+ gfloat resource_scale;
g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0);
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale))
+ return 0;
+
/* Take any offset due to scrolling into account, and normalize
* the coordinates to PangoScale units
*/
- px = (x - self->priv->text_x) * PANGO_SCALE;
- py = (y - self->priv->text_y) * PANGO_SCALE;
+ px = logical_pixels_to_pango (x - self->priv->text_logical_x, resource_scale);
+ py = logical_pixels_to_pango (y - self->priv->text_logical_y, resource_scale);
pango_layout_xy_to_index (clutter_text_get_layout (self),
px, py,
@@ -1053,26 +1169,12 @@ clutter_text_coords_to_position (ClutterText *self,
return index_ + trailing;
}
-/**
- * clutter_text_position_to_coords:
- * @self: a #ClutterText
- * @position: position in characters
- * @x: (out): return location for the X coordinate, or %NULL
- * @y: (out): return location for the Y coordinate, or %NULL
- * @line_height: (out): return location for the line height, or %NULL
- *
- * Retrieves the coordinates of the given @position.
- *
- * Return value: %TRUE if the conversion was successful
- *
- * Since: 1.0
- */
-gboolean
-clutter_text_position_to_coords (ClutterText *self,
- gint position,
- gfloat *x,
- gfloat *y,
- gfloat *line_height)
+static gboolean
+clutter_text_position_to_coords_internal (ClutterText *self,
+ gint position,
+ gfloat *x,
+ gfloat *y,
+ gfloat *line_height)
{
ClutterTextPrivate *priv;
PangoRectangle rect;
@@ -1138,7 +1240,7 @@ clutter_text_position_to_coords (ClutterText *self,
if (x)
{
- *x = (gfloat) rect.x / 1024.0f;
+ *x = pango_to_pixels (rect.x);
/* Take any offset due to scrolling into account */
if (priv->single_line_mode)
@@ -1146,14 +1248,58 @@ clutter_text_position_to_coords (ClutterText *self,
}
if (y)
- *y = (gfloat) rect.y / 1024.0f;
+ *y = pango_to_pixels (rect.y);
if (line_height)
- *line_height = (gfloat) rect.height / 1024.0f;
+ *line_height = pango_to_pixels (rect.height);
return TRUE;
}
+/**
+ * clutter_text_position_to_coords:
+ * @self: a #ClutterText
+ * @position: position in characters
+ * @x: (out): return location for the X coordinate, or %NULL
+ * @y: (out): return location for the Y coordinate, or %NULL
+ * @line_height: (out): return location for the line height, or %NULL
+ *
+ * Retrieves the coordinates of the given @position.
+ *
+ * Return value: %TRUE if the conversion was successful
+ *
+ * Since: 1.0
+ */
+gboolean
+clutter_text_position_to_coords (ClutterText *self,
+ gint position,
+ gfloat *x,
+ gfloat *y,
+ gfloat *line_height)
+{
+ gfloat resource_scale;
+ gboolean ret;
+
+ g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE);
+
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale))
+ return FALSE;
+
+ ret = clutter_text_position_to_coords_internal (self, position,
+ x, y, line_height);
+
+ if (x)
+ *x /= resource_scale;
+
+ if (y)
+ *y /= resource_scale;
+
+ if (line_height)
+ *line_height /= resource_scale;
+
+ return ret;
+}
+
static inline void
update_cursor_location (ClutterText *self)
{
@@ -1171,7 +1317,8 @@ update_cursor_location (ClutterText *self)
}
static inline void
-clutter_text_ensure_cursor_position (ClutterText *self)
+clutter_text_ensure_cursor_position (ClutterText *self,
+ float scale)
{
ClutterTextPrivate *priv = self->priv;
gfloat x, y, cursor_height;
@@ -1194,15 +1341,15 @@ clutter_text_ensure_cursor_position (ClutterText *self)
priv->preedit_set ? priv->preedit_cursor_pos : 0);
x = y = cursor_height = 0;
- clutter_text_position_to_coords (self, position,
- &x, &y,
- &cursor_height);
+ clutter_text_position_to_coords_internal (self, position,
+ &x, &y,
+ &cursor_height);
clutter_rect_init (&cursor_rect,
x,
- y + CURSOR_Y_PADDING,
- priv->cursor_size,
- cursor_height - 2 * CURSOR_Y_PADDING);
+ y + CURSOR_Y_PADDING * scale,
+ priv->cursor_size * scale,
+ cursor_height - 2 * CURSOR_Y_PADDING * scale);
if (!clutter_rect_equals (&priv->cursor_rect, &cursor_rect))
{
@@ -1625,6 +1772,12 @@ clutter_text_dispose (GObject *gobject)
priv->direction_changed_id = 0;
}
+ if (priv->resource_scale_changed_id)
+ {
+ g_signal_handler_disconnect (self, priv->resource_scale_changed_id);
+ priv->resource_scale_changed_id = 0;
+ }
+
if (priv->settings_changed_id)
{
g_signal_handler_disconnect (clutter_get_default_backend (),
@@ -1677,6 +1830,7 @@ typedef void (* ClutterTextSelectionFunc) (ClutterText *text,
static void
clutter_text_foreach_selection_rectangle (ClutterText *self,
+ float scale,
ClutterTextSelectionFunc func,
gpointer user_data)
{
@@ -1728,9 +1882,9 @@ clutter_text_foreach_selection_rectangle (ClutterText *self,
&n_ranges);
pango_layout_line_x_to_index (line, 0, &index_, NULL);
- clutter_text_position_to_coords (self,
- bytes_to_offset (utf8, index_),
- NULL, &y, &height);
+ clutter_text_position_to_coords_internal (self,
+ bytes_to_offset (utf8, index_),
+ NULL, &y, &height);
box.y1 = y;
box.y2 = y + height;
@@ -1740,18 +1894,18 @@ clutter_text_foreach_selection_rectangle (ClutterText *self,
gfloat range_x;
gfloat range_width;
- range_x = ranges[i * 2] / PANGO_SCALE;
+ range_x = pango_to_pixels (ranges[i * 2]);
/* Account for any scrolling in single line mode */
if (priv->single_line_mode)
range_x += priv->text_x;
- range_width = ((gfloat) ranges[i * 2 + 1] - (gfloat) ranges[i * 2])
- / PANGO_SCALE;
-
+ range_width = pango_to_pixels (ranges[i * 2 + 1] - ranges[i * 2]);
box.x1 = range_x;
- box.x2 = ceilf (range_x + range_width + .5f);
+ box.x2 = ceilf (range_x + range_width);
+
+ clutter_actor_box_scale (&box, scale);
func (self, &box, user_data);
}
@@ -1770,6 +1924,14 @@ add_selection_rectangle_to_path (ClutterText *text,
cogl_path_rectangle (user_data, box->x1, box->y1, box->x2, box->y2);
}
+static void
+clutter_text_foreach_selection_rectangle_prescaled (ClutterText *self,
+ ClutterTextSelectionFunc func,
+ gpointer user_data)
+{
+ clutter_text_foreach_selection_rectangle (self, 1.0f, func, user_data);
+}
+
/* Draws the selected text, its background, and the cursor */
static void
selection_paint (ClutterText *self,
@@ -1825,9 +1987,9 @@ selection_paint (ClutterText *self,
else
color = &priv->text_color;
- clutter_text_foreach_selection_rectangle (self,
- add_selection_rectangle_to_path,
- selection_path);
+ clutter_text_foreach_selection_rectangle_prescaled (self,
+ add_selection_rectangle_to_path,
+ selection_path);
cogl_path_fill (selection_path);
@@ -2416,6 +2578,7 @@ clutter_text_paint (ClutterActor *self)
guint n_chars;
float alloc_width;
float alloc_height;
+ float resource_scale;
fb = cogl_get_draw_framebuffer ();
@@ -2425,8 +2588,6 @@ clutter_text_paint (ClutterActor *self)
n_chars = clutter_text_buffer_get_length (get_buffer (text));
clutter_actor_get_allocation_box (self, &alloc);
- alloc_width = alloc.x2 - alloc.x1;
- alloc_height = alloc.y2 - alloc.y1;
if (G_UNLIKELY (default_color_pipeline == NULL))
{
@@ -2459,7 +2620,8 @@ clutter_text_paint (ClutterActor *self)
cogl_framebuffer_draw_rectangle (fb,
color_pipeline,
0, 0,
- alloc_width, alloc_height);
+ clutter_actor_box_get_width (&alloc),
+ clutter_actor_box_get_height (&alloc));
cogl_object_unref (color_pipeline);
}
@@ -2472,6 +2634,12 @@ clutter_text_paint (ClutterActor *self)
!clutter_text_should_draw_cursor (text))
return;
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale))
+ return;
+
+ clutter_actor_box_scale (&alloc, resource_scale);
+ clutter_actor_box_get_size (&alloc, &alloc_width, &alloc_height);
+
if (priv->editable && priv->single_line_mode)
layout = clutter_text_create_layout (text, -1, -1);
else
@@ -2503,8 +2671,15 @@ clutter_text_paint (ClutterActor *self)
}
}
+ if (resource_scale != 1.0f)
+ {
+ float paint_scale = 1.0f / resource_scale;
+ cogl_framebuffer_push_matrix (fb);
+ cogl_framebuffer_scale (fb, paint_scale, paint_scale, 1.0f);
+ }
+
if (clutter_text_should_draw_cursor (text))
- clutter_text_ensure_cursor_position (text);
+ clutter_text_ensure_cursor_position (text, resource_scale);
if (priv->editable && priv->single_line_mode)
{
@@ -2518,7 +2693,7 @@ clutter_text_paint (ClutterActor *self)
clip_set = TRUE;
actor_width = alloc_width - 2 * TEXT_PADDING;
- text_width = logical_rect.width / PANGO_SCALE;
+ text_width = pango_to_pixels (logical_rect.width);
rtl = priv->resolved_direction == PANGO_DIRECTION_RTL;
@@ -2575,8 +2750,10 @@ clutter_text_paint (ClutterActor *self)
{
priv->text_x = text_x;
priv->text_y = text_y;
+ priv->text_logical_x = roundf ((float) text_x / resource_scale);
+ priv->text_logical_y = roundf ((float) text_y / resource_scale);
- clutter_text_ensure_cursor_position (text);
+ clutter_text_ensure_cursor_position (text, resource_scale);
}
real_opacity = clutter_actor_get_paint_opacity (self)
@@ -2595,6 +2772,9 @@ clutter_text_paint (ClutterActor *self)
selection_paint (text, fb);
+ if (resource_scale != 1.0f)
+ cogl_framebuffer_pop_matrix (fb);
+
if (clip_set)
cogl_framebuffer_pop_clip (fb);
}
@@ -2624,26 +2804,32 @@ add_selection_to_paint_volume (ClutterText *text,
static void
clutter_text_get_paint_volume_for_cursor (ClutterText *text,
+ float resource_scale,
ClutterPaintVolume *volume)
{
ClutterTextPrivate *priv = text->priv;
ClutterVertex origin;
- clutter_text_ensure_cursor_position (text);
+ clutter_text_ensure_cursor_position (text, resource_scale);
if (priv->position == priv->selection_bound)
{
- origin.x = priv->cursor_rect.origin.x;
- origin.y = priv->cursor_rect.origin.y;
+ float width, height;
+
+ width = priv->cursor_rect.size.width / resource_scale;
+ height = priv->cursor_rect.size.height / resource_scale;
+ origin.x = priv->cursor_rect.origin.x / resource_scale;
+ origin.y = priv->cursor_rect.origin.y / resource_scale;
origin.z = 0;
clutter_paint_volume_set_origin (volume, &origin);
- clutter_paint_volume_set_width (volume, priv->cursor_rect.size.width);
- clutter_paint_volume_set_height (volume, priv->cursor_rect.size.height);
+ clutter_paint_volume_set_width (volume, width);
+ clutter_paint_volume_set_height (volume, height);
}
else
{
clutter_text_foreach_selection_rectangle (text,
+ 1.0f / resource_scale,
add_selection_to_paint_volume,
volume);
}
@@ -2666,6 +2852,7 @@ clutter_text_get_paint_volume (ClutterActor *self,
PangoLayout *layout;
PangoRectangle ink_rect;
ClutterVertex origin;
+ float resource_scale;
/* If the text is single line editable then it gets clipped to
the allocation anyway so we can just use that */
@@ -2680,19 +2867,24 @@ clutter_text_get_paint_volume (ClutterActor *self,
if (!clutter_actor_has_allocation (self))
return FALSE;
+ if (!clutter_actor_get_resource_scale (self, &resource_scale))
+ return FALSE;
+
_clutter_paint_volume_init_static (&priv->paint_volume, self);
layout = clutter_text_get_layout (text);
pango_layout_get_extents (layout, &ink_rect, NULL);
- origin.x = ink_rect.x / (float) PANGO_SCALE;
- origin.y = ink_rect.y / (float) PANGO_SCALE;
+ origin.x = pango_to_logical_pixels (ink_rect.x, resource_scale);
+ origin.y = pango_to_logical_pixels (ink_rect.y, resource_scale);
origin.z = 0;
clutter_paint_volume_set_origin (&priv->paint_volume, &origin);
clutter_paint_volume_set_width (&priv->paint_volume,
- ink_rect.width / (float) PANGO_SCALE);
+ pango_to_logical_pixels (ink_rect.width,
+ resource_scale));
clutter_paint_volume_set_height (&priv->paint_volume,
- ink_rect.height / (float) PANGO_SCALE);
+ pango_to_logical_pixels (ink_rect.height,
+ resource_scale));
/* If the cursor is visible then that will likely be drawn
outside of the ink rectangle so we should merge that in */
@@ -2702,7 +2894,8 @@ clutter_text_get_paint_volume (ClutterActor *self,
_clutter_paint_volume_init_static (&cursor_paint_volume, self);
- clutter_text_get_paint_volume_for_cursor (text, &cursor_paint_volume);
+ clutter_text_get_paint_volume_for_cursor (text, resource_scale,
+ &cursor_paint_volume);
clutter_paint_volume_union (&priv->paint_volume,
&cursor_paint_volume);
@@ -2730,9 +2923,12 @@ clutter_text_get_preferred_width (ClutterActor *self,
PangoLayout *layout;
gint logical_width;
gfloat layout_width;
+ gfloat resource_scale;
- layout = clutter_text_create_layout (text, -1, -1);
+ if (!clutter_actor_get_resource_scale (self, &resource_scale))
+ resource_scale = 1;
+ layout = clutter_text_create_layout (text, -1, -1);
pango_layout_get_extents (layout, NULL, &logical_rect);
/* the X coordinate of the logical rectangle might be non-zero
@@ -2742,7 +2938,7 @@ clutter_text_get_preferred_width (ClutterActor *self,
logical_width = logical_rect.x + logical_rect.width;
layout_width = logical_width > 0
- ? ceilf (logical_width / 1024.0f)
+ ? pango_to_logical_pixels (logical_width, resource_scale)
: 1;
if (min_width_p)
@@ -2784,12 +2980,16 @@ clutter_text_get_preferred_height (ClutterActor *self,
PangoRectangle logical_rect = { 0, };
gint logical_height;
gfloat layout_height;
+ gfloat resource_scale;
+
+ if (!clutter_actor_get_resource_scale (self, &resource_scale))
+ resource_scale = 1;
if (priv->single_line_mode)
for_width = -1;
- layout = clutter_text_create_layout (CLUTTER_TEXT (self),
- for_width, -1);
+ layout = create_text_layout_with_scale (CLUTTER_TEXT (self),
+ for_width, -1, resource_scale);
pango_layout_get_extents (layout, NULL, &logical_rect);
@@ -2798,7 +2998,7 @@ clutter_text_get_preferred_height (ClutterActor *self,
* the height accordingly
*/
logical_height = logical_rect.y + logical_rect.height;
- layout_height = ceilf (logical_height / 1024.0f);
+ layout_height = pango_to_logical_pixels (logical_height, resource_scale);
if (min_height_p)
{
@@ -2814,7 +3014,8 @@ clutter_text_get_preferred_height (ClutterActor *self,
pango_layout_line_get_extents (line, NULL, &logical_rect);
logical_height = logical_rect.y + logical_rect.height;
- line_height = ceilf (logical_height / 1024.0f);
+ line_height = pango_to_logical_pixels (logical_height,
+ resource_scale);
*min_height_p = line_height;
}
@@ -2845,9 +3046,9 @@ clutter_text_allocate (ClutterActor *self,
if (text->priv->editable && text->priv->single_line_mode)
clutter_text_create_layout (text, -1, -1);
else
- clutter_text_create_layout (text,
- box->x2 - box->x1,
- box->y2 - box->y1);
+ maybe_create_text_layout_with_resource_scale (text,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
parent_class->allocate (self, box, flags);
@@ -4418,6 +4619,11 @@ clutter_text_init (ClutterText *self)
NULL);
priv->input_focus = clutter_text_input_focus_new (self);
+
+ priv->resource_scale_changed_id =
+ g_signal_connect (self, "notify::resource-scale",
+ G_CALLBACK (clutter_text_resource_scale_changed_cb),
+ NULL);
}
/**
@@ -5528,6 +5734,7 @@ clutter_text_set_markup (ClutterText *self,
PangoLayout *
clutter_text_get_layout (ClutterText *self)
{
+ PangoLayout *layout;
gfloat width, height;
g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL);
@@ -5536,8 +5743,12 @@ clutter_text_get_layout (ClutterText *self)
return clutter_text_create_layout (self, -1, -1);
clutter_actor_get_size (CLUTTER_ACTOR (self), &width, &height);
+ layout = maybe_create_text_layout_with_resource_scale (self, width, height);
- return clutter_text_create_layout (self, width, height);
+ if (!layout)
+ layout = clutter_text_create_layout (self, width, height);
+
+ return layout;
}
/**
@@ -6541,10 +6752,10 @@ clutter_text_get_layout_offsets (ClutterText *self,
priv = self->priv;
if (x != NULL)
- *x = priv->text_x;
+ *x = priv->text_logical_x;
if (y != NULL)
- *y = priv->text_y;
+ *y = priv->text_logical_y;
}
/**
diff --git a/clutter/tests/conform/text.c b/clutter/tests/conform/text.c
index 30101ce34..cef99023e 100644
--- a/clutter/tests/conform/text.c
+++ b/clutter/tests/conform/text.c
@@ -468,6 +468,19 @@ validate_markup_attributes (ClutterText *text,
a = attributes->data;
+ if (a->klass->type == PANGO_ATTR_SCALE)
+ {
+ PangoAttrFloat *scale = (PangoAttrFloat*) a;
+ float resource_scale;
+
+ if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (text), &resource_scale))
+ resource_scale = 1.0;
+
+ g_assert_cmpfloat (scale->value, ==, resource_scale);
+ g_slist_free_full (attributes, (GDestroyNotify) pango_attribute_destroy);
+ continue;
+ }
+
g_assert (a->klass->type == attr_type);
g_assert_cmpint (a->start_index, ==, start_index);
g_assert_cmpint (a->end_index, ==, end_index);