⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-test.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright © 2004 Red Hat, Inc. * * 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 name of * Red Hat, Inc. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Red Hat, Inc. makes no representations about the * suitability of this software for any purpose.  It is provided "as * is" without express or implied warranty. * * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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. * * Author: Carl D. Worth <cworth@cworth.org> */#if HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#include <assert.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <errno.h>#include <string.h>#if HAVE_FCFINI#include <fontconfig/fontconfig.h>#endif#include "cairo-test.h"#include "buffer-diff.h"#include "read-png.h"#include "write-png.h"#include "xmalloc.h"/* This is copied from cairoint.h. That makes it painful to keep in * sync, but the slim stuff makes cairoint.h "hard" to include when * not actually building the cairo library itself. Fortunately, since * we're checking all these values, we do have a safeguard for keeping * them in sync. */typedef enum cairo_internal_surface_type {    CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,    CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,    CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,    CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,    CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED} cairo_internal_surface_type_t;#ifdef _MSC_VER#define vsnprintf _vsnprintf#define access _access#define F_OK 0#endif#ifndef FALSE#define FALSE 0#endif#ifndef TRUE#define TRUE !FALSE#endifstatic voidxunlink (const char *pathname);static const char *fail_face = "", *normal_face = "";#define CAIRO_TEST_LOG_SUFFIX ".log"#define CAIRO_TEST_PNG_SUFFIX "-out.png"#define CAIRO_TEST_REF_SUFFIX "-ref.png"#define CAIRO_TEST_DIFF_SUFFIX "-diff.png"#define NUM_DEVICE_OFFSETS 2/* A fake format we use for the flattened ARGB output of the PS and * PDF surfaces. */#define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED -1/* Static data is messy, but we're coding for tests here, not a * general-purpose library, and it keeps the tests cleaner to avoid a * context object there, (though not a whole lot). */FILE *cairo_test_log_file = NULL;char *srcdir;/* Used to catch crashes in a test, such that we report it as such and * continue testing, although one crasher may already have corrupted memory in * an nonrecoverable fashion. */jmp_buf jmpbuf;voidcairo_test_init (const char *test_name){    char *log_name;    xasprintf (&log_name, "%s%s", test_name, CAIRO_TEST_LOG_SUFFIX);    xunlink (log_name);    cairo_test_log_file = fopen (log_name, "a");    if (cairo_test_log_file == NULL) {	fprintf (stderr, "Error opening log file: %s\n", log_name);	cairo_test_log_file = stderr;    }    free (log_name);}voidcairo_test_log (const char *fmt, ...){    va_list va;    FILE *file = cairo_test_log_file ? cairo_test_log_file : stderr;    va_start (va, fmt);    vfprintf (file, fmt, va);    va_end (va);}voidxasprintf (char **strp, const char *fmt, ...){#ifdef HAVE_VASPRINTF    va_list va;    int ret;    va_start (va, fmt);    ret = vasprintf (strp, fmt, va);    va_end (va);    if (ret < 0) {	cairo_test_log ("Out of memory\n");	exit (1);    }#else /* !HAVE_VASNPRINTF */#define BUF_SIZE 1024    va_list va;    char buffer[BUF_SIZE];    int ret;    va_start (va, fmt);    ret = vsnprintf (buffer, sizeof(buffer), fmt, va);    va_end (va);    if (ret < 0) {	cairo_test_log ("Failure in vsnprintf\n");	exit (1);    }    if (strlen (buffer) == sizeof(buffer) - 1) {	cairo_test_log ("Overflowed fixed buffer\n");	exit (1);    }    *strp = strdup (buffer);    if (!*strp) {	cairo_test_log ("Out of memory\n");	exit (1);    }#endif /* !HAVE_VASNPRINTF */}static voidxunlink (const char *pathname){    if (unlink (pathname) < 0 && errno != ENOENT) {	cairo_test_log ("  Error: Cannot remove %s: %s\n",			pathname, strerror (errno));	exit (1);    }}typedef cairo_surface_t *(*cairo_test_create_target_surface_t) (cairo_test_t	 *test,				       cairo_content_t	  content,				       void		**closure);typedef cairo_status_t(*cairo_test_write_to_png_t) (cairo_surface_t *surface, const char *filename);typedef void(*cairo_test_cleanup_target_t) (void *closure);typedef struct _cairo_test_target{    const char		       	       *name;    cairo_surface_type_t		expected_type;    cairo_content_t			content;    cairo_test_create_target_surface_t	create_target_surface;    cairo_test_write_to_png_t		write_to_png;    cairo_test_cleanup_target_t		cleanup_target;    void			       *closure;} cairo_test_target_t;static char *_cairo_test_content_name (cairo_content_t content){    switch (content) {    case CAIRO_CONTENT_COLOR:	return "rgb24";    case CAIRO_CONTENT_COLOR_ALPHA:    case CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED:	return "argb32";    default:	assert (0); /* not reached */	return "---";    }}static cairo_surface_t *create_image_surface (cairo_test_t	 *test,		      cairo_content_t	  content,		      void		**closure){    cairo_format_t format;    *closure = NULL;    if (content == CAIRO_CONTENT_COLOR_ALPHA) {	format = CAIRO_FORMAT_ARGB32;    } else if (content == CAIRO_CONTENT_COLOR) {	format = CAIRO_FORMAT_RGB24;    } else {	assert (0); /* not reached */	return NULL;    }    return cairo_image_surface_create (format, test->width, test->height);}#ifdef CAIRO_HAS_TEST_SURFACES#include "test-fallback-surface.h"#include "test-meta-surface.h"#include "test-paginated-surface.h"static cairo_surface_t *create_test_fallback_surface (cairo_test_t	 *test,			      cairo_content_t	  content,			      void		**closure){    *closure = NULL;    return _test_fallback_surface_create (content, test->width, test->height);}static cairo_surface_t *create_test_meta_surface (cairo_test_t		 *test,			  cairo_content_t	  content,			  void			**closure){    *closure = NULL;    return _test_meta_surface_create (content, test->width, test->height);}static const cairo_user_data_key_t test_paginated_closure_key;typedef struct {    unsigned char *data;    cairo_content_t content;    int width;    int height;    int stride;} test_paginated_closure_t;static cairo_surface_t *create_test_paginated_surface (cairo_test_t	 *test,			       cairo_content_t	  content,			       void		**closure){    test_paginated_closure_t *tpc;    cairo_surface_t *surface;    *closure = tpc = xmalloc (sizeof (test_paginated_closure_t));    tpc->content = content;    tpc->width = test->width;    tpc->height = test->height;    tpc->stride = test->width * 4;    tpc->data = xcalloc (tpc->stride * test->height, 1);    surface = _test_paginated_surface_create_for_data (tpc->data,						       tpc->content,						       tpc->width,						       tpc->height,						       tpc->stride);    cairo_surface_set_user_data (surface, &test_paginated_closure_key,				 tpc, NULL);    return surface;}/* The only reason we go through all these machinations to write a PNG * image is to _really ensure_ that the data actually landed in our * buffer through the paginated surface to the test_paginated_surface. * * If we didn't implement this function then the default * cairo_surface_write_to_png would result in the paginated_surface's * acquire_source_image function replaying the meta-surface to an * intermediate image surface. And in that case the * test_paginated_surface would not be involved and wouldn't be * tested. */static cairo_status_ttest_paginated_write_to_png (cairo_surface_t *surface,			     const char	     *filename){    cairo_surface_t *image;    cairo_format_t format;    test_paginated_closure_t *tpc;    tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);    switch (tpc->content) {    case CAIRO_CONTENT_COLOR:	format = CAIRO_FORMAT_RGB24;	break;    case CAIRO_CONTENT_COLOR_ALPHA:	format = CAIRO_FORMAT_ARGB32;	break;    default:	assert (0); /* not reached */	return CAIRO_STATUS_NO_MEMORY;    }    image = cairo_image_surface_create_for_data (tpc->data,						 format,						 tpc->width,						 tpc->height,						 tpc->stride);    cairo_surface_write_to_png (image, filename);    cairo_surface_destroy (image);    return CAIRO_STATUS_SUCCESS;}static voidcleanup_test_paginated (void *closure){    test_paginated_closure_t *tpc = closure;    free (tpc->data);    free (tpc);}#endif#ifdef CAIRO_HAS_GLITZ_SURFACE#include <glitz.h>#include <cairo-glitz.h>static const cairo_user_data_key_t glitz_closure_key;typedef struct _glitz_target_closure_base {    int width;    int height;    cairo_content_t content;} glitz_target_closure_base_t;#if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE#include <glitz-glx.h>typedef struct _glitz_glx_target_closure {    glitz_target_closure_base_t base;    Display        *dpy;    int             scr;    Window          win;} glitz_glx_target_closure_t;static glitz_surface_t *create_glitz_glx_surface (glitz_format_name_t	      formatname,			  int			      width,			  int			      height,			  glitz_glx_target_closure_t *closure){    Display                 * dpy = closure->dpy;    int                       scr = closure->scr;    glitz_drawable_format_t   templ;    glitz_drawable_format_t * dformat = NULL;    unsigned long             mask;    glitz_drawable_t        * drawable = NULL;    glitz_format_t          * format;    glitz_surface_t         * sr;    XSizeHints                xsh;    XSetWindowAttributes      xswa;    XVisualInfo             * vinfo;    memset(&templ, 0, sizeof(templ));    templ.color.red_size = 8;    templ.color.green_size = 8;    templ.color.blue_size = 8;    templ.color.alpha_size = 8;    templ.color.fourcc = GLITZ_FOURCC_RGB;    templ.samples = 1;    glitz_glx_init (NULL);    mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_FOURCC_MASK |	GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |	GLITZ_FORMAT_BLUE_SIZE_MASK;    if (formatname == GLITZ_STANDARD_ARGB32)	mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK;    /* Try for a pbuffer first */    if (!getenv("CAIRO_TEST_FORCE_GLITZ_WINDOW"))	dformat = glitz_glx_find_pbuffer_format (dpy, scr, mask, &templ, 0);    if (dformat) {	closure->win = None;	drawable = glitz_glx_create_pbuffer_drawable (dpy, scr, dformat,						      width, height);	if (!drawable)	    goto FAIL;    } else {	/* No pbuffer, try window */	dformat = glitz_glx_find_window_format (dpy, scr, mask, &templ, 0);	if (!dformat)	    goto FAIL;	vinfo = glitz_glx_get_visual_info_from_format(dpy,						      DefaultScreen(dpy),						      dformat);	if (!vinfo)	    goto FAIL;	xsh.flags = PSize;	xsh.x = 0;	xsh.y = 0;	xsh.width = width;	xsh.height = height;	xswa.colormap = XCreateColormap (dpy, RootWindow(dpy, scr),					 vinfo->visual, AllocNone);	closure->win = XCreateWindow (dpy, RootWindow(dpy, scr),				      xsh.x, xsh.y, xsh.width, xsh.height,				      0, vinfo->depth, CopyFromParent,				      vinfo->visual, CWColormap, &xswa);	XFree (vinfo);	drawable =	    glitz_glx_create_drawable_for_window (dpy, scr,						  dformat, closure->win,						  width, height);	if (!drawable)	    goto DESTROY_WINDOW;    }    format = glitz_find_standard_format (drawable, formatname);    if (!format)	goto DESTROY_DRAWABLE;    sr = glitz_surface_create (drawable, format, width, height, 0, NULL);    if (!sr)	goto DESTROY_DRAWABLE;    if (closure->win == None || dformat->doublebuffer) {	glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_BACK_COLOR);    } else {	XMapWindow (closure->dpy, closure->win);	glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);    }    glitz_drawable_destroy (drawable);    return sr; DESTROY_DRAWABLE:    glitz_drawable_destroy (drawable); DESTROY_WINDOW:    if (closure->win)	XDestroyWindow (dpy, closure->win); FAIL:    return NULL;}static cairo_surface_t *create_cairo_glitz_glx_surface (cairo_test_t   *test,				cairo_content_t content,				void          **closure){    int width = test->width;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -