diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-13 23:09:39 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-13 23:09:39 +0100 |
commit | b4584da9fec1b05adfed29b95bf086aec14c860d (patch) | |
tree | 6ba9751106eb3721ca421fab37436fe77b3d7f8c | |
parent | cda9e7feaf46fad5dfe465c881c96f1e004c9e65 (diff) |
Add some rudimentary clipping variations
-rw-r--r-- | chart-demo.c | 7 | ||||
-rw-r--r-- | demo.c | 84 | ||||
-rw-r--r-- | demo.h | 10 | ||||
-rw-r--r-- | fish-demo.c | 5 | ||||
-rw-r--r-- | flowers-demo.c | 13 | ||||
-rw-r--r-- | glx.c | 29 | ||||
-rw-r--r-- | tiger-demo.c | 7 |
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); @@ -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); +} @@ -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); @@ -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) { |