1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Small example demonstrating emulating knockout-groups as in PDF-1.4
4 * using cairo_set_operator().
8 * v0.1 30 November 2002
9 * v0.2 1 December 2002 - typo fixes from Keith Packard
10 * v0.3 17 April 2003 - Tracking changes in Xr, (Removal of Xr{Push,Pop}Group)
11 * v0.4 29 September 2003 - Use cairo_rectangle rather than private rect_path
12 * Use cairo_arc for oval_path
13 * Keeping log of changes in ChangeLog/CVS now. (2003-11-19) Carl Worth
17 #include <X11/Xutil.h>
19 #include <cairo-xlib.h>
23 /* Fill the given area with checks in the standard style
24 * for showing compositing effects.
26 static void fill_checks(cairo_t * cr, int x, int y, int width, int height)
28 cairo_surface_t *check;
29 cairo_pattern_t *check_pattern;
36 cairo_surface_create_similar(cairo_current_target_surface(cr),
38 2 * CHECK_SIZE, 2 * CHECK_SIZE);
39 cairo_surface_set_repeat(check, 1);
45 cairo_set_target_surface(cr, check);
47 cairo_set_operator(cr, CAIRO_OPERATOR_SRC);
49 cairo_set_rgb_color(cr, 0.4, 0.4, 0.4);
51 cairo_rectangle(cr, 0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
54 cairo_set_rgb_color(cr, 0.7, 0.7, 0.7);
56 cairo_rectangle(cr, x, y, CHECK_SIZE, CHECK_SIZE);
58 cairo_rectangle(cr, x + CHECK_SIZE, y + CHECK_SIZE,
59 CHECK_SIZE, CHECK_SIZE);
65 /* Fill the whole surface with the check */
67 check_pattern = cairo_pattern_create_for_surface(check);
68 cairo_set_pattern(cr, check_pattern);
69 cairo_rectangle(cr, 0, 0, width, height);
72 cairo_pattern_destroy(check_pattern);
73 cairo_surface_destroy(check);
78 static void draw_pee(cairo_t * cr, double xc, double yc)
80 cairo_set_rgb_color(cr, 0, 0, 0);
81 cairo_show_text(cr, "Conky");
84 static void draw(cairo_t * cr, int width, int height)
86 cairo_surface_t *overlay;
88 /* Fill the background */
89 double xc = width / 2.;
90 double yc = height / 2.;
93 cairo_surface_create_similar(cairo_current_target_surface(cr),
94 CAIRO_FORMAT_ARGB32, width,
99 fill_checks(cr, 0, 0, width, height);
102 cairo_set_target_surface(cr, overlay);
104 cairo_set_alpha(cr, 0.5);
105 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
106 draw_pee(cr, xc, yc);
110 cairo_show_surface(cr, overlay, width, height);
112 cairo_surface_destroy(overlay);
121 char *title = "cairo: Knockout Groups";
122 unsigned int quit_keycode;
126 XSizeHints *normalhints;
127 XClassHint *classhint;
132 dpy = XOpenDisplay(NULL);
133 screen = DefaultScreen(dpy);
135 w = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
136 0, 0, width, height, 0,
137 BlackPixel(dpy, screen), WhitePixel(dpy,
140 normalhints = XAllocSizeHints();
141 normalhints->flags = 0;
144 normalhints->width = width;
145 normalhints->height = height;
147 classhint = XAllocClassHint();
148 classhint->res_name = "cairo-knockout";
149 classhint->res_class = "Cairo-knockout";
151 wmhints = XAllocWMHints();
152 wmhints->flags = InputHint;
153 wmhints->input = True;
155 XmbSetWMProperties(dpy, w, title, "cairo-knockout", 0, 0,
156 normalhints, wmhints, classhint);
162 XCreatePixmap(dpy, w, width, height,
163 DefaultDepth(dpy, screen));
164 gc = XCreateGC(dpy, pixmap, 0, NULL);
166 quit_keycode = XKeysymToKeycode(dpy, XStringToKeysym("Q"));
169 ExposureMask | StructureNotifyMask | ButtonPressMask |
178 /* Only do the redraw if there are no events pending. This
179 * avoids us getting behind doing several redraws for several
180 * consecutive resize events for example.
182 if (!XPending(dpy) && needs_redraw) {
183 cairo_t *cr = cairo_create();
185 cairo_set_target_drawable(cr, dpy, pixmap);
187 draw(cr, width, height);
191 XCopyArea(dpy, pixmap, w, gc,
192 0, 0, width, height, 0, 0);
197 XNextEvent(dpy, &xev);
199 switch (xev.xany.type) {
201 /* A click on the canvas ends the program */
204 if (xev.xkey.keycode == quit_keycode)
207 case ConfigureNotify:
208 /* Note new size and create new pixmap. */
209 width = xev.xconfigure.width;
210 height = xev.xconfigure.height;
211 XFreePixmap(dpy, pixmap);
213 XCreatePixmap(dpy, w, width, height,
214 DefaultDepth(dpy, screen));
218 XCopyArea(dpy, pixmap, w, gc,
219 xev.xexpose.x, xev.xexpose.y,
220 xev.xexpose.width, xev.xexpose.height,
221 xev.xexpose.x, xev.xexpose.y);