double xc, double yc,
double xr, double yr)
{
- cairo_matrix_t *matrix;
-
- matrix = cairo_matrix_create ();
- cairo_current_matrix (cr, matrix);
+ cairo_save (cr);
cairo_translate (cr, xc, yc);
cairo_scale (cr, 1.0, yr / xr);
0, 2 * G_PI);
cairo_close_path (cr);
- cairo_set_matrix (cr, matrix);
- cairo_matrix_destroy (matrix);
+ cairo_restore (cr);
}
/* Create a path that is a circular oval with radii xr, yr at xc,
#define CHECK_SIZE 32
cairo_rectangle (cr, x, y, width, height);
- cairo_set_rgb_color (cr, 0.4, 0.4, 0.4);
+ cairo_set_source_rgb (cr, 0.4, 0.4, 0.4);
cairo_fill (cr);
/* Only works for CHECK_SIZE a power of 2 */
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
}
- cairo_set_rgb_color (cr, 0.7, 0.7, 0.7);
+ cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
cairo_fill (cr);
}
static void
draw_3circles (cairo_t *cr,
double xc, double yc,
- double radius)
+ double radius,
+ double alpha)
{
double subradius = radius * (2 / 3. - 0.1);
- cairo_set_rgb_color (cr, 1., 0., 0.);
+ cairo_set_source_rgba (cr, 1., 0., 0., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5)),
yc - radius / 3. * sin (G_PI * (0.5)),
subradius, subradius);
cairo_fill (cr);
- cairo_set_rgb_color (cr, 0., 1., 0.);
+ cairo_set_source_rgba (cr, 0., 1., 0., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5 + 2/.3)),
yc - radius / 3. * sin (G_PI * (0.5 + 2/.3)),
subradius, subradius);
cairo_fill (cr);
- cairo_set_rgb_color (cr, 0., 0., 1.);
+ cairo_set_source_rgba (cr, 0., 0., 1., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5 + 4/.3)),
yc - radius / 3. * sin (G_PI * (0.5 + 4/.3)),
cairo_fill (cr);
}
-static void
-draw (cairo_t *cr,
- int width,
- int height)
+static gboolean
+on_draw (GtkWidget *widget,
+ cairo_t *cr)
{
cairo_surface_t *overlay, *punch, *circles;
+ cairo_t *overlay_cr, *punch_cr, *circles_cr;
/* Fill the background */
+ int width = gtk_widget_get_allocated_width (widget);
+ int height = gtk_widget_get_allocated_height (widget);
double radius = 0.5 * (width < height ? width : height) - 10;
double xc = width / 2.;
double yc = height / 2.;
- overlay = cairo_surface_create_similar (cairo_current_target_surface (cr),
- CAIRO_FORMAT_ARGB32,
+ overlay = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
width, height);
- if (overlay == NULL)
- return;
- punch = cairo_surface_create_similar (cairo_current_target_surface (cr),
- CAIRO_FORMAT_A8,
+ punch = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
width, height);
- if (punch == NULL)
- return;
- circles = cairo_surface_create_similar (cairo_current_target_surface (cr),
- CAIRO_FORMAT_ARGB32,
+ circles = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
width, height);
- if (circles == NULL)
- return;
fill_checks (cr, 0, 0, width, height);
- cairo_save (cr);
- cairo_set_target_surface (cr, overlay);
- cairo_identity_matrix (cr);
-
/* Draw a black circle on the overlay
*/
- cairo_set_rgb_color (cr, 0., 0., 0.);
- oval_path (cr, xc, yc, radius, radius);
- cairo_fill (cr);
-
- cairo_save (cr);
- cairo_set_target_surface (cr, punch);
+ overlay_cr = cairo_create (overlay);
+ cairo_set_source_rgb (overlay_cr, 0., 0., 0.);
+ oval_path (overlay_cr, xc, yc, radius, radius);
+ cairo_fill (overlay_cr);
/* Draw 3 circles to the punch surface, then cut
* that out of the main circle in the overlay
*/
- draw_3circles (cr, xc, yc, radius);
+ punch_cr = cairo_create (punch);
+ draw_3circles (punch_cr, xc, yc, radius, 1.0);
+ cairo_destroy (punch_cr);
- cairo_restore (cr);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_OUT_REVERSE);
- cairo_show_surface (cr, punch, width, height);
+ cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT);
+ cairo_set_source_surface (overlay_cr, punch, 0, 0);
+ cairo_paint (overlay_cr);
/* Now draw the 3 circles in a subgroup again
* at half intensity, and use OperatorAdd to join up
* without seams.
*/
- cairo_save (cr);
- cairo_set_target_surface (cr, circles);
-
- cairo_set_alpha (cr, 0.5);
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- draw_3circles (cr, xc, yc, radius);
-
- cairo_restore (cr);
+ circles_cr = cairo_create (circles);
+
+ cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER);
+ draw_3circles (circles_cr, xc, yc, radius, 0.5);
+ cairo_destroy (circles_cr);
- cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
- cairo_show_surface (cr, circles, width, height);
+ cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD);
+ cairo_set_source_surface (overlay_cr, circles, 0, 0);
+ cairo_paint (overlay_cr);
- cairo_restore (cr);
+ cairo_destroy (overlay_cr);
- cairo_show_surface (cr, overlay, width, height);
+ cairo_set_source_surface (cr, overlay, 0, 0);
+ cairo_paint (cr);
cairo_surface_destroy (overlay);
cairo_surface_destroy (punch);
cairo_surface_destroy (circles);
-}
-
-static gboolean
-on_expose_event (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data)
-{
- cairo_t *cr;
-
- cr = gdk_drawable_create_cairo_context (widget->window);
-
- draw (cr, widget->allocation.width, widget->allocation.height);
-
- cairo_destroy (cr);
return FALSE;
}
darea = gtk_drawing_area_new ();
gtk_container_add (GTK_CONTAINER (window), darea);
- g_signal_connect (darea, "expose-event",
- G_CALLBACK (on_expose_event), NULL);
+ g_signal_connect (darea, "draw",
+ G_CALLBACK (on_draw), NULL);
g_signal_connect (window, "destroy-event",
G_CALLBACK (gtk_main_quit), NULL);