From f90523288d1f4abf40664e851bf595bb42b7ca8a Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 19 Feb 2009 14:33:41 -0500 Subject: [PATCH] Port BigBox to Clutter-0.9 - include only - cogl_rectangle() takes x1/y1/x2/y2 instead of x/y/width/height - cogl_color() renamed to cogl_set_source_color4ub() - use explicit CoglMaterial in BigRectangle to combine a texture and a color. - Remove defensive calls to cogl_enable(0) - cogl_enable() no longer exists (enable flags are part of the material) - Use ClutterCairoTexture actor (from Clutter) rather than ClutterCairo --- src/big/box.c | 33 +++----- src/big/rectangle.c | 171 ++++++++++++++++++++++++++---------------- src/big/theme-image.c | 14 ++-- 3 files changed, 124 insertions(+), 94 deletions(-) diff --git a/src/big/box.c b/src/big/box.c index 8587a3614..9aad7ce68 100644 --- a/src/big/box.c +++ b/src/big/box.c @@ -22,9 +22,7 @@ #include -#include -#include -#include +#include #include #include @@ -2196,7 +2194,6 @@ big_box_paint (ClutterActor *actor) ClutterColor color; guint8 actor_opacity; ClutterGeometry allocation; - ClutterGeometry bg_rect; int border_top, border_bottom, border_left, border_right; int padding_top, padding_bottom, padding_left, padding_right; @@ -2217,8 +2214,6 @@ big_box_paint (ClutterActor *actor) */ clutter_actor_get_allocation_geometry (actor, &allocation); - cogl_enable(0); /* defeat cogl GL cache in case GL used directly */ - cogl_push_matrix (); /* Background */ @@ -2226,11 +2221,6 @@ big_box_paint (ClutterActor *actor) color = self->priv->background_color; color.alpha = (color.alpha * actor_opacity) / 0xff; - bg_rect.x = border_left; - bg_rect.y = border_top; - bg_rect.width = allocation.width - border_left - border_right; - bg_rect.height = allocation.height - border_top - border_bottom; - /* Border */ if (self->priv->draw_rounded_corner) @@ -2245,8 +2235,11 @@ big_box_paint (ClutterActor *actor) { if (color.alpha != 0) { - cogl_color (&color); - cogl_rectangle (bg_rect.x, bg_rect.y, bg_rect.width, bg_rect.height); + cogl_set_source_color4ub (color.red, color.green, color.blue, color.alpha); + + cogl_rectangle (border_left, border_top, + allocation.width - border_left, + allocation.height - border_bottom); } color = self->priv->border_color; @@ -2254,7 +2247,7 @@ big_box_paint (ClutterActor *actor) if (color.alpha != 0) { - cogl_color (&color); + cogl_set_source_color4ub (color.red, color.green, color.blue, color.alpha); /* top */ cogl_rectangle (0, 0, @@ -2264,27 +2257,24 @@ big_box_paint (ClutterActor *actor) /* left */ cogl_rectangle (0, border_top, border_left, - allocation.height - border_top - border_bottom); + allocation.height - border_top); /* right */ cogl_rectangle (allocation.width - border_right, border_top, - border_right, - allocation.height - border_top - border_bottom); + allocation.width, + allocation.height - border_top); /* bottom */ cogl_rectangle (0, allocation.height - border_bottom, allocation.width, - border_bottom); + allocation.height); } } - cogl_enable(0); /* defeat cogl GL cache in case GL used directly */ - if (self->priv->background_texture && CLUTTER_ACTOR_IS_VISIBLE(self->priv->background_texture)) { clutter_actor_paint (CLUTTER_ACTOR (self->priv->background_texture)); - cogl_enable(0); /* defeat cogl GL cache in case GL used directly */ } /* Children */ @@ -2299,7 +2289,6 @@ big_box_paint (ClutterActor *actor) if (BOX_CHILD_IS_VISIBLE (child)) { clutter_actor_paint (child->actor); - cogl_enable(0); /* defeat cogl GL cache in case GL used directly */ } } diff --git a/src/big/rectangle.c b/src/big/rectangle.c index db848dece..fd5d1dadd 100644 --- a/src/big/rectangle.c +++ b/src/big/rectangle.c @@ -45,6 +45,9 @@ struct BigRectangle { ClutterRectangle parent_instance; ClutterUnit radius; Corner *corner; + CoglHandle corner_material; + CoglHandle border_material; + CoglHandle background_material; gboolean corners_dirty; }; @@ -299,6 +302,14 @@ big_rectangle_update_corners(BigRectangle *rectangle) rectangle->corner = corner; + if (corner) { + if (!rectangle->corner_material) + rectangle->corner_material = cogl_material_new(); + + cogl_material_set_layer (rectangle->corner_material, 0, + rectangle->corner->texture); + } + rectangle->corners_dirty = FALSE; } @@ -308,14 +319,14 @@ big_rectangle_paint(ClutterActor *actor) BigRectangle *rectangle; ClutterColor *color; ClutterColor *border_color; + guint8 actor_opacity; + CoglColor tmp_color; guint border_width; ClutterActorBox box; - ClutterFixed radiusx; - ClutterFixed widthx; - ClutterFixed heightx; - ClutterFixed border_widthx; - ClutterFixed max; - ClutterColor tmp_col; + float radius; + float width; + float height; + float max; rectangle = BIG_RECTANGLE(actor); @@ -335,97 +346,113 @@ big_rectangle_paint(ClutterActor *actor) "color", &color, NULL); + actor_opacity = clutter_actor_get_paint_opacity (actor); + clutter_actor_get_allocation_box(actor, &box); /* translation was already done */ box.x2 -= box.x1; box.y2 -= box.y1; - widthx = CLUTTER_UNITS_TO_FIXED(box.x2); - heightx = CLUTTER_UNITS_TO_FIXED(box.y2); + width = box.x2; + height = box.y2; - radiusx = CLUTTER_UNITS_TO_FIXED(rectangle->radius); + radius = rectangle->radius; - border_widthx = CLUTTER_INT_TO_FIXED(border_width); - max = MAX(border_widthx, radiusx); + max = MAX(border_width, radius); - if (radiusx != 0) { - tmp_col.red = 0xFF; - tmp_col.blue = 0xFF; - tmp_col.green = 0xFF; - tmp_col.alpha = clutter_actor_get_paint_opacity(actor); - - cogl_color(&tmp_col); + if (radius != 0) { + cogl_color_set_from_4ub(&tmp_color, + 0xff, 0xff, 0xff, actor_opacity); + cogl_material_set_color(rectangle->corner_material, &tmp_color); + cogl_set_source(rectangle->corner_material); /* NW */ - cogl_texture_rectangle(rectangle->corner->texture, - 0, 0, - max, max, - 0, 0, - CFX_HALF, CFX_HALF); + cogl_rectangle_with_texture_coords(0, 0, + max, max, + 0, 0, + 0.5, 0.5); /* NE */ - cogl_texture_rectangle(rectangle->corner->texture, - widthx - max, 0, - widthx, max, - CFX_HALF, 0, - CFX_ONE, CFX_HALF); + cogl_rectangle_with_texture_coords(width - max, 0, + width, max, + 0.5, 0, + 1.0, 0.5); /* SW */ - cogl_texture_rectangle(rectangle->corner->texture, - 0, heightx - max, - max, heightx, - 0, CFX_HALF, - CFX_HALF, CFX_ONE); + cogl_rectangle_with_texture_coords(0, height - max, + max, height, + 0, 0.5, + 0.5, 1.0); /* SE */ - cogl_texture_rectangle(rectangle->corner->texture, - widthx - max, heightx - max, - widthx, heightx, - CFX_HALF, CFX_HALF, - CFX_ONE, CFX_ONE); + cogl_rectangle_with_texture_coords(width - max, height - max, + width, height, + 0.5, 0.5, + 1.0, 1.0); } if (border_width != 0) { - tmp_col = *border_color; + if (!rectangle->border_material) + rectangle->border_material = cogl_material_new (); - tmp_col.alpha = clutter_actor_get_paint_opacity(actor) * tmp_col.alpha / 255; - - cogl_color(&tmp_col); + cogl_color_set_from_4ub(&tmp_color, + border_color->red, + border_color->green, + border_color->blue, + actor_opacity * border_color->alpha / 255); + cogl_material_set_color(rectangle->border_material, &tmp_color); + cogl_set_source(rectangle->border_material); /* NORTH */ - cogl_rectanglex(max, 0, - widthx - 2 * max, border_widthx); + cogl_rectangle(max, 0, + width - max, border_width); /* EAST */ - cogl_rectanglex(widthx - border_widthx, max, - border_widthx, heightx - 2 * max); + cogl_rectangle(width - border_width, max, + width, height - max); /* SOUTH */ - cogl_rectanglex(max, heightx - border_widthx, - widthx - 2 * max, border_widthx); + cogl_rectangle(max, height - border_width, + width - max, height); /* WEST */ - cogl_rectanglex(0, max, - border_widthx, heightx - 2 * max); - + cogl_rectangle(0, max, + border_width, height - max); } - tmp_col = *color; - tmp_col.alpha = clutter_actor_get_paint_opacity(actor) * tmp_col.alpha / 255; + if (!rectangle->background_material) + rectangle->background_material = cogl_material_new (); - cogl_color(&tmp_col); + cogl_color_set_from_4ub(&tmp_color, + color->red, + color->green, + color->blue, + actor_opacity * color->alpha / 255); + cogl_material_set_color(rectangle->background_material, &tmp_color); + cogl_set_source(rectangle->background_material); - if (radiusx > border_widthx) { - cogl_rectanglex(radiusx, border_widthx, - widthx - radiusx - radiusx, radiusx - border_widthx); - cogl_rectanglex(radiusx, heightx - radiusx, - widthx - 2 * radiusx, radiusx - border_widthx); + if (radius > border_width) { + /* Once we've drawn the borders and corners, if the corners are bigger + * the the border width, the remaining area is shaped like + * + * ######## + * ########## + * ########## + * ######## + * + * We draw it in 3 pieces - first the top and bottom, then the main + * rectangle + */ + cogl_rectangle(radius, border_width, + width - radius, radius); + cogl_rectangle(radius, height - radius, + width - radius, height - border_width); } - cogl_rectanglex(border_widthx, MAX(radiusx, border_widthx), - widthx - 2 * border_widthx, heightx - 2 * MAX(radiusx, border_widthx)); + cogl_rectangle(border_width, max, + width - border_width, height - max); clutter_color_free(border_color); clutter_color_free(color); @@ -497,12 +524,28 @@ big_rectangle_dispose(GObject *object) rectangle = BIG_RECTANGLE(object); - rectangle->radius = 0; - big_rectangle_update_corners(rectangle); + if (rectangle->corner) { + corner_unref(rectangle->corner); + rectangle->corner = NULL; + } + + if (rectangle->corner_material) { + cogl_material_unref (rectangle->corner_material); + rectangle->corner_material = NULL; + } + + if (rectangle->background_material) { + cogl_material_unref (rectangle->background_material); + rectangle->background_material = NULL; + } + + if (rectangle->border_material) { + cogl_material_unref (rectangle->border_material); + rectangle->border_material = NULL; + } if (G_OBJECT_CLASS(big_rectangle_parent_class)->dispose) G_OBJECT_CLASS(big_rectangle_parent_class)->dispose(object); - } diff --git a/src/big/theme-image.c b/src/big/theme-image.c index 1eaade561..82ddbc8e2 100644 --- a/src/big/theme-image.c +++ b/src/big/theme-image.c @@ -22,9 +22,7 @@ #include -#include -#include -#include +#include #include @@ -41,7 +39,7 @@ typedef enum { } BigThemeImageType; struct BigThemeImage { - ClutterCairo parent_instance; + ClutterCairoTexture parent_instance; guint border_top; guint border_bottom; @@ -60,10 +58,10 @@ struct BigThemeImage { }; struct BigThemeImageClass { - ClutterCairoClass parent_class; + ClutterCairoTextureClass parent_class; }; -G_DEFINE_TYPE(BigThemeImage, big_theme_image, CLUTTER_TYPE_CAIRO) +G_DEFINE_TYPE(BigThemeImage, big_theme_image, CLUTTER_TYPE_CAIRO_TEXTURE) enum { @@ -144,7 +142,7 @@ big_theme_image_render(BigThemeImage *image) dest_width = geometry.width; dest_height = geometry.height; - cr = clutter_cairo_create(CLUTTER_CAIRO(image)); + cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(image)); for (j = 0; j < 3; j++) { switch (j) { @@ -301,7 +299,7 @@ big_theme_image_allocate(ClutterActor *actor, if (width != old_width || height != old_height) { - clutter_cairo_surface_resize(CLUTTER_CAIRO(actor), width, height); + clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(actor), width, height); big_theme_image_queue_render(image); }