diff options
Diffstat (limited to 'cairogears.c')
-rw-r--r-- | cairogears.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/cairogears.c b/cairogears.c new file mode 100644 index 0000000..f3a16f9 --- /dev/null +++ b/cairogears.c @@ -0,0 +1,317 @@ +/* + * Copyright © 2004 David Reveman, Peter Nilsson + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the names of + * David Reveman and Peter Nilsson not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. David Reveman and Peter Nilsson + * makes no representations about the suitability of this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND + * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: David Reveman <c99drn@cs.umu.se> + * Peter Nilsson <c99pnn@cs.umu.se> + */ + +#include <cairo.h> +#include <cairo-xlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <math.h> +#include <strings.h> + +#define PACKAGE "cairogears" + +#define WINDOW_WIDTH 512 +#define WINDOW_HEIGHT 512 + +void trap_setup (cairo_surface_t *target, int w, int h); +void trap_render (cairo_t *cr, int w, int h); + +void comp_setup (cairo_surface_t *target, int w, int h); +void comp_render (cairo_t *cr, int w, int h); + +void text_setup (cairo_surface_t *target, int w, int h); +void text_render (cairo_t *cr, int w, int h); + +void text2_setup (cairo_surface_t *target, int w, int h); +void text2_render (cairo_t *cr, int w, int h); + +void shadow_setup (cairo_surface_t *target, int w, int h); +void shadow_render (cairo_t *cr, int w, int h); + +static enum { + XRENDER_TYPE, + IMAGE_TYPE +} output_type = XRENDER_TYPE; +static const char *backend = "image"; + +static enum { + NONE, + STROKE_AND_FILL_TYPE, + COMPOSITE_AND_TRANSFORM_TYPE, + TEXT_PATH_TYPE, + TEXT_BITMAP_TYPE, + SHADOW_TYPE +} test_type = NONE; +static const char *test = "gradient"; + +static const char *program_name; + +static Display *dpy; +static Window win; +static XWMHints xwmh = { + (InputHint|StateHint), + False, + NormalState, + 0, + 0, + 0, 0, + 0, + 0, +}; + +static cairo_t *cr; +static cairo_surface_t *win_surface; +static cairo_surface_t *surface; + +static unsigned int frame_cnt = 0; + +int fast = 0; +int fill_gradient = 0; +int aa = -1; + +extern unsigned int glyph_cnt; + +void +usage(void) +{ + + printf ("Usage: %s [-image | -xrender] TEST\n\n" + "\tThe following tests are available:\n\n" + "\tTRAP Trapezoid fill test\n" + "\tGRAD Trapezoid gradient test\n" + "\tCOMP Composite and transform test\n" + "\tTEXT Text path test\n" + "\tTEXT2 Text bitmap test\n" + "\tSHADOW Composite with mask and convolution filter test\n\n", + program_name); +} + +void alarmhandler (int sig) { + if (sig == SIGALRM) { + if (test_type == TEXT_BITMAP_TYPE) { + printf ("%s - %s: %d glyphs in 5.0 seconds = %.3f GPS\n", + backend, test, + glyph_cnt, glyph_cnt / 5.0); + glyph_cnt = 0; + } + printf ("%s - %s: %d frames in 5.0 seconds = %.3f FPS\n", + backend, test, + frame_cnt, frame_cnt / 5.0); + frame_cnt = 0; + } + signal (SIGALRM, alarmhandler); + alarm(5); +} + +int +main (int argc, char **argv) { + + XEvent event; + XSizeHints xsh; + XSetWindowAttributes xswa; + + unsigned int width, height, window_width, window_height; + int i; + + program_name = argv[0]; + + for (i = 1; i < argc; i++) { + if (!strcasecmp ("-image", argv[i])) { + output_type = IMAGE_TYPE; + backend = "image"; + } else if (!strcasecmp ("-xrender", argv[i])) { + output_type = XRENDER_TYPE; + backend = "xrender"; + } else if (!strcasecmp ("TRAP", argv[i])) { + test_type = STROKE_AND_FILL_TYPE; + test = "trapezoids"; + } else if (!strcasecmp ("GRAD", argv[i])) { + test_type = STROKE_AND_FILL_TYPE; + fill_gradient = 1; + test = "gradient"; + } else if (!strcasecmp ("COMP", argv[i])) { + test_type = COMPOSITE_AND_TRANSFORM_TYPE; + test = "composite"; + } else if (!strcasecmp ("TEXT", argv[i])) { + test_type = TEXT_PATH_TYPE; + test = "text"; + } else if (!strcasecmp ("TEXT2", argv[i])) { + test_type = TEXT_BITMAP_TYPE; + test = "text2"; + } else if (!strcasecmp ("SHADOW", argv[i])) { + test_type = SHADOW_TYPE; + test = "shadow"; + } else { + fprintf (stderr, "%s: unrecognized option `%s'\n", + argv[0], argv[i]); + usage(); + exit(1); + } + } + + if (!test_type) { + usage(); + exit(1); + } + + window_width = width = WINDOW_WIDTH; + window_height = height = WINDOW_HEIGHT; + + if ((dpy = XOpenDisplay (NULL)) == NULL) { + fprintf(stderr, "%s: can't open display: %s\n", argv[0], + XDisplayName (NULL)); + exit(1); + } + + xsh.flags = PSize; + xsh.width = width; + xsh.height = height; + xsh.x = 0; + xsh.y = 0; + + win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)), + xsh.x, xsh.y, xsh.width, xsh.height, + 0, CopyFromParent, CopyFromParent, + CopyFromParent, 0, &xswa); + + XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None, + argv, argc, &xsh); + XSetWMHints (dpy, win, &xwmh); + + XSelectInput (dpy, win, StructureNotifyMask); + + win_surface = cairo_xlib_surface_create (dpy, win, + DefaultVisual (dpy, DefaultScreen (dpy)), + width, height); + switch (output_type) { + case XRENDER_TYPE: + surface = cairo_surface_create_similar (win_surface, + CAIRO_CONTENT_COLOR_ALPHA, width, height); + break; + + case IMAGE_TYPE: + surface = cairo_image_surface_create ( + CAIRO_FORMAT_ARGB32, width, height); + break; + } + + cr = cairo_create (surface); + cairo_set_tolerance (cr, 0.5); + + switch (test_type) { + case STROKE_AND_FILL_TYPE: + trap_setup (surface, width, height); + break; + case COMPOSITE_AND_TRANSFORM_TYPE: + comp_setup (surface, width, height); + break; + case TEXT_PATH_TYPE: + text_setup (surface, width, height); + break; + case TEXT_BITMAP_TYPE: + text2_setup (surface, width, height); + break; + case SHADOW_TYPE: + shadow_setup (surface, width, height); + break; + } + + signal (SIGALRM, alarmhandler); + alarm (5); + + XMapWindow (dpy, win); + + if (test_type == TEXT_BITMAP_TYPE) { + XSync (dpy, False); + usleep (200000); + XSync (dpy, False); + } + + for (;;) { + if (XPending (dpy)) { + XNextEvent (dpy, &event); + if (event.type == ConfigureNotify) { + width = event.xconfigure.width; + height = event.xconfigure.height; + + cairo_xlib_surface_set_size (win_surface, width, height); + cairo_surface_destroy (surface); + switch (output_type) { + case XRENDER_TYPE: + surface = cairo_surface_create_similar (win_surface, + CAIRO_CONTENT_COLOR_ALPHA, width, height); + + + break; + + case IMAGE_TYPE: + surface = cairo_image_surface_create ( + CAIRO_FORMAT_ARGB32, width, height); + break; + } + } + + cairo_destroy (cr); + cr = cairo_create (surface); + cairo_set_tolerance (cr, 0.5); + } else { + switch (test_type) { + case STROKE_AND_FILL_TYPE: + trap_render (cr, width, height); + break; + case COMPOSITE_AND_TRANSFORM_TYPE: + comp_render (cr, width, height); + break; + case TEXT_PATH_TYPE: + text_render (cr, width, height); + break; + case TEXT_BITMAP_TYPE: + text2_render (cr, width, height); + break; + case SHADOW_TYPE: + shadow_render (cr, width, height); + break; + } + + { + cairo_t *cr2 = cairo_create (win_surface); + cairo_set_source_surface (cr2, surface, 0, 0); + cairo_paint (cr2); + cairo_destroy (cr2); + } + + frame_cnt++; + } + } + + exit (1); +} |