summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-10-13 23:09:39 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-13 23:09:39 +0100
commitb4584da9fec1b05adfed29b95bf086aec14c860d (patch)
tree6ba9751106eb3721ca421fab37436fe77b3d7f8c
parentcda9e7feaf46fad5dfe465c881c96f1e004c9e65 (diff)
Add some rudimentary clipping variations
-rw-r--r--chart-demo.c7
-rw-r--r--demo.c84
-rw-r--r--demo.h10
-rw-r--r--fish-demo.c5
-rw-r--r--flowers-demo.c13
-rw-r--r--glx.c29
-rw-r--r--tiger-demo.c7
7 files changed, 148 insertions, 7 deletions
diff --git a/chart-demo.c b/chart-demo.c
index 0c76fe1..488a922 100644
--- a/chart-demo.c
+++ b/chart-demo.c
@@ -185,12 +185,14 @@ int main (int argc, char **argv)
int show_fps = 1;
int benchmark;
cairo_antialias_t antialias;
+ enum clip clip;
struct chart c[5];
int n;
device = device_open(argc, argv);
antialias = device_get_antialias(argc, argv);
+ clip = device_get_clip(argc, argv);
benchmark = device_get_benchmark(argc, argv);
if (benchmark == 0)
benchmark = 20;
@@ -214,6 +216,7 @@ int main (int argc, char **argv)
cr = cairo_create(fb->surface);
bg_draw(device, cr);
+ device_apply_clip(device, cr, clip);
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
for (n = 0; n < 5; n++)
@@ -226,8 +229,10 @@ int main (int argc, char **argv)
chart_stroke(device, cr, &c[n]);
gettimeofday(&now, NULL);
- if (show_fps && last_fps.tv_sec)
+ if (show_fps && last_fps.tv_sec) {
+ cairo_reset_clip (cr);
fps_draw(cr, device->name, &last_fps, &now);
+ }
last_fps = now;
cairo_destroy(cr);
diff --git a/demo.c b/demo.c
index 86c2551..733461b 100644
--- a/demo.c
+++ b/demo.c
@@ -1,6 +1,7 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <math.h>
#include "demo.h"
@@ -275,3 +276,86 @@ fps_draw (cairo_t *cr, const char *name,
cairo_show_text (cr, buf);
}
+#ifndef min
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+#endif
+
+enum clip device_get_clip(int argc, char **argv)
+{
+ const char *clip = NULL;
+ enum clip c;
+ int n;
+
+ for (n = 1; n < argc; n++) {
+ if (strcmp (argv[n], "--clip") == 0 && n < argc - 1)
+ clip = argv[++n];
+ else if (strncmp (argv[n], "--clip=", 7) == 0)
+ clip = argv[n] + 7;
+ }
+
+ c = CLIP_NONE;
+ if (clip) {
+ if (strcmp (clip, "none") == 0) {
+ } else if (strcmp (clip, "region") == 0 || strcmp (clip, "region1") == 0) {
+ c = CLIP_REGION1;
+ } else if (strcmp (clip, "box") == 0 || strcmp (clip, "box1") == 0) {
+ c = CLIP_BOX1;
+ } else if (strcmp (clip, "region2") == 0) {
+ c = CLIP_REGION2;
+ } else if (strcmp (clip, "box2") == 0) {
+ c = CLIP_BOX2;
+ } else if (strcmp (clip, "diamond") == 0) {
+ c = CLIP_DIAMOND;
+ } else if (strcmp (clip, "circle") == 0) {
+ c = CLIP_CIRCLE;
+ }
+ }
+
+ return c;
+}
+
+void device_apply_clip(struct device *device, cairo_t *cr, enum clip c)
+{
+ cairo_new_path (cr);
+ switch (c) {
+ case CLIP_NONE:
+ return;
+ case CLIP_REGION1:
+ cairo_rectangle (cr,
+ device->width/4, device->height/4,
+ device->width/2, device->height/2);
+ break;
+ case CLIP_BOX1:
+ cairo_rectangle (cr,
+ device->width/4+.25, device->height/4+.25,
+ device->width/2, device->height/2);
+ break;
+ case CLIP_REGION2:
+ cairo_rectangle (cr,
+ 0, 0, 3*device->width/4, 3*device->height/4);
+ cairo_rectangle (cr,
+ device->width/4, device->height/4,
+ 3*device->width/4, 3*device->height/4);
+ break;
+ case CLIP_BOX2:
+ cairo_rectangle (cr,
+ 0.25, 0.25, 3*device->width/4, 3*device->height/4);
+ cairo_rectangle (cr,
+ device->width/4-.25, device->height/4-.25,
+ 3*device->width/4 + .25, 3*device->height/4 + .25);
+ break;
+ case CLIP_DIAMOND:
+ cairo_move_to (cr, device->width/2, 0);
+ cairo_line_to (cr, device->width, device->height/2);
+ cairo_line_to (cr, device->width/2, device->height);
+ cairo_line_to (cr, 0, device->height/2);
+ cairo_close_path (cr);
+ break;
+ case CLIP_CIRCLE:
+ cairo_arc (cr, device->width/2, device->height/2,
+ min(device->width/2, device->height/2),
+ 0, 2 * M_PI);
+ break;
+ }
+ cairo_clip (cr);
+}
diff --git a/demo.h b/demo.h
index ddfca9f..8415be8 100644
--- a/demo.h
+++ b/demo.h
@@ -31,6 +31,16 @@ struct device *device_open(int argc, char **argv);
int device_get_size(int argc, char **argv, int *width, int *height);
cairo_antialias_t device_get_antialias(int argc, char **argv);
int device_get_benchmark(int argc, char **argv);
+enum clip {
+ CLIP_NONE,
+ CLIP_REGION1,
+ CLIP_BOX1,
+ CLIP_REGION2,
+ CLIP_BOX2,
+ CLIP_DIAMOND,
+ CLIP_CIRCLE,
+} device_get_clip(int argc, char **argv);
+void device_apply_clip(struct device *device, cairo_t *cr, enum clip c);
#if HAVE_COGL
struct device *cogl_open (int argc, char **argv);
diff --git a/fish-demo.c b/fish-demo.c
index 358a385..413977b 100644
--- a/fish-demo.c
+++ b/fish-demo.c
@@ -172,10 +172,12 @@ int main (int argc, char **argv)
int frame = 0;
int frames = 0;
int benchmark;
+ enum clip clip;
cairo_pattern_t *reflection = NULL;
int x1, x2;
device = device_open(argc, argv);
+ clip = device_get_clip(argc, argv);
benchmark = device_get_benchmark(argc, argv);
if (benchmark == 0)
benchmark = 20;
@@ -215,6 +217,9 @@ int main (int argc, char **argv)
cairo_t *cr;
cr = cairo_create(fb->surface);
+
+ device_apply_clip(device, cr, clip);
+
cairo_set_source(cr, bg);
if (reflection)
cairo_mask(cr, reflection);
diff --git a/flowers-demo.c b/flowers-demo.c
index 9ab07ee..204c2bb 100644
--- a/flowers-demo.c
+++ b/flowers-demo.c
@@ -247,6 +247,7 @@ naive_flowers_draw (cairo_t *cr, bool opaque)
cairo_matrix_t m;
if (! opaque) {
+ cairo_save (cr);
cairo_rectangle (cr, 0, 0, f->size, f->size);
cairo_clip (cr);
cairo_push_group (cr);
@@ -318,12 +319,13 @@ naive_flowers_draw (cairo_t *cr, bool opaque)
cairo_stroke (cr);
}
if (! opaque) {
- cairo_pop_group_to_source(cr);
- cairo_reset_clip (cr);
-
+ cairo_pattern_t *p = cairo_pop_group(cr);
+ cairo_restore (cr);
cairo_matrix_init_translate (&m, -f->x, -f->y);
- cairo_pattern_set_matrix (cairo_get_source(cr), &m);
+ cairo_pattern_set_matrix (p, &m);
+ cairo_set_source (cr, p);
cairo_paint_with_alpha (cr, f->fade);
+ cairo_pattern_destroy (p);
} else
cairo_restore (cr);
}
@@ -356,11 +358,13 @@ int main (int argc, char **argv)
int frame = 0;
int frames = 0;
int benchmark;
+ enum clip clip;
void (*draw) (cairo_t *, bool);
int naive, opaque;
int i;
device = device_open(argc, argv);
+ clip = device_get_clip(argc, argv);
benchmark = device_get_benchmark(argc, argv);
if (benchmark == 0)
benchmark = 20;
@@ -392,6 +396,7 @@ int main (int argc, char **argv)
cairo_paint (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ device_apply_clip (device, cr, clip);
draw(cr, opaque);
gettimeofday(&now, NULL);
diff --git a/glx.c b/glx.c
index e1fa4d5..a8668fe 100644
--- a/glx.c
+++ b/glx.c
@@ -3,6 +3,7 @@
#include "demo.h"
#include <stdlib.h>
+#include <string.h>
#include <X11/X.h>
struct glx_device {
@@ -13,6 +14,8 @@ struct glx_device {
Window drawable;
GLXContext ctx;
cairo_device_t *device;
+
+ int double_buffered;
};
static void
@@ -23,7 +26,16 @@ destroy (struct framebuffer *fb)
static void
show (struct framebuffer *fb)
{
- cairo_gl_surface_swapbuffers (fb->surface);
+ struct glx_device *device = (struct glx_device *) fb->device;
+
+ if (device->double_buffered) {
+ cairo_t *cr = cairo_create (device->base.scanout);
+ cairo_set_source_surface (cr, fb->surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+ }
+
+ cairo_gl_surface_swapbuffers (device->base.scanout);
}
static struct framebuffer *
@@ -51,6 +63,7 @@ glx_open (int argc, char **argv)
Screen *scr;
int screen;
XSetWindowAttributes attr;
+ int i;
dpy = XOpenDisplay (NULL);
if (dpy == NULL)
@@ -65,6 +78,13 @@ glx_open (int argc, char **argv)
device->fb.show = show;
device->fb.destroy = destroy;
+ device->double_buffered = 0;
+ for (i = 1; i < argc; i++) {
+ if (strcmp (argv[i], "--double") == 0)
+ device->double_buffered = 1;
+ }
+
+
screen = DefaultScreen (dpy);
scr = XScreenOfDisplay (dpy, screen);
device->base.width = WidthOfScreen (scr);
@@ -104,7 +124,14 @@ glx_open (int argc, char **argv)
device->drawable,
device->base.width,
device->base.height);
+ if (device->double_buffered) {
+ device->fb.surface = cairo_surface_create_similar (device->base.scanout,
+ CAIRO_CONTENT_COLOR,
+ device->base.width,
+ device->base.height);
+ } else {
device->fb.surface = device->base.scanout;
+ }
return &device->base;
}
diff --git a/tiger-demo.c b/tiger-demo.c
index 0712a8f..136351d 100644
--- a/tiger-demo.c
+++ b/tiger-demo.c
@@ -24,6 +24,7 @@
static void tiger(struct device *device,
struct framebuffer *fb,
cairo_antialias_t antialias,
+ enum clip c,
double scale,
double rotation)
{
@@ -39,6 +40,8 @@ static void tiger(struct device *device,
cairo_paint (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ device_apply_clip (device, cr, c);
+
cairo_translate (cr, device->width/2, device->height/2);
cairo_translate (cr, 32, 30);
cairo_scale (cr, scale, scale);
@@ -77,6 +80,7 @@ int main (int argc, char **argv)
struct timeval start, last_tty, last_fps, now;
cairo_antialias_t antialias;
+ enum clip clip;
double scale = 0.1;
double factor = 1.05;
@@ -89,6 +93,7 @@ int main (int argc, char **argv)
device = device_open(argc, argv);
antialias = device_get_antialias(argc, argv);
+ clip = device_get_clip(argc, argv);
benchmark = device_get_benchmark(argc, argv);
if (benchmark == 0)
benchmark = 20;
@@ -97,7 +102,7 @@ int main (int argc, char **argv)
do {
struct framebuffer *fb = device->get_framebuffer (device);
- tiger (device, fb, antialias, scale, rotation);
+ tiger (device, fb, antialias, clip, scale, rotation);
gettimeofday(&now, NULL);
if (benchmark < 0 && last_fps.tv_sec) {