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.
27 fill_checks (cairo_t *cr,
29 int width, int height)
31 cairo_surface_t *check;
32 cairo_pattern_t *check_pattern;
38 check = cairo_surface_create_similar (cairo_current_target_surface (cr),
40 2 * CHECK_SIZE, 2 * CHECK_SIZE);
41 cairo_surface_set_repeat (check, 1);
47 cairo_set_target_surface (cr, check);
49 cairo_set_operator (cr, CAIRO_OPERATOR_SRC);
51 cairo_set_rgb_color (cr, 0.4, 0.4, 0.4);
53 cairo_rectangle (cr, 0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
56 cairo_set_rgb_color (cr, 0.7, 0.7, 0.7);
58 cairo_rectangle (cr, x, y, CHECK_SIZE, CHECK_SIZE);
60 cairo_rectangle (cr, x + CHECK_SIZE, y + CHECK_SIZE, CHECK_SIZE, CHECK_SIZE);
66 /* Fill the whole surface with the check */
68 check_pattern = cairo_pattern_create_for_surface (check);
69 cairo_set_pattern (cr, check_pattern);
70 cairo_rectangle (cr, 0, 0, width, height);
73 cairo_pattern_destroy (check_pattern);
74 cairo_surface_destroy (check);
79 static void draw_pee (cairo_t *cr, double xc, double yc)
81 cairo_set_rgb_color (cr, 0, 0, 0);
82 cairo_show_text (cr, "Conky");
90 cairo_surface_t *overlay;
92 /* Fill the background */
93 double xc = width / 2.;
94 double yc = height / 2.;
96 overlay = cairo_surface_create_similar (cairo_current_target_surface (cr),
102 fill_checks (cr, 0, 0, width, height);
105 cairo_set_target_surface (cr, overlay);
107 cairo_set_alpha (cr, 0.5);
108 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
109 draw_pee (cr, xc, yc);
113 cairo_show_surface (cr, overlay, width, height);
115 cairo_surface_destroy (overlay);
125 char *title = "cairo: Knockout Groups";
126 unsigned int quit_keycode;
130 XSizeHints *normalhints;
131 XClassHint *classhint;
136 dpy = XOpenDisplay (NULL);
137 screen = DefaultScreen (dpy);
139 w = XCreateSimpleWindow (dpy, RootWindow (dpy, screen),
140 0, 0, width, height, 0,
141 BlackPixel (dpy, screen), WhitePixel (dpy, screen));
143 normalhints = XAllocSizeHints ();
144 normalhints->flags = 0;
147 normalhints->width = width;
148 normalhints->height = height;
150 classhint = XAllocClassHint ();
151 classhint->res_name = "cairo-knockout";
152 classhint->res_class = "Cairo-knockout";
154 wmhints = XAllocWMHints ();
155 wmhints->flags = InputHint;
156 wmhints->input = True;
158 XmbSetWMProperties (dpy, w, title, "cairo-knockout", 0, 0,
159 normalhints, wmhints, classhint);
164 pixmap = XCreatePixmap (dpy, w, width, height, DefaultDepth (dpy, screen));
165 gc = XCreateGC (dpy, pixmap, 0, NULL);
167 quit_keycode = XKeysymToKeycode(dpy, XStringToKeysym("Q"));
169 XSelectInput (dpy, w, ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask);
177 /* Only do the redraw if there are no events pending. This
178 * avoids us getting behind doing several redraws for several
179 * consecutive resize events for example.
181 if (!XPending (dpy) && needs_redraw) {
182 cairo_t *cr = cairo_create ();
184 cairo_set_target_drawable (cr, dpy, pixmap);
186 draw (cr, width, height);
190 XCopyArea (dpy, pixmap, w, gc,
198 XNextEvent (dpy, &xev);
200 switch (xev.xany.type) {
202 /* A click on the canvas ends the program */
205 if (xev.xkey.keycode == quit_keycode)
208 case ConfigureNotify:
209 /* Note new size and create new pixmap. */
210 width = xev.xconfigure.width;
211 height = xev.xconfigure.height;
212 XFreePixmap (dpy, pixmap);
213 pixmap = XCreatePixmap (dpy, w, width, height, DefaultDepth (dpy, screen));
217 XCopyArea (dpy, pixmap, w, gc,
218 xev.xexpose.x, xev.xexpose.y,
219 xev.xexpose.width, xev.xexpose.height,
220 xev.xexpose.x, xev.xexpose.y);