static void make_clip_path (Clip *clip) { switch (clip->type) { case CLIP_NONE: break; case CLIP_RECTANGLE: cogl_path_rectangle (clip->x1, clip->y1, clip->x2, clip->y2); break; case CLIP_ROTATED_RECTANGLE: { int size = MIN (ABS (clip->x2 - clip->x1), ABS (clip->y2 - clip->y1)); int cx = (clip->x1 + clip->x2) / 2; int cy = (clip->y1 + clip->y2) / 2; cogl_path_move_to (cx - size / 2, cy); cogl_path_line_to (cx, cy - size / 2); cogl_path_line_to (cx + size / 2, cy); cogl_path_line_to (cx, cy + size / 2); cogl_path_close (); } break; case CLIP_SHAPES: { int x, y, width, height; if (clip->x1 < clip->x2) { x = clip->x1; width = clip->x2 - x; } else { x = clip->x2; width = clip->x1 - x; } if (clip->y1 < clip->y2) { y = clip->y1; height = clip->y2 - y; } else { y = clip->y2; height = clip->y1 - y; } path_shapes (x, y, width, height); } break; } }
void test_path_clip (void) { CoglPath *path; CoglPipeline *pipeline; int fb_width, fb_height; fb_width = cogl_framebuffer_get_width (test_fb); fb_height = cogl_framebuffer_get_height (test_fb); cogl_framebuffer_orthographic (test_fb, 0, 0, fb_width, fb_height, -1, 100); path = cogl_path_new (); cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1.0f, 0.0f, 0.0f, 1.0f); /* Make an L-shape with the top right corner left untouched */ cogl_path_move_to (path, 0, fb_height); cogl_path_line_to (path, fb_width, fb_height); cogl_path_line_to (path, fb_width, fb_height / 2); cogl_path_line_to (path, fb_width / 2, fb_height / 2); cogl_path_line_to (path, fb_width / 2, 0); cogl_path_line_to (path, 0, 0); cogl_path_close (path); cogl_framebuffer_push_path_clip (test_fb, path); /* Try to fill the framebuffer with a blue rectangle. This should be * clipped to leave the top right quadrant as is */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, 0, 0, 255, 255); cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, fb_width, fb_height); cogl_framebuffer_pop_clip (test_fb); cogl_object_unref (pipeline); cogl_object_unref (path); /* Check each of the four quadrants */ test_utils_check_pixel (test_fb, fb_width / 4, fb_height / 4, 0x0000ffff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height / 4, 0xff0000ff); test_utils_check_pixel (test_fb, fb_width / 4, fb_height * 3 / 4, 0x0000ffff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height * 3 / 4, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
static void circle_paint_cb (ClutterActor *actor) { const CoglColor fill_color = { 0xff, 0xff, 0xff, 0x80 }; gint i; gdouble angle; guint radius = clutter_actor_get_width (actor) / 2; cogl_set_source_color (&fill_color); angle = *((gdouble *)g_object_get_data (G_OBJECT (actor), "angle")); for (i = 0; i < CIRCLE_S; i++, angle += (2.0 * G_PI) / (gdouble) CIRCLE_S) { gdouble angle2 = angle + ((2.0 * G_PI) / (gdouble)CIRCLE_S) / 2.0; cogl_path_move_to (((radius - CIRCLE_W) * cos (angle)) + radius, ((radius - CIRCLE_W) * sin (angle)) + radius); cogl_path_arc (radius, radius, radius, radius, CLUTTER_ANGLE_FROM_RAD (angle), CLUTTER_ANGLE_FROM_RAD (angle2)); cogl_path_line_to (((radius - CIRCLE_W) * cos (angle2)) + radius, ((radius - CIRCLE_W) * sin (angle2)) + radius); cogl_path_arc (radius, radius, radius - CIRCLE_W, radius - CIRCLE_W, CLUTTER_ANGLE_FROM_RAD (angle2), CLUTTER_ANGLE_FROM_RAD (angle)); cogl_path_close (); cogl_path_fill (); } }
static VALUE rb_cogl_path_move_to (VALUE self, VALUE x, VALUE y) { cogl_path_move_to (rbclt_num_to_fixed (x), rbclt_num_to_fixed (y)); return Qnil; }
static void test_paint_curve (void) { cogl_path_move_to (-50, +50); cogl_path_curve_to (+100, -50, -100, -50, +50, +50); }
void cogl_path_line (CoglPath *path, float x_1, float y_1, float x_2, float y_2) { cogl_path_move_to (path, x_1, y_1); cogl_path_line_to (path, x_2, y_2); }
void cogl_path_round_rectangle (CoglPath *path, float x_1, float y_1, float x_2, float y_2, float radius, float arc_step) { float inner_width = x_2 - x_1 - radius * 2; float inner_height = y_2 - y_1 - radius * 2; _COGL_RETURN_IF_FAIL (cogl_is_path (path)); cogl_path_move_to (path, x_1, y_1 + radius); _cogl_path_rel_arc (path, radius, 0, radius, radius, 180, 270, arc_step); cogl_path_line_to (path, path->data->path_pen.x + inner_width, path->data->path_pen.y); _cogl_path_rel_arc (path, 0, radius, radius, radius, -90, 0, arc_step); cogl_path_line_to (path, path->data->path_pen.x, path->data->path_pen.y + inner_height); _cogl_path_rel_arc (path, -radius, 0, radius, radius, 0, 90, arc_step); cogl_path_line_to (path, path->data->path_pen.x - inner_width, path->data->path_pen.y); _cogl_path_rel_arc (path, 0, -radius, radius, radius, 90, 180, arc_step); cogl_path_close (path); }
static void test_paint_curve () { cogl_path_move_to (CLUTTER_INT_TO_FIXED (-50), CLUTTER_INT_TO_FIXED (+50)); cogl_path_curve_to (CLUTTER_INT_TO_FIXED (+100), CLUTTER_INT_TO_FIXED (-50), CLUTTER_INT_TO_FIXED (-100), CLUTTER_INT_TO_FIXED (-50), CLUTTER_INT_TO_FIXED (+50), CLUTTER_INT_TO_FIXED (+50)); }
static void pre_paint_clip_cb (void) { /* Generate a clip path that clips out the top left division */ cogl_path_move_to (DIVISION_WIDTH, 0); cogl_path_line_to (SOURCE_SIZE, 0); cogl_path_line_to (SOURCE_SIZE, SOURCE_SIZE); cogl_path_line_to (0, SOURCE_SIZE); cogl_path_line_to (0, DIVISION_HEIGHT); cogl_path_line_to (DIVISION_WIDTH, DIVISION_HEIGHT); cogl_path_close (); cogl_clip_push_from_path (); }
void cogl_path_polyline (CoglPath *path, const float *coords, int num_points) { int c = 0; _COGL_RETURN_IF_FAIL (cogl_is_path (path)); cogl_path_move_to (path, coords[0], coords[1]); for (c = 1; c < num_points; ++c) cogl_path_line_to (path, coords[2*c], coords[2*c+1]); }
static void paint_triangle (ClutterActor *actor) { gfloat width, height; clutter_actor_get_size (actor, &width, &height); cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); cogl_path_move_to (width/2, 0); cogl_path_line_to (width, height); cogl_path_line_to (0, height); cogl_path_close (); cogl_path_fill (); }
void cogl_path_rel_move_to (CoglPath *path, float x, float y) { CoglPathData *data; _COGL_RETURN_IF_FAIL (cogl_is_path (path)); data = path->data; cogl_path_move_to (path, data->path_pen.x + x, data->path_pen.y + y); }
static void path_shapes (gint x, gint y, gint width, gint height) { cogl_path_move_to (x, y); cogl_path_line_to (x, (y + height * 4 / 5)); cogl_path_line_to ((x + width * 4 / 15), (y + height * 4 / 5)); cogl_path_close (); cogl_path_rectangle (x + width / 3, y, x + width * 9 / 15, y + height * 4 / 5); cogl_path_ellipse ((x + width * 4 / 5), (y + height * 2 / 5), (width * 2 / 15), (height * 2 / 5)); }
static void pick (ClutterActor *self, const ClutterColor *color) { ChamplainPointPrivate *priv = GET_PRIVATE (self); gdouble radius = priv->size / 2.0; cogl_path_new (); cogl_set_source_color4ub (color->red, color->green, color->blue, color->alpha); cogl_path_move_to (radius, radius); cogl_path_arc (radius, radius, radius, radius, 0, 360.0); cogl_path_close (); cogl_path_fill (); }
void cogl_path_rectangle (CoglPath *path, float x_1, float y_1, float x_2, float y_2) { CoglBool is_rectangle; /* If the path was previously empty and the rectangle isn't mirrored then we'll record that this is a simple rectangle path so that we can optimise it */ is_rectangle = (path->data->path_nodes->len == 0 && x_2 >= x_1 && y_2 >= y_1); cogl_path_move_to (path, x_1, y_1); cogl_path_line_to (path, x_2, y_1); cogl_path_line_to (path, x_2, y_2); cogl_path_line_to (path, x_1, y_2); cogl_path_close (path); path->data->is_rectangle = is_rectangle; }
static void _cogl_path_arc (CoglPath *path, float center_x, float center_y, float radius_x, float radius_y, float angle_1, float angle_2, float angle_step, unsigned int move_first) { float a = 0x0; float cosa = 0x0; float sina = 0x0; float px = 0x0; float py = 0x0; /* Fix invalid angles */ if (angle_1 == angle_2 || angle_step == 0x0) return; if (angle_step < 0x0) angle_step = -angle_step; /* Walk the arc by given step */ a = angle_1; while (a != angle_2) { cosa = cosf (a * (G_PI/180.0)); sina = sinf (a * (G_PI/180.0)); px = center_x + (cosa * radius_x); py = center_y + (sina * radius_y); if (a == angle_1 && move_first) cogl_path_move_to (path, px, py); else cogl_path_line_to (path, px, py); if (G_LIKELY (angle_2 > angle_1)) { a += angle_step; if (a > angle_2) a = angle_2; } else { a -= angle_step; if (a < angle_2) a = angle_2; } } /* Make sure the final point is drawn */ cosa = cosf (angle_2 * (G_PI/180.0)); sina = sinf (angle_2 * (G_PI/180.0)); px = center_x + (cosa * radius_x); py = center_y + (sina * radius_y); cogl_path_line_to (path, px, py); }
static void mnb_fancy_bin_paint (ClutterActor *actor) { MnbFancyBin *self = MNB_FANCY_BIN (actor); MnbFancyBinPrivate *priv = self->priv; /* Draw the clipped child if necessary */ if (priv->fanciness > 0.0) { MxPadding padding; gfloat width, height; clutter_actor_get_size (actor, &width, &height); mx_widget_get_padding (MX_WIDGET (actor), &padding); /* Create a clip path so that the clone won't poke out * from underneath the background. */ cogl_path_new (); cogl_path_move_to (padding.left + priv->curve_radius, padding.top); cogl_path_arc (width - padding.right - priv->curve_radius, priv->curve_radius + padding.top, priv->curve_radius, priv->curve_radius, 270, 360); cogl_path_arc (width - padding.right - priv->curve_radius, height - padding.bottom - priv->curve_radius, priv->curve_radius, priv->curve_radius, 0, 90); cogl_path_arc (padding.left + priv->curve_radius, height - padding.bottom - priv->curve_radius, priv->curve_radius, priv->curve_radius, 90, 180); cogl_path_arc (padding.left + priv->curve_radius, padding.top + priv->curve_radius, priv->curve_radius, priv->curve_radius, 180, 270); cogl_path_close (); cogl_clip_push_from_path (); /* Paint child */ if (priv->child) clutter_actor_paint (priv->child); cogl_clip_pop (); /* Chain up for background */ CLUTTER_ACTOR_CLASS (mnb_fancy_bin_parent_class)->paint (actor); } /* Draw the un-fancy child */ if ((priv->fanciness < 1.0) && priv->clone) clutter_actor_paint (priv->clone); }