summaryrefslogtreecommitdiff
path: root/clutter/clutter/clutter-text.c
diff options
context:
space:
mode:
Diffstat (limited to 'clutter/clutter/clutter-text.c')
-rw-r--r--clutter/clutter/clutter-text.c179
1 files changed, 116 insertions, 63 deletions
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index d8c7f2875..4e480fecf 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -1746,7 +1746,8 @@ add_selection_rectangle_to_path (ClutterText *text,
/* Draws the selected text, its background, and the cursor */
static void
-selection_paint (ClutterText *self)
+paint_selection (ClutterText *self,
+ ClutterPaintNode *node)
{
ClutterTextPrivate *priv = self->priv;
ClutterActor *actor = CLUTTER_ACTOR (self);
@@ -1758,33 +1759,59 @@ selection_paint (ClutterText *self)
if (priv->position == priv->selection_bound)
{
+ g_autoptr(ClutterPaintNode) cursor_node = NULL;
+
/* No selection, just draw the cursor */
if (priv->cursor_color_set)
color = &priv->cursor_color;
else
color = &priv->text_color;
- cogl_set_source_color4ub (color->red,
- color->green,
- color->blue,
- paint_opacity * color->alpha / 255);
-
- cogl_rectangle (priv->cursor_rect.origin.x,
- priv->cursor_rect.origin.y,
- priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
- priv->cursor_rect.origin.y + priv->cursor_rect.size.height);
+ cursor_node = clutter_color_node_new (&(ClutterColor) {
+ color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255,
+ });
+ clutter_paint_node_set_name (cursor_node, "ClutterText.selection-background");
+ clutter_paint_node_add_child (node, cursor_node);
+
+ clutter_paint_node_add_rectangle (cursor_node,
+ &(ClutterActorBox) {
+ priv->cursor_rect.origin.x,
+ priv->cursor_rect.origin.y,
+ priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
+ priv->cursor_rect.origin.y + priv->cursor_rect.size.height
+ });
}
else
{
/* Paint selection background first */
+ g_autoptr(ClutterPaintNode) selection_background_node = NULL;
+ g_autoptr(ClutterPaintNode) selection_text_node = NULL;
+ g_autoptr(ClutterPaintNode) selection_clip_node = NULL;
PangoLayout *layout = clutter_text_get_layout (self);
+ ClutterActorBox alloc = { 0, };
CoglPath *selection_path = cogl_path_new ();
- CoglColor cogl_color = { 0, };
- CoglFramebuffer *fb;
- fb = cogl_get_draw_framebuffer ();
- if (G_UNLIKELY (fb == NULL))
- return;
+ clutter_text_foreach_selection_rectangle (self,
+ add_selection_rectangle_to_path,
+ selection_path);
+
+ /* Clip against both the actor allocation - we don't want to draw
+ * the selection rectangle outside the actor - and the selection
+ * path - we don't want to render the text over the unselected
+ * text either.
+ */
+ selection_clip_node = clutter_clip_node_new ();
+ clutter_paint_node_set_name (selection_clip_node, "ClutterText.clip-selection");
+ clutter_paint_node_add_child (node, selection_clip_node);
+
+ clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &alloc);
+ clutter_actor_box_set_origin (&alloc, 0, 0);
+
+ clutter_paint_node_add_rectangle (selection_clip_node, &alloc);
+ clutter_paint_node_add_path (selection_clip_node, selection_path);
/* Paint selection background */
if (priv->selection_color_set)
@@ -1794,35 +1821,40 @@ selection_paint (ClutterText *self)
else
color = &priv->text_color;
- cogl_set_source_color4ub (color->red,
- color->green,
- color->blue,
- paint_opacity * color->alpha / 255);
+ selection_background_node = clutter_color_node_new (&(ClutterColor) {
+ color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255,
+ });
+ clutter_paint_node_set_name (selection_background_node, "ClutterText.selection-background");
+ clutter_paint_node_add_child (selection_clip_node, selection_background_node);
- clutter_text_foreach_selection_rectangle (self,
- add_selection_rectangle_to_path,
- selection_path);
-
- cogl_path_fill (selection_path);
+ clutter_paint_node_add_path (selection_background_node, selection_path);
/* Paint selected text */
- cogl_framebuffer_push_path_clip (fb, selection_path);
- cogl_object_unref (selection_path);
-
if (priv->selected_text_color_set)
color = &priv->selected_text_color;
else
color = &priv->text_color;
- cogl_color_init_from_4ub (&cogl_color,
- color->red,
- color->green,
- color->blue,
- paint_opacity * color->alpha / 255);
+ selection_text_node = clutter_text_node_new (layout,
+ &(ClutterColor) {
+ color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255,
+ });
+
+ clutter_paint_node_set_name (selection_text_node, "ClutterText.selection-text");
+ clutter_paint_node_add_child (selection_clip_node, selection_text_node);
- cogl_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0);
+ clutter_paint_node_add_texture_rectangle (selection_text_node,
+ &alloc,
+ priv->text_x, priv->text_y,
+ 1, 1);
- cogl_framebuffer_pop_clip (fb);
+ cogl_object_unref (selection_path);
}
}
@@ -2373,26 +2405,43 @@ clutter_text_compute_layout_offsets (ClutterText *self,
#define TEXT_PADDING 2
+static inline ClutterPaintNode *
+create_clip_node (ClutterPaintNode *node,
+ float width,
+ float height)
+{
+ g_autoptr(ClutterPaintNode) clip_node = NULL;
+
+ clip_node = clutter_clip_node_new ();
+ clutter_paint_node_set_name (clip_node, "ClutterText.clip");
+ clutter_paint_node_add_child (node, clip_node);
+
+ clutter_paint_node_add_rectangle (clip_node,
+ &(ClutterActorBox) {
+ 0, 0,
+ width, height,
+ });
+
+ return g_steal_pointer (&clip_node);
+}
+
static void
-clutter_text_paint (ClutterActor *self)
+clutter_text_paint_node (ClutterActor *self,
+ ClutterPaintNode *node)
{
+ g_autoptr(ClutterPaintNode) text_node = NULL;
ClutterText *text = CLUTTER_TEXT (self);
ClutterTextPrivate *priv = text->priv;
- CoglFramebuffer *fb;
PangoLayout *layout;
ClutterActorBox alloc = { 0, };
- CoglColor color = { 0, };
guint8 real_opacity;
gint text_x = priv->text_x;
gint text_y = priv->text_y;
- gboolean clip_set = FALSE;
gboolean bg_color_set = FALSE;
guint n_chars;
float alloc_width;
float alloc_height;
- fb = cogl_get_draw_framebuffer ();
-
/* Note that if anything in this paint method changes it needs to be
reflected in the get_paint_volume implementation which is tightly
tied to the workings of this function */
@@ -2405,6 +2454,7 @@ clutter_text_paint (ClutterActor *self)
g_object_get (self, "background-color-set", &bg_color_set, NULL);
if (bg_color_set)
{
+ g_autoptr(ClutterPaintNode) background_color_node = NULL;
ClutterColor bg_color;
clutter_actor_get_background_color (self, &bg_color);
@@ -2412,11 +2462,11 @@ clutter_text_paint (ClutterActor *self)
* bg_color.alpha
/ 255;
- cogl_set_source_color4ub (bg_color.red,
- bg_color.green,
- bg_color.blue,
- bg_color.alpha);
- cogl_rectangle (0, 0, alloc_width, alloc_height);
+ background_color_node = clutter_color_node_new (&bg_color);
+ clutter_paint_node_set_name (background_color_node, "ClutterText.background-color");
+ clutter_paint_node_add_child (node, background_color_node);
+
+ clutter_paint_node_add_rectangle (background_color_node, &alloc);
}
/* don't bother painting an empty text actor, unless it's
@@ -2469,8 +2519,7 @@ clutter_text_paint (ClutterActor *self)
pango_layout_get_extents (layout, NULL, &logical_rect);
- cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height);
- clip_set = TRUE;
+ node = create_clip_node (node, alloc_width, alloc_height);
actor_width = alloc_width - 2 * TEXT_PADDING;
text_width = logical_rect.width / PANGO_SCALE;
@@ -2513,12 +2562,8 @@ clutter_text_paint (ClutterActor *self)
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
/* don't clip if the layout managed to fit inside our allocation */
- if (logical_rect.width > alloc_width ||
- logical_rect.height > alloc_height)
- {
- cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height);
- clip_set = TRUE;
- }
+ if (logical_rect.width > alloc_width || logical_rect.height > alloc_height)
+ node = create_clip_node (node, alloc_width, alloc_height);
clutter_text_compute_layout_offsets (text, layout, &alloc, &text_x, &text_y);
}
@@ -2541,17 +2586,25 @@ clutter_text_paint (ClutterActor *self)
CLUTTER_NOTE (PAINT, "painting text (text: '%s')",
clutter_text_buffer_get_text (get_buffer (text)));
- cogl_color_init_from_4ub (&color,
- priv->text_color.red,
- priv->text_color.green,
- priv->text_color.blue,
- real_opacity);
- cogl_pango_render_layout (layout, priv->text_x, priv->text_y, &color, 0);
+ text_node = clutter_text_node_new (layout,
+ &(ClutterColor) {
+ priv->text_color.red,
+ priv->text_color.green,
+ priv->text_color.blue,
+ real_opacity
+ });
+
+ clutter_paint_node_set_name (text_node, "ClutterText.text");
+ clutter_paint_node_add_child (node, text_node);
- selection_paint (text);
+ clutter_actor_box_set_origin (&alloc, 0, 0);
+ clutter_paint_node_add_texture_rectangle (text_node,
+ &alloc,
+ priv->text_x,
+ priv->text_y,
+ 1, 1);
- if (clip_set)
- cogl_framebuffer_pop_clip (fb);
+ paint_selection (text, node);
}
static void
@@ -3548,7 +3601,7 @@ clutter_text_class_init (ClutterTextClass *klass)
gobject_class->dispose = clutter_text_dispose;
gobject_class->finalize = clutter_text_finalize;
- actor_class->paint = clutter_text_paint;
+ actor_class->paint_node = clutter_text_paint_node;
actor_class->get_paint_volume = clutter_text_get_paint_volume;
actor_class->get_preferred_width = clutter_text_get_preferred_width;
actor_class->get_preferred_height = clutter_text_get_preferred_height;