Hello, I hate to bother you all with trivial stuff like this, but I am having some serious trouble finding the error in my program. Essentially, I want to render a shape with a gradient background and a text label, so I created an actor that has a single Text actor as a child. The gradient is rendered using a method similar to http://lists.o-hand.com/clutter/1787.html written in vala and adapted to handle angles. (Any improvements to this function would also be welcome C: ) A screenshot of the incorrect behaviour is located at http://sellyourvote.ca/Screenshot-test.png I know it has something to do with the Text actor, since both rectangles render properly if the text is turned off in both of them. Thanks, Sam ------------ // test.vala - Problem clutter file // Should render two rounded rectangles with gradients, // the left one without text, and the right one with text // On my machine left box only has border, but right box // is correct. // Compile with valac --pkg=clutter-1.0 test.vala using Clutter; using Cogl; struct Point { float x; float y; } public class TestActor : Actor { Text t = new Text.with_text(null, "Test"); bool _text; construct { t.set_parent(this); t.set_size(40, 40); t.set_position(10, 10); } public TestActor(bool draw_text) { _text = draw_text; } private inline static void rotate_point(ref Point p, float angle) { float oldx = p.x, oldy = p.y; p.x = oldx*Math.cosf(angle) - oldy*Math.sinf(angle); p.y = oldy*Math.cosf(angle) + oldx*Math.sinf(angle); } private static void draw_gradient(float width, float height, Cogl.Color c1, Cogl.Color c2, float angle) { if (angle >= Math.PI) { Cogl.Color temp = c1; c1 = c2; c2 = temp; } float sin_a = Math.sinf(angle); float cos_a = Math.cosf(angle); float A = sin_a*width; float B = cos_a*width; float C = sin_a*height; float D = cos_a*height; float s1 = A+D; float s2 = B+C; float x0 = -s2/2f, x1 = x0 + s2; float y0 = -s1/2f, y1 = y0 + s1; Point p[4]; p[0] = {x0, y0}; p[1] = {x0, y1}; p[2] = {x1, y1}; p[3] = {x1, y0}; for (int i = 0; i < p.length; i++) { rotate_point(ref p[i], angle); p[i].x += width/2f; p[i].y += height/2f; } TextureVertex v[4]; v[0] = {p[0].x, p[0].y, 0, 0, 0, c1}; v[1] = {p[1].x, p[1].y, 0, 0, 0, c1}; v[2] = {p[2].x, p[2].y, 0, 0, 0, c2}; v[3] = {p[3].x, p[3].y, 0, 0, 0, c2}; Cogl.polygon(v, true); } protected override void paint() { Geometry geom; get_allocation_geometry(out geom); Cogl.Color pri = {0, 255, 0, 255}; Cogl.Color sec = {0, 0, 255, 255}; Cogl.path_round_rectangle(0, 0, geom.width, geom.height, 5, (float)Math.PI_4/4f); Cogl.clip_push_from_path(); draw_gradient(geom.width, geom.height, pri, sec, (float)Math.PI/4); Cogl.clip_pop(); Cogl.path_round_rectangle(0, 0, geom.width, geom.height, 5, (float)Math.PI_4/4f); Cogl.set_source_color({128, 128, 128, 255}); Cogl.path_stroke(); if (_text) t.paint(); } protected override void pick(Clutter.Color c) { Geometry geom; get_allocation_geometry(out geom); Cogl.path_round_rectangle(0, 0, geom.width, geom.height, 5, (float)Math.PI_4/4f); Cogl.set_source_color({c.red,c.green,c.blue,c.alpha}); Cogl.path_fill(); t.paint(); } protected override void map() { base.map(); t.map(); } protected override void unmap() { t.unmap(); base.unmap(); } protected override void allocate(ActorBox box, AllocationFlags flags) { base.allocate(box, flags); float x, y, width, height; t.get_size(out width, out height); t.get_position(out x, out y); t.allocate({x, y, width, height}, flags); } } void main(string[] args) { if (Clutter.init(ref args) != 1) return; weak Stage s = Stage.get_default(); s.color = {0, 0, 0, 255}; s.set_size(230, 120); s.show_all(); // Should render gradient, no text TestActor off = new TestActor(false); // Should render gradient and text TestActor on = new TestActor(true); s.add_actor(off); s.add_actor(on); off.set_size(100, 100); off.set_position(10, 10); on.set_size(100, 100); on.set_position(120, 10); s.destroy.connect(() => { Clutter.main_quit(); }); Clutter.main(); }
Attachment:
smime.p7s
Description: S/MIME cryptographic signature