summaryrefslogtreecommitdiff
path: root/cairogears.c
diff options
context:
space:
mode:
Diffstat (limited to 'cairogears.c')
-rw-r--r--cairogears.c317
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);
+}