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

📄 cairo-pattern.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
/* cairo - a vector graphics library with display and print output * * Copyright © 2004 David Reveman * Copyright © 2005 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 David * Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. David Reveman makes no representations about the * suitability of this software for any purpose.  It is provided "as * is" without express or implied warranty. * * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL DAVID REVEMAN 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 <davidr@novell.com> *	    Keith Packard <keithp@keithp.com> *	    Carl Worth <cworth@cworth.org> */#include "cairoint.h"const cairo_solid_pattern_t cairo_pattern_nil = {    { CAIRO_PATTERN_TYPE_SOLID, 	/* type */      (unsigned int)-1,		/* ref_count */      CAIRO_STATUS_NO_MEMORY,	/* status */      { 1., 0., 0., 1., 0., 0., }, /* matrix */      CAIRO_FILTER_DEFAULT,	/* filter */      CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */};static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {    { CAIRO_PATTERN_TYPE_SOLID, 	/* type */      (unsigned int)-1,		/* ref_count */      CAIRO_STATUS_NULL_POINTER,/* status */      { 1., 0., 0., 1., 0., 0., }, /* matrix */      CAIRO_FILTER_DEFAULT,	/* filter */      CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */};static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {    { CAIRO_PATTERN_TYPE_SOLID, 	/* type */      (unsigned int)-1,		/* ref_count */      CAIRO_STATUS_FILE_NOT_FOUND, /* status */      { 1., 0., 0., 1., 0., 0., }, /* matrix */      CAIRO_FILTER_DEFAULT,	/* filter */      CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */};static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {    { CAIRO_PATTERN_TYPE_SOLID, 	/* type */      (unsigned int)-1,		/* ref_count */      CAIRO_STATUS_READ_ERROR,	/* status */      { 1., 0., 0., 1., 0., 0., }, /* matrix */      CAIRO_FILTER_DEFAULT,	/* filter */      CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */};static const cairo_pattern_t *_cairo_pattern_nil_for_status (cairo_status_t status){    switch (status) {    case CAIRO_STATUS_NULL_POINTER:	return &cairo_pattern_nil_null_pointer.base;    case CAIRO_STATUS_FILE_NOT_FOUND:	return &cairo_pattern_nil_file_not_found.base;    case CAIRO_STATUS_READ_ERROR:	return &cairo_pattern_nil_read_error.base;    default:    case CAIRO_STATUS_NO_MEMORY:	return &cairo_pattern_nil.base;    }}/** * _cairo_pattern_set_error: * @pattern: a pattern * @status: a status value indicating an error, (eg. not * CAIRO_STATUS_SUCCESS) * * Sets pattern->status to @status and calls _cairo_error; * * All assignments of an error status to pattern->status should happen * through _cairo_pattern_set_error() or else _cairo_error() should be * called immediately after the assignment. * * The purpose of this function is to allow the user to set a * breakpoint in _cairo_error() to generate a stack trace for when the * user causes cairo to detect an error. **/static void_cairo_pattern_set_error (cairo_pattern_t *pattern,			  cairo_status_t status){    /* Don't overwrite an existing error. This preserves the first     * error, which is the most significant. It also avoids attempting     * to write to read-only data (eg. from a nil pattern). */    if (pattern->status == CAIRO_STATUS_SUCCESS)	pattern->status = status;    _cairo_error (status);}static void_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type){    pattern->type      = type;    pattern->ref_count = 1;    pattern->status    = CAIRO_STATUS_SUCCESS;    if (type == CAIRO_PATTERN_TYPE_SURFACE)	pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;    else	pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;    pattern->filter    = CAIRO_FILTER_DEFAULT;    cairo_matrix_init_identity (&pattern->matrix);}static void_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t	  *pattern,				   const cairo_gradient_pattern_t *other){    if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)    {	cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;	cairo_linear_pattern_t *src = (cairo_linear_pattern_t *) other;	*dst = *src;    }    else    {	cairo_radial_pattern_t *dst = (cairo_radial_pattern_t *) pattern;	cairo_radial_pattern_t *src = (cairo_radial_pattern_t *) other;	*dst = *src;    }    if (other->n_stops)    {	pattern->stops = malloc (other->n_stops *				 sizeof (pixman_gradient_stop_t));	if (pattern->stops == NULL) {	    _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);	    return;	}	memcpy (pattern->stops, other->stops,		other->n_stops * sizeof (pixman_gradient_stop_t));    }}void_cairo_pattern_init_copy (cairo_pattern_t	*pattern,			  const cairo_pattern_t *other){    if (other->status) {	_cairo_pattern_set_error (pattern, other->status);	return;    }    switch (other->type) {    case CAIRO_PATTERN_TYPE_SOLID: {	cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern;	cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other;	*dst = *src;    } break;    case CAIRO_PATTERN_TYPE_SURFACE: {	cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern;	cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other;	*dst = *src;	cairo_surface_reference (dst->surface);    } break;    case CAIRO_PATTERN_TYPE_LINEAR:    case CAIRO_PATTERN_TYPE_RADIAL: {	cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;	cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;	_cairo_gradient_pattern_init_copy (dst, src);    } break;    }    pattern->ref_count = 1;}void_cairo_pattern_fini (cairo_pattern_t *pattern){    switch (pattern->type) {    case CAIRO_PATTERN_TYPE_SOLID:	break;    case CAIRO_PATTERN_TYPE_SURFACE: {	cairo_surface_pattern_t *surface_pattern =	    (cairo_surface_pattern_t *) pattern;	cairo_surface_destroy (surface_pattern->surface);    } break;    case CAIRO_PATTERN_TYPE_LINEAR:    case CAIRO_PATTERN_TYPE_RADIAL: {	cairo_gradient_pattern_t *gradient =	    (cairo_gradient_pattern_t *) pattern;	if (gradient->stops)	    free (gradient->stops);    } break;    }}void_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern,			   const cairo_color_t	 *color){    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID);    pattern->color = *color;}void_cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern,				 cairo_surface_t	 *surface){    if (surface->status) {	/* Force to solid to simplify the pattern_fini process. */	pattern->base.type = CAIRO_PATTERN_TYPE_SOLID;	_cairo_pattern_set_error (&pattern->base, surface->status);	return;    }    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SURFACE);    pattern->surface = cairo_surface_reference (surface);}static void_cairo_pattern_init_gradient (cairo_gradient_pattern_t *pattern,			      cairo_pattern_type_t     type){    _cairo_pattern_init (&pattern->base, type);    pattern->stops   = NULL;    pattern->n_stops = 0;}void_cairo_pattern_init_linear (cairo_linear_pattern_t *pattern,			    double x0, double y0, double x1, double y1){    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_LINEAR);    pattern->gradient.p1.x = _cairo_fixed_from_double (x0);    pattern->gradient.p1.y = _cairo_fixed_from_double (y0);    pattern->gradient.p2.x = _cairo_fixed_from_double (x1);    pattern->gradient.p2.y = _cairo_fixed_from_double (y1);}void_cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,			    double cx0, double cy0, double radius0,			    double cx1, double cy1, double radius1){    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_RADIAL);    pattern->gradient.inner.x	   = _cairo_fixed_from_double (cx0);    pattern->gradient.inner.y	   = _cairo_fixed_from_double (cy0);    pattern->gradient.inner.radius = _cairo_fixed_from_double (fabs (radius0));    pattern->gradient.outer.x	   = _cairo_fixed_from_double (cx1);    pattern->gradient.outer.y	   = _cairo_fixed_from_double (cy1);    pattern->gradient.outer.radius = _cairo_fixed_from_double (fabs (radius1));}cairo_pattern_t *_cairo_pattern_create_solid (const cairo_color_t *color){    cairo_solid_pattern_t *pattern;    pattern = malloc (sizeof (cairo_solid_pattern_t));    if (pattern == NULL)	return (cairo_pattern_t *) &cairo_pattern_nil.base;    _cairo_pattern_init_solid (pattern, color);    return &pattern->base;}/** * cairo_pattern_create_rgb: * @red: red component of the color * @green: green component of the color * @blue: blue component of the color * * Creates a new cairo_pattern_t corresponding to an opaque color.  The * color components are floating point numbers in the range 0 to 1. * If the values passed in are outside that range, they will be * clamped. * * Return value: the newly created #cairo_pattern_t if succesful, or * an error pattern in case of no memory.  The caller owns the * returned object and should call cairo_pattern_destroy() when * finished with it. * * This function will always return a valid pointer, but if an error * occurred the pattern status will be set to an error.  To inspect * the status of a pattern use cairo_pattern_status(). **/cairo_pattern_t *cairo_pattern_create_rgb (double red, double green, double blue){    cairo_pattern_t *pattern;    cairo_color_t color;    _cairo_restrict_value (&red,   0.0, 1.0);    _cairo_restrict_value (&green, 0.0, 1.0);    _cairo_restrict_value (&blue,  0.0, 1.0);    _cairo_color_init_rgb (&color, red, green, blue);    pattern = _cairo_pattern_create_solid (&color);    if (pattern->status)	_cairo_error (pattern->status);    return pattern;}/** * cairo_pattern_create_rgba: * @red: red component of the color * @green: green component of the color * @blue: blue component of the color * @alpha: alpha component of the color * * Creates a new cairo_pattern_t corresponding to a translucent color. * The color components are floating point numbers in the range 0 to * 1.  If the values passed in are outside that range, they will be * clamped. * * Return value: the newly created #cairo_pattern_t if succesful, or * an error pattern in case of no memory.  The caller owns the * returned object and should call cairo_pattern_destroy() when * finished with it. * * This function will always return a valid pointer, but if an error * occurred the pattern status will be set to an error.  To inspect * the status of a pattern use cairo_pattern_status(). **/cairo_pattern_t *cairo_pattern_create_rgba (double red, double green, double blue,			   double alpha){    cairo_pattern_t *pattern;    cairo_color_t color;    _cairo_restrict_value (&red,   0.0, 1.0);    _cairo_restrict_value (&green, 0.0, 1.0);    _cairo_restrict_value (&blue,  0.0, 1.0);    _cairo_restrict_value (&alpha, 0.0, 1.0);    _cairo_color_init_rgba (&color, red, green, blue, alpha);    pattern = _cairo_pattern_create_solid (&color);    if (pattern->status)	_cairo_error (pattern->status);    return pattern;}/** * cairo_pattern_create_for_surface: * @surface: the surface * * Create a new cairo_pattern_t for the given surface. * * Return value: the newly created #cairo_pattern_t if succesful, or * an error pattern in case of no memory.  The caller owns the * returned object and should call cairo_pattern_destroy() when * finished with it. * * This function will always return a valid pointer, but if an error * occurred the pattern status will be set to an error.  To inspect * the status of a pattern use cairo_pattern_status(). **/cairo_pattern_t *cairo_pattern_create_for_surface (cairo_surface_t *surface){    cairo_surface_pattern_t *pattern;    if (surface == NULL)	return (cairo_pattern_t*) _cairo_pattern_nil_for_status (CAIRO_STATUS_NULL_POINTER);    if (surface->status)	return (cairo_pattern_t*) _cairo_pattern_nil_for_status (surface->status);    pattern = malloc (sizeof (cairo_surface_pattern_t));    if (pattern == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_pattern_t *)&cairo_pattern_nil.base;    }    _cairo_pattern_init_for_surface (pattern, surface);    return &pattern->base;}/** * cairo_pattern_create_linear: * @x0: x coordinate of the start point * @y0: y coordinate of the start point * @x1: x coordinate of the end point * @y1: y coordinate of the end point * * Create a new linear gradient cairo_pattern_t along the line defined * by (x0, y0) and (x1, y1).  Before using the gradient pattern, a * number of color stops should be defined using * cairo_pattern_add_color_stop_rgb() or * cairo_pattern_add_color_stop_rgba(). * * Note: The coordinates here are in pattern space. For a new pattern, * pattern space is identical to user space, but the relationship * between the spaces can be changed with cairo_pattern_set_matrix(). * * Return value: the newly created #cairo_pattern_t if succesful, or * an error pattern in case of no memory.  The caller owns the * returned object and should call cairo_pattern_destroy() when * finished with it. * * This function will always return a valid pointer, but if an error * occurred the pattern status will be set to an error.  To inspect * the status of a pattern use cairo_pattern_status(). **/cairo_pattern_t *cairo_pattern_create_linear (double x0, double y0, double x1, double y1){    cairo_linear_pattern_t *pattern;    pattern = malloc (sizeof (cairo_linear_pattern_t));    if (pattern == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_pattern_t *) &cairo_pattern_nil.base;    }    _cairo_pattern_init_linear (pattern, x0, y0, x1, y1);    return &pattern->base.base;}/** * cairo_pattern_create_radial: * @cx0: x coordinate for the center of the start circle * @cy0: y coordinate for the center of the start circle * @radius0: radius of the start cirle * @cx1: x coordinate for the center of the end circle * @cy1: y coordinate for the center of the end circle * @radius1: radius of the end cirle * * Creates a new radial gradient cairo_pattern_t between the two * circles defined by (x0, y0, c0) and (x1, y1, c0).  Before using the * gradient pattern, a number of color stops should be defined using * cairo_pattern_add_color_stop_rgb() or * cairo_pattern_add_color_stop_rgba(). * * Note: The coordinates here are in pattern space. For a new pattern, * pattern space is identical to user space, but the relationship * between the spaces can be changed with cairo_pattern_set_matrix(). * * Return value: the newly created #cairo_pattern_t if succesful, or * an error pattern in case of no memory.  The caller owns the * returned object and should call cairo_pattern_destroy() when * finished with it. * * This function will always return a valid pointer, but if an error * occurred the pattern status will be set to an error.  To inspect * the status of a pattern use cairo_pattern_status(). **/cairo_pattern_t *cairo_pattern_create_radial (double cx0, double cy0, double radius0,			     double cx1, double cy1, double radius1){    cairo_radial_pattern_t *pattern;

⌨️ 快捷键说明

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