Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
  2. /* cairo - a vector graphics library with display and print output
  3.  *
  4.  * Copyright © 2004 David Reveman
  5.  * Copyright © 2005 Red Hat, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software
  8.  * and its documentation for any purpose is hereby granted without
  9.  * fee, provided that the above copyright notice appear in all copies
  10.  * and that both that copyright notice and this permission notice
  11.  * appear in supporting documentation, and that the name of David
  12.  * Reveman not be used in advertising or publicity pertaining to
  13.  * distribution of the software without specific, written prior
  14.  * permission. David Reveman makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as
  16.  * is" without express or implied warranty.
  17.  *
  18.  * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  19.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20.  * FITNESS, IN NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL,
  21.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  22.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  23.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  24.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * Authors: David Reveman <davidr@novell.com>
  27.  *          Keith Packard <keithp@keithp.com>
  28.  *          Carl Worth <cworth@cworth.org>
  29.  */
  30.  
  31. #include "cairoint.h"
  32.  
  33. #include "cairo-array-private.h"
  34. #include "cairo-error-private.h"
  35. #include "cairo-freed-pool-private.h"
  36. #include "cairo-image-surface-private.h"
  37. #include "cairo-list-inline.h"
  38. #include "cairo-path-private.h"
  39. #include "cairo-pattern-private.h"
  40. #include "cairo-recording-surface-inline.h"
  41. #include "cairo-surface-snapshot-inline.h"
  42.  
  43. #include <float.h>
  44.  
  45. #define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
  46.  
  47. /**
  48.  * SECTION:cairo-pattern
  49.  * @Title: cairo_pattern_t
  50.  * @Short_Description: Sources for drawing
  51.  * @See_Also: #cairo_t, #cairo_surface_t
  52.  *
  53.  * #cairo_pattern_t is the paint with which cairo draws.
  54.  * The primary use of patterns is as the source for all cairo drawing
  55.  * operations, although they can also be used as masks, that is, as the
  56.  * brush too.
  57.  *
  58.  * A cairo pattern is created by using one of the many constructors,
  59.  * of the form
  60.  * <function>cairo_pattern_create_<emphasis>type</emphasis>()</function>
  61.  * or implicitly through
  62.  * <function>cairo_set_source_<emphasis>type</emphasis>()</function>
  63.  * functions.
  64.  **/
  65.  
  66. static freed_pool_t freed_pattern_pool[5];
  67.  
  68. static const cairo_solid_pattern_t _cairo_pattern_nil = {
  69.     {
  70.       CAIRO_REFERENCE_COUNT_INVALID,    /* ref_count */
  71.       CAIRO_STATUS_NO_MEMORY,           /* status */
  72.       { 0, 0, 0, NULL },                /* user_data */
  73.       { NULL, NULL },                   /* observers */
  74.  
  75.       CAIRO_PATTERN_TYPE_SOLID,         /* type */
  76.       CAIRO_FILTER_DEFAULT,             /* filter */
  77.       CAIRO_EXTEND_GRADIENT_DEFAULT,    /* extend */
  78.       FALSE,                            /* has component alpha */
  79.       { 1., 0., 0., 1., 0., 0., },      /* matrix */
  80.       1.0                               /* opacity */
  81.     }
  82. };
  83.  
  84. static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
  85.     {
  86.       CAIRO_REFERENCE_COUNT_INVALID,    /* ref_count */
  87.       CAIRO_STATUS_NULL_POINTER,        /* status */
  88.       { 0, 0, 0, NULL },                /* user_data */
  89.       { NULL, NULL },                   /* observers */
  90.  
  91.       CAIRO_PATTERN_TYPE_SOLID,         /* type */
  92.       CAIRO_FILTER_DEFAULT,             /* filter */
  93.       CAIRO_EXTEND_GRADIENT_DEFAULT,    /* extend */
  94.       FALSE,                            /* has component alpha */
  95.       { 1., 0., 0., 1., 0., 0., },      /* matrix */
  96.       1.0                               /* opacity */
  97.     }
  98. };
  99.  
  100. const cairo_solid_pattern_t _cairo_pattern_black = {
  101.     {
  102.       CAIRO_REFERENCE_COUNT_INVALID,    /* ref_count */
  103.       CAIRO_STATUS_SUCCESS,             /* status */
  104.       { 0, 0, 0, NULL },                /* user_data */
  105.       { NULL, NULL },                   /* observers */
  106.  
  107.       CAIRO_PATTERN_TYPE_SOLID,         /* type */
  108.       CAIRO_FILTER_NEAREST,             /* filter */
  109.       CAIRO_EXTEND_REPEAT,              /* extend */
  110.       FALSE,                            /* has component alpha */
  111.       { 1., 0., 0., 1., 0., 0., },      /* matrix */
  112.       1.0                               /* opacity */
  113.     },
  114.     { 0., 0., 0., 1., 0, 0, 0, 0xffff },/* color (double rgba, short rgba) */
  115. };
  116.  
  117. const cairo_solid_pattern_t _cairo_pattern_clear = {
  118.     {
  119.       CAIRO_REFERENCE_COUNT_INVALID,    /* ref_count */
  120.       CAIRO_STATUS_SUCCESS,             /* status */
  121.       { 0, 0, 0, NULL },                /* user_data */
  122.       { NULL, NULL },                   /* observers */
  123.  
  124.       CAIRO_PATTERN_TYPE_SOLID,         /* type */
  125.       CAIRO_FILTER_NEAREST,             /* filter */
  126.       CAIRO_EXTEND_REPEAT,              /* extend */
  127.       FALSE,                            /* has component alpha */
  128.       { 1., 0., 0., 1., 0., 0., },      /* matrix */
  129.       1.0                               /* opacity */
  130.     },
  131.     { 0., 0., 0., 0., 0, 0, 0, 0 },/* color (double rgba, short rgba) */
  132. };
  133.  
  134. const cairo_solid_pattern_t _cairo_pattern_white = {
  135.     {
  136.       CAIRO_REFERENCE_COUNT_INVALID,    /* ref_count */
  137.       CAIRO_STATUS_SUCCESS,             /* status */
  138.       { 0, 0, 0, NULL },                /* user_data */
  139.       { NULL, NULL },                   /* observers */
  140.  
  141.       CAIRO_PATTERN_TYPE_SOLID,         /* type */
  142.       CAIRO_FILTER_NEAREST,             /* filter */
  143.       CAIRO_EXTEND_REPEAT,              /* extend */
  144.       FALSE,                            /* has component alpha */
  145.       { 1., 0., 0., 1., 0., 0., },      /* matrix */
  146.       1.0                               /* opacity */
  147.     },
  148.     { 1., 1., 1., 1., 0xffff, 0xffff, 0xffff, 0xffff },/* color (double rgba, short rgba) */
  149. };
  150.  
  151. static void
  152. _cairo_pattern_notify_observers (cairo_pattern_t *pattern,
  153.                                  unsigned int flags)
  154. {
  155.     cairo_pattern_observer_t *pos;
  156.  
  157.     cairo_list_foreach_entry (pos, cairo_pattern_observer_t, &pattern->observers, link)
  158.         pos->notify (pos, pattern, flags);
  159. }
  160.  
  161. /**
  162.  * _cairo_pattern_set_error:
  163.  * @pattern: a pattern
  164.  * @status: a status value indicating an error
  165.  *
  166.  * Atomically sets pattern->status to @status and calls _cairo_error;
  167.  * Does nothing if status is %CAIRO_STATUS_SUCCESS.
  168.  *
  169.  * All assignments of an error status to pattern->status should happen
  170.  * through _cairo_pattern_set_error(). Note that due to the nature of
  171.  * the atomic operation, it is not safe to call this function on the nil
  172.  * objects.
  173.  *
  174.  * The purpose of this function is to allow the user to set a
  175.  * breakpoint in _cairo_error() to generate a stack trace for when the
  176.  * user causes cairo to detect an error.
  177.  **/
  178. static cairo_status_t
  179. _cairo_pattern_set_error (cairo_pattern_t *pattern,
  180.                           cairo_status_t status)
  181. {
  182.     if (status == CAIRO_STATUS_SUCCESS)
  183.         return status;
  184.  
  185.     /* Don't overwrite an existing error. This preserves the first
  186.      * error, which is the most significant. */
  187.     _cairo_status_set_error (&pattern->status, status);
  188.  
  189.     return _cairo_error (status);
  190. }
  191.  
  192. void
  193. _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
  194. {
  195. #if HAVE_VALGRIND
  196.     switch (type) {
  197.     case CAIRO_PATTERN_TYPE_SOLID:
  198.         VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t));
  199.         break;
  200.     case CAIRO_PATTERN_TYPE_SURFACE:
  201.         VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t));
  202.         break;
  203.     case CAIRO_PATTERN_TYPE_LINEAR:
  204.         VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t));
  205.         break;
  206.     case CAIRO_PATTERN_TYPE_RADIAL:
  207.         VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t));
  208.         break;
  209.     case CAIRO_PATTERN_TYPE_MESH:
  210.         VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t));
  211.         break;
  212.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  213.         break;
  214.     }
  215. #endif
  216.  
  217.     pattern->type      = type;
  218.     pattern->status    = CAIRO_STATUS_SUCCESS;
  219.  
  220.     /* Set the reference count to zero for on-stack patterns.
  221.      * Callers needs to explicitly increment the count for heap allocations. */
  222.     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
  223.  
  224.     _cairo_user_data_array_init (&pattern->user_data);
  225.  
  226.     if (type == CAIRO_PATTERN_TYPE_SURFACE ||
  227.         type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
  228.         pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;
  229.     else
  230.         pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
  231.  
  232.     pattern->filter    = CAIRO_FILTER_DEFAULT;
  233.     pattern->opacity   = 1.0;
  234.  
  235.     pattern->has_component_alpha = FALSE;
  236.  
  237.     cairo_matrix_init_identity (&pattern->matrix);
  238.  
  239.     cairo_list_init (&pattern->observers);
  240. }
  241.  
  242. static cairo_status_t
  243. _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t       *pattern,
  244.                                    const cairo_gradient_pattern_t *other)
  245. {
  246.     if (CAIRO_INJECT_FAULT ())
  247.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  248.  
  249.     if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)
  250.     {
  251.         cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;
  252.         cairo_linear_pattern_t *src = (cairo_linear_pattern_t *) other;
  253.  
  254.         *dst = *src;
  255.     }
  256.     else
  257.     {
  258.         cairo_radial_pattern_t *dst = (cairo_radial_pattern_t *) pattern;
  259.         cairo_radial_pattern_t *src = (cairo_radial_pattern_t *) other;
  260.  
  261.         *dst = *src;
  262.     }
  263.  
  264.     if (other->stops == other->stops_embedded)
  265.         pattern->stops = pattern->stops_embedded;
  266.     else if (other->stops)
  267.     {
  268.         pattern->stops = _cairo_malloc_ab (other->stops_size,
  269.                                            sizeof (cairo_gradient_stop_t));
  270.         if (unlikely (pattern->stops == NULL)) {
  271.             pattern->stops_size = 0;
  272.             pattern->n_stops = 0;
  273.             return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
  274.         }
  275.  
  276.         memcpy (pattern->stops, other->stops,
  277.                 other->n_stops * sizeof (cairo_gradient_stop_t));
  278.     }
  279.  
  280.     return CAIRO_STATUS_SUCCESS;
  281. }
  282.  
  283. static cairo_status_t
  284. _cairo_mesh_pattern_init_copy (cairo_mesh_pattern_t       *pattern,
  285.                                const cairo_mesh_pattern_t *other)
  286. {
  287.     *pattern = *other;
  288.  
  289.     _cairo_array_init (&pattern->patches,  sizeof (cairo_mesh_patch_t));
  290.     return _cairo_array_append_multiple (&pattern->patches,
  291.                                          _cairo_array_index_const (&other->patches, 0),
  292.                                          _cairo_array_num_elements (&other->patches));
  293. }
  294.  
  295. cairo_status_t
  296. _cairo_pattern_init_copy (cairo_pattern_t       *pattern,
  297.                           const cairo_pattern_t *other)
  298. {
  299.     cairo_status_t status;
  300.  
  301.     if (other->status)
  302.         return _cairo_pattern_set_error (pattern, other->status);
  303.  
  304.     switch (other->type) {
  305.     case CAIRO_PATTERN_TYPE_SOLID: {
  306.         cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern;
  307.         cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other;
  308.  
  309.         VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t)));
  310.  
  311.         *dst = *src;
  312.     } break;
  313.     case CAIRO_PATTERN_TYPE_SURFACE: {
  314.         cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern;
  315.         cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other;
  316.  
  317.         VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t)));
  318.  
  319.         *dst = *src;
  320.         cairo_surface_reference (dst->surface);
  321.     } break;
  322.     case CAIRO_PATTERN_TYPE_LINEAR:
  323.     case CAIRO_PATTERN_TYPE_RADIAL: {
  324.         cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
  325.         cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
  326.  
  327.         if (other->type == CAIRO_PATTERN_TYPE_LINEAR) {
  328.             VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t)));
  329.         } else {
  330.             VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t)));
  331.         }
  332.  
  333.         status = _cairo_gradient_pattern_init_copy (dst, src);
  334.         if (unlikely (status))
  335.             return status;
  336.  
  337.     } break;
  338.     case CAIRO_PATTERN_TYPE_MESH: {
  339.         cairo_mesh_pattern_t *dst = (cairo_mesh_pattern_t *) pattern;
  340.         cairo_mesh_pattern_t *src = (cairo_mesh_pattern_t *) other;
  341.  
  342.         VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t)));
  343.  
  344.         status = _cairo_mesh_pattern_init_copy (dst, src);
  345.         if (unlikely (status))
  346.             return status;
  347.  
  348.     } break;
  349.  
  350.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE: {
  351.         status = _cairo_raster_source_pattern_init_copy (pattern, other);
  352.         if (unlikely (status))
  353.             return status;
  354.     } break;
  355.     }
  356.  
  357.     /* The reference count and user_data array are unique to the copy. */
  358.     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
  359.     _cairo_user_data_array_init (&pattern->user_data);
  360.  
  361.     return CAIRO_STATUS_SUCCESS;
  362. }
  363.  
  364. void
  365. _cairo_pattern_init_static_copy (cairo_pattern_t        *pattern,
  366.                                  const cairo_pattern_t *other)
  367. {
  368.     int size;
  369.  
  370.     assert (other->status == CAIRO_STATUS_SUCCESS);
  371.  
  372.     switch (other->type) {
  373.     default:
  374.         ASSERT_NOT_REACHED;
  375.     case CAIRO_PATTERN_TYPE_SOLID:
  376.         size = sizeof (cairo_solid_pattern_t);
  377.         break;
  378.     case CAIRO_PATTERN_TYPE_SURFACE:
  379.         size = sizeof (cairo_surface_pattern_t);
  380.         break;
  381.     case CAIRO_PATTERN_TYPE_LINEAR:
  382.         size = sizeof (cairo_linear_pattern_t);
  383.         break;
  384.     case CAIRO_PATTERN_TYPE_RADIAL:
  385.         size = sizeof (cairo_radial_pattern_t);
  386.         break;
  387.     case CAIRO_PATTERN_TYPE_MESH:
  388.         size = sizeof (cairo_mesh_pattern_t);
  389.         break;
  390.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  391.         size = sizeof (cairo_raster_source_pattern_t);
  392.         break;
  393.     }
  394.  
  395.     memcpy (pattern, other, size);
  396.  
  397.     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
  398.     _cairo_user_data_array_init (&pattern->user_data);
  399. }
  400.  
  401. cairo_status_t
  402. _cairo_pattern_init_snapshot (cairo_pattern_t       *pattern,
  403.                               const cairo_pattern_t *other)
  404. {
  405.     cairo_status_t status;
  406.  
  407.     /* We don't bother doing any fancy copy-on-write implementation
  408.      * for the pattern's data. It's generally quite tiny. */
  409.     status = _cairo_pattern_init_copy (pattern, other);
  410.     if (unlikely (status))
  411.         return status;
  412.  
  413.     /* But we do let the surface snapshot stuff be as fancy as it
  414.      * would like to be. */
  415.     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
  416.         cairo_surface_pattern_t *surface_pattern =
  417.             (cairo_surface_pattern_t *) pattern;
  418.         cairo_surface_t *surface = surface_pattern->surface;
  419.  
  420.         surface_pattern->surface = _cairo_surface_snapshot (surface);
  421.  
  422.         cairo_surface_destroy (surface);
  423.  
  424.         status = surface_pattern->surface->status;
  425.     } else if (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
  426.         status = _cairo_raster_source_pattern_snapshot (pattern);
  427.  
  428.     return status;
  429. }
  430.  
  431. void
  432. _cairo_pattern_fini (cairo_pattern_t *pattern)
  433. {
  434.     _cairo_user_data_array_fini (&pattern->user_data);
  435.  
  436.     switch (pattern->type) {
  437.     case CAIRO_PATTERN_TYPE_SOLID:
  438.         break;
  439.     case CAIRO_PATTERN_TYPE_SURFACE: {
  440.         cairo_surface_pattern_t *surface_pattern =
  441.             (cairo_surface_pattern_t *) pattern;
  442.  
  443.         cairo_surface_destroy (surface_pattern->surface);
  444.     } break;
  445.     case CAIRO_PATTERN_TYPE_LINEAR:
  446.     case CAIRO_PATTERN_TYPE_RADIAL: {
  447.         cairo_gradient_pattern_t *gradient =
  448.             (cairo_gradient_pattern_t *) pattern;
  449.  
  450.         if (gradient->stops && gradient->stops != gradient->stops_embedded)
  451.             free (gradient->stops);
  452.     } break;
  453.     case CAIRO_PATTERN_TYPE_MESH: {
  454.         cairo_mesh_pattern_t *mesh =
  455.             (cairo_mesh_pattern_t *) pattern;
  456.  
  457.         _cairo_array_fini (&mesh->patches);
  458.     } break;
  459.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  460.         _cairo_raster_source_pattern_finish (pattern);
  461.         break;
  462.     }
  463.  
  464. #if HAVE_VALGRIND
  465.     switch (pattern->type) {
  466.     case CAIRO_PATTERN_TYPE_SOLID:
  467.         VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_solid_pattern_t));
  468.         break;
  469.     case CAIRO_PATTERN_TYPE_SURFACE:
  470.         VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_surface_pattern_t));
  471.         break;
  472.     case CAIRO_PATTERN_TYPE_LINEAR:
  473.         VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_linear_pattern_t));
  474.         break;
  475.     case CAIRO_PATTERN_TYPE_RADIAL:
  476.         VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_radial_pattern_t));
  477.         break;
  478.     case CAIRO_PATTERN_TYPE_MESH:
  479.         VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_mesh_pattern_t));
  480.         break;
  481.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  482.         break;
  483.     }
  484. #endif
  485. }
  486.  
  487. cairo_status_t
  488. _cairo_pattern_create_copy (cairo_pattern_t       **pattern_out,
  489.                             const cairo_pattern_t  *other)
  490. {
  491.     cairo_pattern_t *pattern;
  492.     cairo_status_t status;
  493.  
  494.     if (other->status)
  495.         return other->status;
  496.  
  497.     switch (other->type) {
  498.     case CAIRO_PATTERN_TYPE_SOLID:
  499.         pattern = malloc (sizeof (cairo_solid_pattern_t));
  500.         break;
  501.     case CAIRO_PATTERN_TYPE_SURFACE:
  502.         pattern = malloc (sizeof (cairo_surface_pattern_t));
  503.         break;
  504.     case CAIRO_PATTERN_TYPE_LINEAR:
  505.         pattern = malloc (sizeof (cairo_linear_pattern_t));
  506.         break;
  507.     case CAIRO_PATTERN_TYPE_RADIAL:
  508.         pattern = malloc (sizeof (cairo_radial_pattern_t));
  509.         break;
  510.     case CAIRO_PATTERN_TYPE_MESH:
  511.         pattern = malloc (sizeof (cairo_mesh_pattern_t));
  512.         break;
  513.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  514.         pattern = malloc (sizeof (cairo_raster_source_pattern_t));
  515.         break;
  516.     default:
  517.         ASSERT_NOT_REACHED;
  518.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  519.     }
  520.     if (unlikely (pattern == NULL))
  521.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  522.  
  523.     status = _cairo_pattern_init_copy (pattern, other);
  524.     if (unlikely (status)) {
  525.         free (pattern);
  526.         return status;
  527.     }
  528.  
  529.     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
  530.     *pattern_out = pattern;
  531.     return CAIRO_STATUS_SUCCESS;
  532. }
  533.  
  534. void
  535. _cairo_pattern_init_solid (cairo_solid_pattern_t *pattern,
  536.                            const cairo_color_t   *color)
  537. {
  538.     _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID);
  539.     pattern->color = *color;
  540. }
  541.  
  542. void
  543. _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern,
  544.                                  cairo_surface_t         *surface)
  545. {
  546.     if (surface->status) {
  547.         /* Force to solid to simplify the pattern_fini process. */
  548.         _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID);
  549.         _cairo_pattern_set_error (&pattern->base, surface->status);
  550.         return;
  551.     }
  552.  
  553.     _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SURFACE);
  554.  
  555.     pattern->surface = cairo_surface_reference (surface);
  556. }
  557.  
  558. static void
  559. _cairo_pattern_init_gradient (cairo_gradient_pattern_t *pattern,
  560.                               cairo_pattern_type_t     type)
  561. {
  562.     _cairo_pattern_init (&pattern->base, type);
  563.  
  564.     pattern->n_stops    = 0;
  565.     pattern->stops_size = 0;
  566.     pattern->stops      = NULL;
  567. }
  568.  
  569. static void
  570. _cairo_pattern_init_linear (cairo_linear_pattern_t *pattern,
  571.                             double x0, double y0, double x1, double y1)
  572. {
  573.     _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_LINEAR);
  574.  
  575.     pattern->pd1.x = x0;
  576.     pattern->pd1.y = y0;
  577.     pattern->pd2.x = x1;
  578.     pattern->pd2.y = y1;
  579. }
  580.  
  581. static void
  582. _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
  583.                             double cx0, double cy0, double radius0,
  584.                             double cx1, double cy1, double radius1)
  585. {
  586.     _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_RADIAL);
  587.  
  588.     pattern->cd1.center.x = cx0;
  589.     pattern->cd1.center.y = cy0;
  590.     pattern->cd1.radius   = fabs (radius0);
  591.     pattern->cd2.center.x = cx1;
  592.     pattern->cd2.center.y = cy1;
  593.     pattern->cd2.radius   = fabs (radius1);
  594. }
  595.  
  596. cairo_pattern_t *
  597. _cairo_pattern_create_solid (const cairo_color_t *color)
  598. {
  599.     cairo_solid_pattern_t *pattern;
  600.  
  601.     pattern =
  602.         _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SOLID]);
  603.     if (unlikely (pattern == NULL)) {
  604.         /* None cached, need to create a new pattern. */
  605.         pattern = malloc (sizeof (cairo_solid_pattern_t));
  606.         if (unlikely (pattern == NULL)) {
  607.             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  608.             return (cairo_pattern_t *) &_cairo_pattern_nil;
  609.         }
  610.     }
  611.  
  612.     _cairo_pattern_init_solid (pattern, color);
  613.     CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
  614.  
  615.     return &pattern->base;
  616. }
  617.  
  618. cairo_pattern_t *
  619. _cairo_pattern_create_in_error (cairo_status_t status)
  620. {
  621.     cairo_pattern_t *pattern;
  622.  
  623.     if (status == CAIRO_STATUS_NO_MEMORY)
  624.         return (cairo_pattern_t *)&_cairo_pattern_nil.base;
  625.  
  626.     CAIRO_MUTEX_INITIALIZE ();
  627.  
  628.     pattern = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
  629.     if (pattern->status == CAIRO_STATUS_SUCCESS)
  630.         status = _cairo_pattern_set_error (pattern, status);
  631.  
  632.     return pattern;
  633. }
  634.  
  635. /**
  636.  * cairo_pattern_create_rgb:
  637.  * @red: red component of the color
  638.  * @green: green component of the color
  639.  * @blue: blue component of the color
  640.  *
  641.  * Creates a new #cairo_pattern_t corresponding to an opaque color.  The
  642.  * color components are floating point numbers in the range 0 to 1.
  643.  * If the values passed in are outside that range, they will be
  644.  * clamped.
  645.  *
  646.  * Return value: the newly created #cairo_pattern_t if successful, or
  647.  * an error pattern in case of no memory.  The caller owns the
  648.  * returned object and should call cairo_pattern_destroy() when
  649.  * finished with it.
  650.  *
  651.  * This function will always return a valid pointer, but if an error
  652.  * occurred the pattern status will be set to an error.  To inspect
  653.  * the status of a pattern use cairo_pattern_status().
  654.  *
  655.  * Since: 1.0
  656.  **/
  657. cairo_pattern_t *
  658. cairo_pattern_create_rgb (double red, double green, double blue)
  659. {
  660.     return cairo_pattern_create_rgba (red, green, blue, 1.0);
  661. }
  662. slim_hidden_def (cairo_pattern_create_rgb);
  663.  
  664. /**
  665.  * cairo_pattern_create_rgba:
  666.  * @red: red component of the color
  667.  * @green: green component of the color
  668.  * @blue: blue component of the color
  669.  * @alpha: alpha component of the color
  670.  *
  671.  * Creates a new #cairo_pattern_t corresponding to a translucent color.
  672.  * The color components are floating point numbers in the range 0 to
  673.  * 1.  If the values passed in are outside that range, they will be
  674.  * clamped.
  675.  *
  676.  * Return value: the newly created #cairo_pattern_t if successful, or
  677.  * an error pattern in case of no memory.  The caller owns the
  678.  * returned object and should call cairo_pattern_destroy() when
  679.  * finished with it.
  680.  *
  681.  * This function will always return a valid pointer, but if an error
  682.  * occurred the pattern status will be set to an error.  To inspect
  683.  * the status of a pattern use cairo_pattern_status().
  684.  *
  685.  * Since: 1.0
  686.  **/
  687. cairo_pattern_t *
  688. cairo_pattern_create_rgba (double red, double green, double blue,
  689.                            double alpha)
  690. {
  691.     cairo_color_t color;
  692.  
  693.     red   = _cairo_restrict_value (red,   0.0, 1.0);
  694.     green = _cairo_restrict_value (green, 0.0, 1.0);
  695.     blue  = _cairo_restrict_value (blue,  0.0, 1.0);
  696.     alpha = _cairo_restrict_value (alpha, 0.0, 1.0);
  697.  
  698.     _cairo_color_init_rgba (&color, red, green, blue, alpha);
  699.  
  700.     CAIRO_MUTEX_INITIALIZE ();
  701.  
  702.     return _cairo_pattern_create_solid (&color);
  703. }
  704. slim_hidden_def (cairo_pattern_create_rgba);
  705.  
  706. /**
  707.  * cairo_pattern_create_for_surface:
  708.  * @surface: the surface
  709.  *
  710.  * Create a new #cairo_pattern_t for the given surface.
  711.  *
  712.  * Return value: the newly created #cairo_pattern_t if successful, or
  713.  * an error pattern in case of no memory.  The caller owns the
  714.  * returned object and should call cairo_pattern_destroy() when
  715.  * finished with it.
  716.  *
  717.  * This function will always return a valid pointer, but if an error
  718.  * occurred the pattern status will be set to an error.  To inspect
  719.  * the status of a pattern use cairo_pattern_status().
  720.  *
  721.  * Since: 1.0
  722.  **/
  723. cairo_pattern_t *
  724. cairo_pattern_create_for_surface (cairo_surface_t *surface)
  725. {
  726.     cairo_surface_pattern_t *pattern;
  727.  
  728.     if (surface == NULL) {
  729.         _cairo_error_throw (CAIRO_STATUS_NULL_POINTER);
  730.         return (cairo_pattern_t*) &_cairo_pattern_nil_null_pointer;
  731.     }
  732.  
  733.     if (surface->status)
  734.         return _cairo_pattern_create_in_error (surface->status);
  735.  
  736.     pattern =
  737.         _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SURFACE]);
  738.     if (unlikely (pattern == NULL)) {
  739.         pattern = malloc (sizeof (cairo_surface_pattern_t));
  740.         if (unlikely (pattern == NULL)) {
  741.             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  742.             return (cairo_pattern_t *)&_cairo_pattern_nil.base;
  743.         }
  744.     }
  745.  
  746.     CAIRO_MUTEX_INITIALIZE ();
  747.  
  748.     _cairo_pattern_init_for_surface (pattern, surface);
  749.     CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
  750.  
  751.     return &pattern->base;
  752. }
  753. slim_hidden_def (cairo_pattern_create_for_surface);
  754.  
  755. /**
  756.  * cairo_pattern_create_linear:
  757.  * @x0: x coordinate of the start point
  758.  * @y0: y coordinate of the start point
  759.  * @x1: x coordinate of the end point
  760.  * @y1: y coordinate of the end point
  761.  *
  762.  * Create a new linear gradient #cairo_pattern_t along the line defined
  763.  * by (x0, y0) and (x1, y1).  Before using the gradient pattern, a
  764.  * number of color stops should be defined using
  765.  * cairo_pattern_add_color_stop_rgb() or
  766.  * cairo_pattern_add_color_stop_rgba().
  767.  *
  768.  * Note: The coordinates here are in pattern space. For a new pattern,
  769.  * pattern space is identical to user space, but the relationship
  770.  * between the spaces can be changed with cairo_pattern_set_matrix().
  771.  *
  772.  * Return value: the newly created #cairo_pattern_t if successful, or
  773.  * an error pattern in case of no memory.  The caller owns the
  774.  * returned object and should call cairo_pattern_destroy() when
  775.  * finished with it.
  776.  *
  777.  * This function will always return a valid pointer, but if an error
  778.  * occurred the pattern status will be set to an error.  To inspect
  779.  * the status of a pattern use cairo_pattern_status().
  780.  *
  781.  * Since: 1.0
  782.  **/
  783. cairo_pattern_t *
  784. cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
  785. {
  786.     cairo_linear_pattern_t *pattern;
  787.  
  788.     pattern =
  789.         _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_LINEAR]);
  790.     if (unlikely (pattern == NULL)) {
  791.         pattern = malloc (sizeof (cairo_linear_pattern_t));
  792.         if (unlikely (pattern == NULL)) {
  793.             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  794.             return (cairo_pattern_t *) &_cairo_pattern_nil.base;
  795.         }
  796.     }
  797.  
  798.     CAIRO_MUTEX_INITIALIZE ();
  799.  
  800.     _cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
  801.     CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1);
  802.  
  803.     return &pattern->base.base;
  804. }
  805.  
  806. /**
  807.  * cairo_pattern_create_radial:
  808.  * @cx0: x coordinate for the center of the start circle
  809.  * @cy0: y coordinate for the center of the start circle
  810.  * @radius0: radius of the start circle
  811.  * @cx1: x coordinate for the center of the end circle
  812.  * @cy1: y coordinate for the center of the end circle
  813.  * @radius1: radius of the end circle
  814.  *
  815.  * Creates a new radial gradient #cairo_pattern_t between the two
  816.  * circles defined by (cx0, cy0, radius0) and (cx1, cy1, radius1).  Before using the
  817.  * gradient pattern, a number of color stops should be defined using
  818.  * cairo_pattern_add_color_stop_rgb() or
  819.  * cairo_pattern_add_color_stop_rgba().
  820.  *
  821.  * Note: The coordinates here are in pattern space. For a new pattern,
  822.  * pattern space is identical to user space, but the relationship
  823.  * between the spaces can be changed with cairo_pattern_set_matrix().
  824.  *
  825.  * Return value: the newly created #cairo_pattern_t if successful, or
  826.  * an error pattern in case of no memory.  The caller owns the
  827.  * returned object and should call cairo_pattern_destroy() when
  828.  * finished with it.
  829.  *
  830.  * This function will always return a valid pointer, but if an error
  831.  * occurred the pattern status will be set to an error.  To inspect
  832.  * the status of a pattern use cairo_pattern_status().
  833.  *
  834.  * Since: 1.0
  835.  **/
  836. cairo_pattern_t *
  837. cairo_pattern_create_radial (double cx0, double cy0, double radius0,
  838.                              double cx1, double cy1, double radius1)
  839. {
  840.     cairo_radial_pattern_t *pattern;
  841.  
  842.     pattern =
  843.         _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_RADIAL]);
  844.     if (unlikely (pattern == NULL)) {
  845.         pattern = malloc (sizeof (cairo_radial_pattern_t));
  846.         if (unlikely (pattern == NULL)) {
  847.             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  848.             return (cairo_pattern_t *) &_cairo_pattern_nil.base;
  849.         }
  850.     }
  851.  
  852.     CAIRO_MUTEX_INITIALIZE ();
  853.  
  854.     _cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
  855.     CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1);
  856.  
  857.     return &pattern->base.base;
  858. }
  859.  
  860. /* This order is specified in the diagram in the documentation for
  861.  * cairo_pattern_create_mesh() */
  862. static const int mesh_path_point_i[12] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1 };
  863. static const int mesh_path_point_j[12] = { 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0 };
  864. static const int mesh_control_point_i[4] = { 1, 1, 2, 2 };
  865. static const int mesh_control_point_j[4] = { 1, 2, 2, 1 };
  866.  
  867. /**
  868.  * cairo_pattern_create_mesh:
  869.  *
  870.  * Create a new mesh pattern.
  871.  *
  872.  * Mesh patterns are tensor-product patch meshes (type 7 shadings in
  873.  * PDF). Mesh patterns may also be used to create other types of
  874.  * shadings that are special cases of tensor-product patch meshes such
  875.  * as Coons patch meshes (type 6 shading in PDF) and Gouraud-shaded
  876.  * triangle meshes (type 4 and 5 shadings in PDF).
  877.  *
  878.  * Mesh patterns consist of one or more tensor-product patches, which
  879.  * should be defined before using the mesh pattern. Using a mesh
  880.  * pattern with a partially defined patch as source or mask will put
  881.  * the context in an error status with a status of
  882.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  883.  *
  884.  * A tensor-product patch is defined by 4 Bézier curves (side 0, 1, 2,
  885.  * 3) and by 4 additional control points (P0, P1, P2, P3) that provide
  886.  * further control over the patch and complete the definition of the
  887.  * tensor-product patch. The corner C0 is the first point of the
  888.  * patch.
  889.  *
  890.  * Degenerate sides are permitted so straight lines may be used. A
  891.  * zero length line on one side may be used to create 3 sided patches.
  892.  *
  893.  * <informalexample><screen>
  894.  *       C1     Side 1       C2
  895.  *        +---------------+
  896.  *        |               |
  897.  *        |  P1       P2  |
  898.  *        |               |
  899.  * Side 0 |               | Side 2
  900.  *        |               |
  901.  *        |               |
  902.  *        |  P0       P3  |
  903.  *        |               |
  904.  *        +---------------+
  905.  *      C0     Side 3        C3
  906.  * </screen></informalexample>
  907.  *
  908.  * Each patch is constructed by first calling
  909.  * cairo_mesh_pattern_begin_patch(), then cairo_mesh_pattern_move_to()
  910.  * to specify the first point in the patch (C0). Then the sides are
  911.  * specified with calls to cairo_mesh_pattern_curve_to() and
  912.  * cairo_mesh_pattern_line_to().
  913.  *
  914.  * The four additional control points (P0, P1, P2, P3) in a patch can
  915.  * be specified with cairo_mesh_pattern_set_control_point().
  916.  *
  917.  * At each corner of the patch (C0, C1, C2, C3) a color may be
  918.  * specified with cairo_mesh_pattern_set_corner_color_rgb() or
  919.  * cairo_mesh_pattern_set_corner_color_rgba(). Any corner whose color
  920.  * is not explicitly specified defaults to transparent black.
  921.  *
  922.  * A Coons patch is a special case of the tensor-product patch where
  923.  * the control points are implicitly defined by the sides of the
  924.  * patch. The default value for any control point not specified is the
  925.  * implicit value for a Coons patch, i.e. if no control points are
  926.  * specified the patch is a Coons patch.
  927.  *
  928.  * A triangle is a special case of the tensor-product patch where the
  929.  * control points are implicitly defined by the sides of the patch,
  930.  * all the sides are lines and one of them has length 0, i.e. if the
  931.  * patch is specified using just 3 lines, it is a triangle. If the
  932.  * corners connected by the 0-length side have the same color, the
  933.  * patch is a Gouraud-shaded triangle.
  934.  *
  935.  * Patches may be oriented differently to the above diagram. For
  936.  * example the first point could be at the top left. The diagram only
  937.  * shows the relationship between the sides, corners and control
  938.  * points. Regardless of where the first point is located, when
  939.  * specifying colors, corner 0 will always be the first point, corner
  940.  * 1 the point between side 0 and side 1 etc.
  941.  *
  942.  * Calling cairo_mesh_pattern_end_patch() completes the current
  943.  * patch. If less than 4 sides have been defined, the first missing
  944.  * side is defined as a line from the current point to the first point
  945.  * of the patch (C0) and the other sides are degenerate lines from C0
  946.  * to C0. The corners between the added sides will all be coincident
  947.  * with C0 of the patch and their color will be set to be the same as
  948.  * the color of C0.
  949.  *
  950.  * Additional patches may be added with additional calls to
  951.  * cairo_mesh_pattern_begin_patch()/cairo_mesh_pattern_end_patch().
  952.  *
  953.  * <informalexample><programlisting>
  954.  * cairo_pattern_t *pattern = cairo_pattern_create_mesh ();
  955.  *
  956.  * /&ast; Add a Coons patch &ast;/
  957.  * cairo_mesh_pattern_begin_patch (pattern);
  958.  * cairo_mesh_pattern_move_to (pattern, 0, 0);
  959.  * cairo_mesh_pattern_curve_to (pattern, 30, -30,  60,  30, 100, 0);
  960.  * cairo_mesh_pattern_curve_to (pattern, 60,  30, 130,  60, 100, 100);
  961.  * cairo_mesh_pattern_curve_to (pattern, 60,  70,  30, 130,   0, 100);
  962.  * cairo_mesh_pattern_curve_to (pattern, 30,  70, -30,  30,   0, 0);
  963.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
  964.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
  965.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
  966.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
  967.  * cairo_mesh_pattern_end_patch (pattern);
  968.  *
  969.  * /&ast; Add a Gouraud-shaded triangle &ast;/
  970.  * cairo_mesh_pattern_begin_patch (pattern)
  971.  * cairo_mesh_pattern_move_to (pattern, 100, 100);
  972.  * cairo_mesh_pattern_line_to (pattern, 130, 130);
  973.  * cairo_mesh_pattern_line_to (pattern, 130,  70);
  974.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
  975.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
  976.  * cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
  977.  * cairo_mesh_pattern_end_patch (pattern)
  978.  * </programlisting></informalexample>
  979.  *
  980.  * When two patches overlap, the last one that has been added is drawn
  981.  * over the first one.
  982.  *
  983.  * When a patch folds over itself, points are sorted depending on
  984.  * their parameter coordinates inside the patch. The v coordinate
  985.  * ranges from 0 to 1 when moving from side 3 to side 1; the u
  986.  * coordinate ranges from 0 to 1 when going from side 0 to side
  987.  * 2. Points with higher v coordinate hide points with lower v
  988.  * coordinate. When two points have the same v coordinate, the one
  989.  * with higher u coordinate is above. This means that points nearer to
  990.  * side 1 are above points nearer to side 3; when this is not
  991.  * sufficient to decide which point is above (for example when both
  992.  * points belong to side 1 or side 3) points nearer to side 2 are
  993.  * above points nearer to side 0.
  994.  *
  995.  * For a complete definition of tensor-product patches, see the PDF
  996.  * specification (ISO32000), which describes the parametrization in
  997.  * detail.
  998.  *
  999.  * Note: The coordinates are always in pattern space. For a new
  1000.  * pattern, pattern space is identical to user space, but the
  1001.  * relationship between the spaces can be changed with
  1002.  * cairo_pattern_set_matrix().
  1003.  *
  1004.  * Return value: the newly created #cairo_pattern_t if successful, or
  1005.  * an error pattern in case of no memory. The caller owns the returned
  1006.  * object and should call cairo_pattern_destroy() when finished with
  1007.  * it.
  1008.  *
  1009.  * This function will always return a valid pointer, but if an error
  1010.  * occurred the pattern status will be set to an error. To inspect the
  1011.  * status of a pattern use cairo_pattern_status().
  1012.  *
  1013.  * Since: 1.12
  1014.  **/
  1015. cairo_pattern_t *
  1016. cairo_pattern_create_mesh (void)
  1017. {
  1018.     cairo_mesh_pattern_t *pattern;
  1019.  
  1020.     pattern =
  1021.         _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_MESH]);
  1022.     if (unlikely (pattern == NULL)) {
  1023.         pattern = malloc (sizeof (cairo_mesh_pattern_t));
  1024.         if (unlikely (pattern == NULL)) {
  1025.             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  1026.             return (cairo_pattern_t *) &_cairo_pattern_nil.base;
  1027.         }
  1028.     }
  1029.  
  1030.     CAIRO_MUTEX_INITIALIZE ();
  1031.  
  1032.     _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_MESH);
  1033.     _cairo_array_init (&pattern->patches, sizeof (cairo_mesh_patch_t));
  1034.     pattern->current_patch = NULL;
  1035.     CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
  1036.  
  1037.     return &pattern->base;
  1038. }
  1039.  
  1040. /**
  1041.  * cairo_pattern_reference:
  1042.  * @pattern: a #cairo_pattern_t
  1043.  *
  1044.  * Increases the reference count on @pattern by one. This prevents
  1045.  * @pattern from being destroyed until a matching call to
  1046.  * cairo_pattern_destroy() is made.
  1047.  *
  1048.  * The number of references to a #cairo_pattern_t can be get using
  1049.  * cairo_pattern_get_reference_count().
  1050.  *
  1051.  * Return value: the referenced #cairo_pattern_t.
  1052.  *
  1053.  * Since: 1.0
  1054.  **/
  1055. cairo_pattern_t *
  1056. cairo_pattern_reference (cairo_pattern_t *pattern)
  1057. {
  1058.     if (pattern == NULL ||
  1059.             CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
  1060.         return pattern;
  1061.  
  1062.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count));
  1063.  
  1064.     _cairo_reference_count_inc (&pattern->ref_count);
  1065.  
  1066.     return pattern;
  1067. }
  1068. slim_hidden_def (cairo_pattern_reference);
  1069.  
  1070. /**
  1071.  * cairo_pattern_get_type:
  1072.  * @pattern: a #cairo_pattern_t
  1073.  *
  1074.  * This function returns the type a pattern.
  1075.  * See #cairo_pattern_type_t for available types.
  1076.  *
  1077.  * Return value: The type of @pattern.
  1078.  *
  1079.  * Since: 1.2
  1080.  **/
  1081. cairo_pattern_type_t
  1082. cairo_pattern_get_type (cairo_pattern_t *pattern)
  1083. {
  1084.     return pattern->type;
  1085. }
  1086.  
  1087. /**
  1088.  * cairo_pattern_status:
  1089.  * @pattern: a #cairo_pattern_t
  1090.  *
  1091.  * Checks whether an error has previously occurred for this
  1092.  * pattern.
  1093.  *
  1094.  * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NO_MEMORY,
  1095.  * %CAIRO_STATUS_INVALID_MATRIX, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
  1096.  * or %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1097.  *
  1098.  * Since: 1.0
  1099.  **/
  1100. cairo_status_t
  1101. cairo_pattern_status (cairo_pattern_t *pattern)
  1102. {
  1103.     return pattern->status;
  1104. }
  1105.  
  1106. /**
  1107.  * cairo_pattern_destroy:
  1108.  * @pattern: a #cairo_pattern_t
  1109.  *
  1110.  * Decreases the reference count on @pattern by one. If the result is
  1111.  * zero, then @pattern and all associated resources are freed.  See
  1112.  * cairo_pattern_reference().
  1113.  *
  1114.  * Since: 1.0
  1115.  **/
  1116. void
  1117. cairo_pattern_destroy (cairo_pattern_t *pattern)
  1118. {
  1119.     cairo_pattern_type_t type;
  1120.  
  1121.     if (pattern == NULL ||
  1122.             CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
  1123.         return;
  1124.  
  1125.     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count));
  1126.  
  1127.     if (! _cairo_reference_count_dec_and_test (&pattern->ref_count))
  1128.         return;
  1129.  
  1130.     type = pattern->type;
  1131.     _cairo_pattern_fini (pattern);
  1132.  
  1133.     /* maintain a small cache of freed patterns */
  1134.     if (type < ARRAY_LENGTH (freed_pattern_pool))
  1135.         _freed_pool_put (&freed_pattern_pool[type], pattern);
  1136.     else
  1137.         free (pattern);
  1138. }
  1139. slim_hidden_def (cairo_pattern_destroy);
  1140.  
  1141. /**
  1142.  * cairo_pattern_get_reference_count:
  1143.  * @pattern: a #cairo_pattern_t
  1144.  *
  1145.  * Returns the current reference count of @pattern.
  1146.  *
  1147.  * Return value: the current reference count of @pattern.  If the
  1148.  * object is a nil object, 0 will be returned.
  1149.  *
  1150.  * Since: 1.4
  1151.  **/
  1152. unsigned int
  1153. cairo_pattern_get_reference_count (cairo_pattern_t *pattern)
  1154. {
  1155.     if (pattern == NULL ||
  1156.             CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
  1157.         return 0;
  1158.  
  1159.     return CAIRO_REFERENCE_COUNT_GET_VALUE (&pattern->ref_count);
  1160. }
  1161.  
  1162. /**
  1163.  * cairo_pattern_get_user_data:
  1164.  * @pattern: a #cairo_pattern_t
  1165.  * @key: the address of the #cairo_user_data_key_t the user data was
  1166.  * attached to
  1167.  *
  1168.  * Return user data previously attached to @pattern using the
  1169.  * specified key.  If no user data has been attached with the given
  1170.  * key this function returns %NULL.
  1171.  *
  1172.  * Return value: the user data previously attached or %NULL.
  1173.  *
  1174.  * Since: 1.4
  1175.  **/
  1176. void *
  1177. cairo_pattern_get_user_data (cairo_pattern_t             *pattern,
  1178.                              const cairo_user_data_key_t *key)
  1179. {
  1180.     return _cairo_user_data_array_get_data (&pattern->user_data,
  1181.                                             key);
  1182. }
  1183.  
  1184. /**
  1185.  * cairo_pattern_set_user_data:
  1186.  * @pattern: a #cairo_pattern_t
  1187.  * @key: the address of a #cairo_user_data_key_t to attach the user data to
  1188.  * @user_data: the user data to attach to the #cairo_pattern_t
  1189.  * @destroy: a #cairo_destroy_func_t which will be called when the
  1190.  * #cairo_t is destroyed or when new user data is attached using the
  1191.  * same key.
  1192.  *
  1193.  * Attach user data to @pattern.  To remove user data from a surface,
  1194.  * call this function with the key that was used to set it and %NULL
  1195.  * for @data.
  1196.  *
  1197.  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
  1198.  * slot could not be allocated for the user data.
  1199.  *
  1200.  * Since: 1.4
  1201.  **/
  1202. cairo_status_t
  1203. cairo_pattern_set_user_data (cairo_pattern_t             *pattern,
  1204.                              const cairo_user_data_key_t *key,
  1205.                              void                        *user_data,
  1206.                              cairo_destroy_func_t         destroy)
  1207. {
  1208.     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
  1209.         return pattern->status;
  1210.  
  1211.     return _cairo_user_data_array_set_data (&pattern->user_data,
  1212.                                             key, user_data, destroy);
  1213. }
  1214.  
  1215. /**
  1216.  * cairo_mesh_pattern_begin_patch:
  1217.  * @pattern: a #cairo_pattern_t
  1218.  *
  1219.  * Begin a patch in a mesh pattern.
  1220.  *
  1221.  * After calling this function, the patch shape should be defined with
  1222.  * cairo_mesh_pattern_move_to(), cairo_mesh_pattern_line_to() and
  1223.  * cairo_mesh_pattern_curve_to().
  1224.  *
  1225.  * After defining the patch, cairo_mesh_pattern_end_patch() must be
  1226.  * called before using @pattern as a source or mask.
  1227.  *
  1228.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1229.  * into an error status with a status of
  1230.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern already has a
  1231.  * current patch, it will be put into an error status with a status of
  1232.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1233.  *
  1234.  * Since: 1.12
  1235.  **/
  1236. void
  1237. cairo_mesh_pattern_begin_patch (cairo_pattern_t *pattern)
  1238. {
  1239.     cairo_mesh_pattern_t *mesh;
  1240.     cairo_status_t status;
  1241.     cairo_mesh_patch_t *current_patch;
  1242.     int i;
  1243.  
  1244.     if (unlikely (pattern->status))
  1245.         return;
  1246.  
  1247.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1248.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1249.         return;
  1250.     }
  1251.  
  1252.     mesh = (cairo_mesh_pattern_t *) pattern;
  1253.     if (unlikely (mesh->current_patch)) {
  1254.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1255.         return;
  1256.     }
  1257.  
  1258.     status = _cairo_array_allocate (&mesh->patches, 1, (void **) &current_patch);
  1259.     if (unlikely (status)) {
  1260.         _cairo_pattern_set_error (pattern, status);
  1261.         return;
  1262.     }
  1263.  
  1264.     mesh->current_patch = current_patch;
  1265.     mesh->current_side = -2; /* no current point */
  1266.  
  1267.     for (i = 0; i < 4; i++)
  1268.         mesh->has_control_point[i] = FALSE;
  1269.  
  1270.     for (i = 0; i < 4; i++)
  1271.         mesh->has_color[i] = FALSE;
  1272. }
  1273.  
  1274.  
  1275. static void
  1276. _calc_control_point (cairo_mesh_patch_t *patch, int control_point)
  1277. {
  1278.     /* The Coons patch is a special case of the Tensor Product patch
  1279.      * where the four control points are:
  1280.      *
  1281.      * P11 = S(1/3, 1/3)
  1282.      * P12 = S(1/3, 2/3)
  1283.      * P21 = S(2/3, 1/3)
  1284.      * P22 = S(2/3, 2/3)
  1285.      *
  1286.      * where S is the gradient surface.
  1287.      *
  1288.      * When one or more control points has not been specified
  1289.      * calculated the Coons patch control points are substituted. If
  1290.      * no control points are specified the gradient will be a Coons
  1291.      * patch.
  1292.      *
  1293.      * The equations below are defined in the ISO32000 standard.
  1294.      */
  1295.     cairo_point_double_t *p[3][3];
  1296.     int cp_i, cp_j, i, j;
  1297.  
  1298.     cp_i = mesh_control_point_i[control_point];
  1299.     cp_j = mesh_control_point_j[control_point];
  1300.  
  1301.     for (i = 0; i < 3; i++)
  1302.         for (j = 0; j < 3; j++)
  1303.             p[i][j] = &patch->points[cp_i ^ i][cp_j ^ j];
  1304.  
  1305.     p[0][0]->x = (- 4 * p[1][1]->x
  1306.                   + 6 * (p[1][0]->x + p[0][1]->x)
  1307.                   - 2 * (p[1][2]->x + p[2][1]->x)
  1308.                   + 3 * (p[2][0]->x + p[0][2]->x)
  1309.                   - 1 * p[2][2]->x) * (1. / 9);
  1310.  
  1311.     p[0][0]->y = (- 4 * p[1][1]->y
  1312.                   + 6 * (p[1][0]->y + p[0][1]->y)
  1313.                   - 2 * (p[1][2]->y + p[2][1]->y)
  1314.                   + 3 * (p[2][0]->y + p[0][2]->y)
  1315.                   - 1 * p[2][2]->y) * (1. / 9);
  1316. }
  1317.  
  1318. /**
  1319.  * cairo_mesh_pattern_end_patch:
  1320.  * @pattern: a #cairo_pattern_t
  1321.  *
  1322.  * Indicates the end of the current patch in a mesh pattern.
  1323.  *
  1324.  * If the current patch has less than 4 sides, it is closed with a
  1325.  * straight line from the current point to the first point of the
  1326.  * patch as if cairo_mesh_pattern_line_to() was used.
  1327.  *
  1328.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1329.  * into an error status with a status of
  1330.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current
  1331.  * patch or the current patch has no current point, @pattern will be
  1332.  * put into an error status with a status of
  1333.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1334.  *
  1335.  * Since: 1.12
  1336.  **/
  1337. void
  1338. cairo_mesh_pattern_end_patch (cairo_pattern_t *pattern)
  1339. {
  1340.     cairo_mesh_pattern_t *mesh;
  1341.     cairo_mesh_patch_t *current_patch;
  1342.     int i;
  1343.  
  1344.     if (unlikely (pattern->status))
  1345.         return;
  1346.  
  1347.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1348.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1349.         return;
  1350.     }
  1351.  
  1352.     mesh = (cairo_mesh_pattern_t *) pattern;
  1353.     current_patch = mesh->current_patch;
  1354.     if (unlikely (!current_patch)) {
  1355.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1356.         return;
  1357.     }
  1358.  
  1359.     if (unlikely (mesh->current_side == -2)) {
  1360.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1361.         return;
  1362.     }
  1363.  
  1364.     while (mesh->current_side < 3) {
  1365.         int corner_num;
  1366.  
  1367.         cairo_mesh_pattern_line_to (pattern,
  1368.                                     current_patch->points[0][0].x,
  1369.                                     current_patch->points[0][0].y);
  1370.  
  1371.         corner_num = mesh->current_side + 1;
  1372.         if (corner_num < 4 && ! mesh->has_color[corner_num]) {
  1373.             current_patch->colors[corner_num] = current_patch->colors[0];
  1374.             mesh->has_color[corner_num] = TRUE;
  1375.         }
  1376.     }
  1377.  
  1378.     for (i = 0; i < 4; i++) {
  1379.         if (! mesh->has_control_point[i])
  1380.             _calc_control_point (current_patch, i);
  1381.     }
  1382.  
  1383.     for (i = 0; i < 4; i++) {
  1384.         if (! mesh->has_color[i])
  1385.             current_patch->colors[i] = *CAIRO_COLOR_TRANSPARENT;
  1386.     }
  1387.  
  1388.     mesh->current_patch = NULL;
  1389. }
  1390.  
  1391. /**
  1392.  * cairo_mesh_pattern_curve_to:
  1393.  * @pattern: a #cairo_pattern_t
  1394.  * @x1: the X coordinate of the first control point
  1395.  * @y1: the Y coordinate of the first control point
  1396.  * @x2: the X coordinate of the second control point
  1397.  * @y2: the Y coordinate of the second control point
  1398.  * @x3: the X coordinate of the end of the curve
  1399.  * @y3: the Y coordinate of the end of the curve
  1400.  *
  1401.  * Adds a cubic Bézier spline to the current patch from the current
  1402.  * point to position (@x3, @y3) in pattern-space coordinates, using
  1403.  * (@x1, @y1) and (@x2, @y2) as the control points.
  1404.  *
  1405.  * If the current patch has no current point before the call to
  1406.  * cairo_mesh_pattern_curve_to(), this function will behave as if
  1407.  * preceded by a call to cairo_mesh_pattern_move_to(@pattern, @x1,
  1408.  * @y1).
  1409.  *
  1410.  * After this call the current point will be (@x3, @y3).
  1411.  *
  1412.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1413.  * into an error status with a status of
  1414.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current
  1415.  * patch or the current patch already has 4 sides, @pattern will be
  1416.  * put into an error status with a status of
  1417.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1418.  *
  1419.  * Since: 1.12
  1420.  **/
  1421. void
  1422. cairo_mesh_pattern_curve_to (cairo_pattern_t *pattern,
  1423.                              double x1, double y1,
  1424.                              double x2, double y2,
  1425.                              double x3, double y3)
  1426. {
  1427.     cairo_mesh_pattern_t *mesh;
  1428.     int current_point, i, j;
  1429.  
  1430.     if (unlikely (pattern->status))
  1431.         return;
  1432.  
  1433.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1434.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1435.         return;
  1436.     }
  1437.  
  1438.     mesh = (cairo_mesh_pattern_t *) pattern;
  1439.     if (unlikely (!mesh->current_patch)) {
  1440.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1441.         return;
  1442.     }
  1443.  
  1444.     if (unlikely (mesh->current_side == 3)) {
  1445.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1446.         return;
  1447.     }
  1448.  
  1449.     if (mesh->current_side == -2)
  1450.         cairo_mesh_pattern_move_to (pattern, x1, y1);
  1451.  
  1452.     assert (mesh->current_side >= -1);
  1453.     assert (pattern->status == CAIRO_STATUS_SUCCESS);
  1454.  
  1455.     mesh->current_side++;
  1456.  
  1457.     current_point = 3 * mesh->current_side;
  1458.  
  1459.     current_point++;
  1460.     i = mesh_path_point_i[current_point];
  1461.     j = mesh_path_point_j[current_point];
  1462.     mesh->current_patch->points[i][j].x = x1;
  1463.     mesh->current_patch->points[i][j].y = y1;
  1464.  
  1465.     current_point++;
  1466.     i = mesh_path_point_i[current_point];
  1467.     j = mesh_path_point_j[current_point];
  1468.     mesh->current_patch->points[i][j].x = x2;
  1469.     mesh->current_patch->points[i][j].y = y2;
  1470.  
  1471.     current_point++;
  1472.     if (current_point < 12) {
  1473.         i = mesh_path_point_i[current_point];
  1474.         j = mesh_path_point_j[current_point];
  1475.         mesh->current_patch->points[i][j].x = x3;
  1476.         mesh->current_patch->points[i][j].y = y3;
  1477.     }
  1478. }
  1479. slim_hidden_def (cairo_mesh_pattern_curve_to);
  1480.  
  1481. /**
  1482.  * cairo_mesh_pattern_line_to:
  1483.  * @pattern: a #cairo_pattern_t
  1484.  * @x: the X coordinate of the end of the new line
  1485.  * @y: the Y coordinate of the end of the new line
  1486.  *
  1487.  * Adds a line to the current patch from the current point to position
  1488.  * (@x, @y) in pattern-space coordinates.
  1489.  *
  1490.  * If there is no current point before the call to
  1491.  * cairo_mesh_pattern_line_to() this function will behave as
  1492.  * cairo_mesh_pattern_move_to(@pattern, @x, @y).
  1493.  *
  1494.  * After this call the current point will be (@x, @y).
  1495.  *
  1496.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1497.  * into an error status with a status of
  1498.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current
  1499.  * patch or the current patch already has 4 sides, @pattern will be
  1500.  * put into an error status with a status of
  1501.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1502.  *
  1503.  * Since: 1.12
  1504.  **/
  1505. void
  1506. cairo_mesh_pattern_line_to (cairo_pattern_t *pattern,
  1507.                             double x, double y)
  1508. {
  1509.     cairo_mesh_pattern_t *mesh;
  1510.     cairo_point_double_t last_point;
  1511.     int last_point_idx, i, j;
  1512.  
  1513.     if (unlikely (pattern->status))
  1514.         return;
  1515.  
  1516.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1517.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1518.         return;
  1519.     }
  1520.  
  1521.     mesh = (cairo_mesh_pattern_t *) pattern;
  1522.     if (unlikely (!mesh->current_patch)) {
  1523.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1524.         return;
  1525.     }
  1526.  
  1527.     if (unlikely (mesh->current_side == 3)) {
  1528.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1529.         return;
  1530.     }
  1531.  
  1532.     if (mesh->current_side == -2) {
  1533.         cairo_mesh_pattern_move_to (pattern, x, y);
  1534.         return;
  1535.     }
  1536.  
  1537.     last_point_idx = 3 * (mesh->current_side + 1);
  1538.     i = mesh_path_point_i[last_point_idx];
  1539.     j = mesh_path_point_j[last_point_idx];
  1540.  
  1541.     last_point = mesh->current_patch->points[i][j];
  1542.  
  1543.     cairo_mesh_pattern_curve_to (pattern,
  1544.                                  (2 * last_point.x + x) * (1. / 3),
  1545.                                  (2 * last_point.y + y) * (1. / 3),
  1546.                                  (last_point.x + 2 * x) * (1. / 3),
  1547.                                  (last_point.y + 2 * y) * (1. / 3),
  1548.                                  x, y);
  1549. }
  1550. slim_hidden_def (cairo_mesh_pattern_line_to);
  1551.  
  1552. /**
  1553.  * cairo_mesh_pattern_move_to:
  1554.  * @pattern: a #cairo_pattern_t
  1555.  * @x: the X coordinate of the new position
  1556.  * @y: the Y coordinate of the new position
  1557.  *
  1558.  * Define the first point of the current patch in a mesh pattern.
  1559.  *
  1560.  * After this call the current point will be (@x, @y).
  1561.  *
  1562.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1563.  * into an error status with a status of
  1564.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current
  1565.  * patch or the current patch already has at least one side, @pattern
  1566.  * will be put into an error status with a status of
  1567.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1568.  *
  1569.  * Since: 1.12
  1570.  **/
  1571. void
  1572. cairo_mesh_pattern_move_to (cairo_pattern_t *pattern,
  1573.                             double x, double y)
  1574. {
  1575.     cairo_mesh_pattern_t *mesh;
  1576.  
  1577.     if (unlikely (pattern->status))
  1578.         return;
  1579.  
  1580.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1581.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1582.         return;
  1583.     }
  1584.  
  1585.     mesh = (cairo_mesh_pattern_t *) pattern;
  1586.     if (unlikely (!mesh->current_patch)) {
  1587.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1588.         return;
  1589.     }
  1590.  
  1591.     if (unlikely (mesh->current_side >= 0)) {
  1592.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1593.         return;
  1594.     }
  1595.  
  1596.     mesh->current_side = -1;
  1597.     mesh->current_patch->points[0][0].x = x;
  1598.     mesh->current_patch->points[0][0].y = y;
  1599. }
  1600. slim_hidden_def (cairo_mesh_pattern_move_to);
  1601.  
  1602. /**
  1603.  * cairo_mesh_pattern_set_control_point:
  1604.  * @pattern: a #cairo_pattern_t
  1605.  * @point_num: the control point to set the position for
  1606.  * @x: the X coordinate of the control point
  1607.  * @y: the Y coordinate of the control point
  1608.  *
  1609.  * Set an internal control point of the current patch.
  1610.  *
  1611.  * Valid values for @point_num are from 0 to 3 and identify the
  1612.  * control points as explained in cairo_pattern_create_mesh().
  1613.  *
  1614.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1615.  * into an error status with a status of
  1616.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @point_num is not valid,
  1617.  * @pattern will be put into an error status with a status of
  1618.  * %CAIRO_STATUS_INVALID_INDEX.  If @pattern has no current patch,
  1619.  * @pattern will be put into an error status with a status of
  1620.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1621.  *
  1622.  * Since: 1.12
  1623.  **/
  1624. void
  1625. cairo_mesh_pattern_set_control_point (cairo_pattern_t *pattern,
  1626.                                       unsigned int     point_num,
  1627.                                       double           x,
  1628.                                       double           y)
  1629. {
  1630.     cairo_mesh_pattern_t *mesh;
  1631.     int i, j;
  1632.  
  1633.     if (unlikely (pattern->status))
  1634.         return;
  1635.  
  1636.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1637.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1638.         return;
  1639.     }
  1640.  
  1641.     if (unlikely (point_num > 3)) {
  1642.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_INDEX);
  1643.         return;
  1644.     }
  1645.  
  1646.     mesh = (cairo_mesh_pattern_t *) pattern;
  1647.     if (unlikely (!mesh->current_patch)) {
  1648.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1649.         return;
  1650.     }
  1651.  
  1652.     i = mesh_control_point_i[point_num];
  1653.     j = mesh_control_point_j[point_num];
  1654.  
  1655.     mesh->current_patch->points[i][j].x = x;
  1656.     mesh->current_patch->points[i][j].y = y;
  1657.     mesh->has_control_point[point_num] = TRUE;
  1658. }
  1659.  
  1660. /* make room for at least one more color stop */
  1661. static cairo_status_t
  1662. _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
  1663. {
  1664.     cairo_gradient_stop_t *new_stops;
  1665.     int old_size = pattern->stops_size;
  1666.     int embedded_size = ARRAY_LENGTH (pattern->stops_embedded);
  1667.     int new_size = 2 * MAX (old_size, 4);
  1668.  
  1669.     /* we have a local buffer at pattern->stops_embedded.  try to fulfill the request
  1670.      * from there. */
  1671.     if (old_size < embedded_size) {
  1672.         pattern->stops = pattern->stops_embedded;
  1673.         pattern->stops_size = embedded_size;
  1674.         return CAIRO_STATUS_SUCCESS;
  1675.     }
  1676.  
  1677.     if (CAIRO_INJECT_FAULT ())
  1678.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1679.  
  1680.     assert (pattern->n_stops <= pattern->stops_size);
  1681.  
  1682.     if (pattern->stops == pattern->stops_embedded) {
  1683.         new_stops = _cairo_malloc_ab (new_size, sizeof (cairo_gradient_stop_t));
  1684.         if (new_stops)
  1685.             memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t));
  1686.     } else {
  1687.         new_stops = _cairo_realloc_ab (pattern->stops,
  1688.                                        new_size,
  1689.                                        sizeof (cairo_gradient_stop_t));
  1690.     }
  1691.  
  1692.     if (unlikely (new_stops == NULL))
  1693.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1694.  
  1695.     pattern->stops = new_stops;
  1696.     pattern->stops_size = new_size;
  1697.  
  1698.     return CAIRO_STATUS_SUCCESS;
  1699. }
  1700.  
  1701. static void
  1702. _cairo_mesh_pattern_set_corner_color (cairo_mesh_pattern_t *mesh,
  1703.                                       unsigned int     corner_num,
  1704.                                       double red, double green, double blue,
  1705.                                       double alpha)
  1706. {
  1707.     cairo_color_t *color;
  1708.  
  1709.     assert (mesh->current_patch);
  1710.     assert (corner_num <= 3);
  1711.  
  1712.     color = &mesh->current_patch->colors[corner_num];
  1713.     color->red   = red;
  1714.     color->green = green;
  1715.     color->blue  = blue;
  1716.     color->alpha = alpha;
  1717.  
  1718.     color->red_short   = _cairo_color_double_to_short (red);
  1719.     color->green_short = _cairo_color_double_to_short (green);
  1720.     color->blue_short  = _cairo_color_double_to_short (blue);
  1721.     color->alpha_short = _cairo_color_double_to_short (alpha);
  1722.  
  1723.     mesh->has_color[corner_num] = TRUE;
  1724. }
  1725.  
  1726. /**
  1727.  * cairo_mesh_pattern_set_corner_color_rgb:
  1728.  * @pattern: a #cairo_pattern_t
  1729.  * @corner_num: the corner to set the color for
  1730.  * @red: red component of color
  1731.  * @green: green component of color
  1732.  * @blue: blue component of color
  1733.  *
  1734.  * Sets the color of a corner of the current patch in a mesh pattern.
  1735.  *
  1736.  * The color is specified in the same way as in cairo_set_source_rgb().
  1737.  *
  1738.  * Valid values for @corner_num are from 0 to 3 and identify the
  1739.  * corners as explained in cairo_pattern_create_mesh().
  1740.  *
  1741.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1742.  * into an error status with a status of
  1743.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @corner_num is not valid,
  1744.  * @pattern will be put into an error status with a status of
  1745.  * %CAIRO_STATUS_INVALID_INDEX.  If @pattern has no current patch,
  1746.  * @pattern will be put into an error status with a status of
  1747.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1748.  *
  1749.  * Since: 1.12
  1750.  **/
  1751. void
  1752. cairo_mesh_pattern_set_corner_color_rgb (cairo_pattern_t *pattern,
  1753.                                          unsigned int     corner_num,
  1754.                                          double red, double green, double blue)
  1755. {
  1756.     cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, red, green, blue, 1.0);
  1757. }
  1758.  
  1759. /**
  1760.  * cairo_mesh_pattern_set_corner_color_rgba:
  1761.  * @pattern: a #cairo_pattern_t
  1762.  * @corner_num: the corner to set the color for
  1763.  * @red: red component of color
  1764.  * @green: green component of color
  1765.  * @blue: blue component of color
  1766.  * @alpha: alpha component of color
  1767.  *
  1768.  * Sets the color of a corner of the current patch in a mesh pattern.
  1769.  *
  1770.  * The color is specified in the same way as in cairo_set_source_rgba().
  1771.  *
  1772.  * Valid values for @corner_num are from 0 to 3 and identify the
  1773.  * corners as explained in cairo_pattern_create_mesh().
  1774.  *
  1775.  * Note: If @pattern is not a mesh pattern then @pattern will be put
  1776.  * into an error status with a status of
  1777.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @corner_num is not valid,
  1778.  * @pattern will be put into an error status with a status of
  1779.  * %CAIRO_STATUS_INVALID_INDEX.  If @pattern has no current patch,
  1780.  * @pattern will be put into an error status with a status of
  1781.  * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION.
  1782.  *
  1783.  * Since: 1.12
  1784.  **/
  1785. void
  1786. cairo_mesh_pattern_set_corner_color_rgba (cairo_pattern_t *pattern,
  1787.                                           unsigned int     corner_num,
  1788.                                           double red, double green, double blue,
  1789.                                           double alpha)
  1790. {
  1791.     cairo_mesh_pattern_t *mesh;
  1792.  
  1793.     if (unlikely (pattern->status))
  1794.         return;
  1795.  
  1796.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) {
  1797.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1798.         return;
  1799.     }
  1800.  
  1801.     if (unlikely (corner_num > 3)) {
  1802.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_INDEX);
  1803.         return;
  1804.     }
  1805.  
  1806.     mesh = (cairo_mesh_pattern_t *) pattern;
  1807.     if (unlikely (!mesh->current_patch)) {
  1808.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION);
  1809.         return;
  1810.     }
  1811.  
  1812.     red    = _cairo_restrict_value (red,    0.0, 1.0);
  1813.     green  = _cairo_restrict_value (green,  0.0, 1.0);
  1814.     blue   = _cairo_restrict_value (blue,   0.0, 1.0);
  1815.     alpha  = _cairo_restrict_value (alpha,  0.0, 1.0);
  1816.  
  1817.     _cairo_mesh_pattern_set_corner_color (mesh, corner_num, red, green, blue, alpha);
  1818. }
  1819. slim_hidden_def (cairo_mesh_pattern_set_corner_color_rgba);
  1820.  
  1821. static void
  1822. _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
  1823.                                double                    offset,
  1824.                                double                    red,
  1825.                                double                    green,
  1826.                                double                    blue,
  1827.                                double                    alpha)
  1828. {
  1829.     cairo_gradient_stop_t *stops;
  1830.     unsigned int           i;
  1831.  
  1832.     if (pattern->n_stops >= pattern->stops_size) {
  1833.         cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
  1834.         if (unlikely (status)) {
  1835.             status = _cairo_pattern_set_error (&pattern->base, status);
  1836.             return;
  1837.         }
  1838.     }
  1839.  
  1840.     stops = pattern->stops;
  1841.  
  1842.     for (i = 0; i < pattern->n_stops; i++)
  1843.     {
  1844.         if (offset < stops[i].offset)
  1845.         {
  1846.             memmove (&stops[i + 1], &stops[i],
  1847.                      sizeof (cairo_gradient_stop_t) * (pattern->n_stops - i));
  1848.  
  1849.             break;
  1850.         }
  1851.     }
  1852.  
  1853.     stops[i].offset = offset;
  1854.  
  1855.     stops[i].color.red   = red;
  1856.     stops[i].color.green = green;
  1857.     stops[i].color.blue  = blue;
  1858.     stops[i].color.alpha = alpha;
  1859.  
  1860.     stops[i].color.red_short   = _cairo_color_double_to_short (red);
  1861.     stops[i].color.green_short = _cairo_color_double_to_short (green);
  1862.     stops[i].color.blue_short  = _cairo_color_double_to_short (blue);
  1863.     stops[i].color.alpha_short = _cairo_color_double_to_short (alpha);
  1864.  
  1865.     pattern->n_stops++;
  1866. }
  1867.  
  1868. /**
  1869.  * cairo_pattern_add_color_stop_rgb:
  1870.  * @pattern: a #cairo_pattern_t
  1871.  * @offset: an offset in the range [0.0 .. 1.0]
  1872.  * @red: red component of color
  1873.  * @green: green component of color
  1874.  * @blue: blue component of color
  1875.  *
  1876.  * Adds an opaque color stop to a gradient pattern. The offset
  1877.  * specifies the location along the gradient's control vector. For
  1878.  * example, a linear gradient's control vector is from (x0,y0) to
  1879.  * (x1,y1) while a radial gradient's control vector is from any point
  1880.  * on the start circle to the corresponding point on the end circle.
  1881.  *
  1882.  * The color is specified in the same way as in cairo_set_source_rgb().
  1883.  *
  1884.  * If two (or more) stops are specified with identical offset values,
  1885.  * they will be sorted according to the order in which the stops are
  1886.  * added, (stops added earlier will compare less than stops added
  1887.  * later). This can be useful for reliably making sharp color
  1888.  * transitions instead of the typical blend.
  1889.  *
  1890.  *
  1891.  * Note: If the pattern is not a gradient pattern, (eg. a linear or
  1892.  * radial pattern), then the pattern will be put into an error status
  1893.  * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH.
  1894.  *
  1895.  * Since: 1.0
  1896.  **/
  1897. void
  1898. cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
  1899.                                   double           offset,
  1900.                                   double           red,
  1901.                                   double           green,
  1902.                                   double           blue)
  1903. {
  1904.     cairo_pattern_add_color_stop_rgba (pattern, offset, red, green, blue, 1.0);
  1905. }
  1906.  
  1907. /**
  1908.  * cairo_pattern_add_color_stop_rgba:
  1909.  * @pattern: a #cairo_pattern_t
  1910.  * @offset: an offset in the range [0.0 .. 1.0]
  1911.  * @red: red component of color
  1912.  * @green: green component of color
  1913.  * @blue: blue component of color
  1914.  * @alpha: alpha component of color
  1915.  *
  1916.  * Adds a translucent color stop to a gradient pattern. The offset
  1917.  * specifies the location along the gradient's control vector. For
  1918.  * example, a linear gradient's control vector is from (x0,y0) to
  1919.  * (x1,y1) while a radial gradient's control vector is from any point
  1920.  * on the start circle to the corresponding point on the end circle.
  1921.  *
  1922.  * The color is specified in the same way as in cairo_set_source_rgba().
  1923.  *
  1924.  * If two (or more) stops are specified with identical offset values,
  1925.  * they will be sorted according to the order in which the stops are
  1926.  * added, (stops added earlier will compare less than stops added
  1927.  * later). This can be useful for reliably making sharp color
  1928.  * transitions instead of the typical blend.
  1929.  *
  1930.  * Note: If the pattern is not a gradient pattern, (eg. a linear or
  1931.  * radial pattern), then the pattern will be put into an error status
  1932.  * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH.
  1933.  *
  1934.  * Since: 1.0
  1935.  **/
  1936. void
  1937. cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
  1938.                                    double          offset,
  1939.                                    double          red,
  1940.                                    double          green,
  1941.                                    double          blue,
  1942.                                    double          alpha)
  1943. {
  1944.     if (pattern->status)
  1945.         return;
  1946.  
  1947.     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
  1948.         pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
  1949.     {
  1950.         _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  1951.         return;
  1952.     }
  1953.  
  1954.     offset = _cairo_restrict_value (offset, 0.0, 1.0);
  1955.     red    = _cairo_restrict_value (red,    0.0, 1.0);
  1956.     green  = _cairo_restrict_value (green,  0.0, 1.0);
  1957.     blue   = _cairo_restrict_value (blue,   0.0, 1.0);
  1958.     alpha  = _cairo_restrict_value (alpha,  0.0, 1.0);
  1959.  
  1960.     _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
  1961.                                    offset, red, green, blue, alpha);
  1962. }
  1963. slim_hidden_def (cairo_pattern_add_color_stop_rgba);
  1964.  
  1965. /**
  1966.  * cairo_pattern_set_matrix:
  1967.  * @pattern: a #cairo_pattern_t
  1968.  * @matrix: a #cairo_matrix_t
  1969.  *
  1970.  * Sets the pattern's transformation matrix to @matrix. This matrix is
  1971.  * a transformation from user space to pattern space.
  1972.  *
  1973.  * When a pattern is first created it always has the identity matrix
  1974.  * for its transformation matrix, which means that pattern space is
  1975.  * initially identical to user space.
  1976.  *
  1977.  * Important: Please note that the direction of this transformation
  1978.  * matrix is from user space to pattern space. This means that if you
  1979.  * imagine the flow from a pattern to user space (and on to device
  1980.  * space), then coordinates in that flow will be transformed by the
  1981.  * inverse of the pattern matrix.
  1982.  *
  1983.  * For example, if you want to make a pattern appear twice as large as
  1984.  * it does by default the correct code to use is:
  1985.  *
  1986.  * <informalexample><programlisting>
  1987.  * cairo_matrix_init_scale (&amp;matrix, 0.5, 0.5);
  1988.  * cairo_pattern_set_matrix (pattern, &amp;matrix);
  1989.  * </programlisting></informalexample>
  1990.  *
  1991.  * Meanwhile, using values of 2.0 rather than 0.5 in the code above
  1992.  * would cause the pattern to appear at half of its default size.
  1993.  *
  1994.  * Also, please note the discussion of the user-space locking
  1995.  * semantics of cairo_set_source().
  1996.  *
  1997.  * Since: 1.0
  1998.  **/
  1999. void
  2000. cairo_pattern_set_matrix (cairo_pattern_t      *pattern,
  2001.                           const cairo_matrix_t *matrix)
  2002. {
  2003.     cairo_matrix_t inverse;
  2004.     cairo_status_t status;
  2005.  
  2006.     if (pattern->status)
  2007.         return;
  2008.  
  2009.     if (memcmp (&pattern->matrix, matrix, sizeof (cairo_matrix_t)) == 0)
  2010.         return;
  2011.  
  2012.     pattern->matrix = *matrix;
  2013.     _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_MATRIX);
  2014.  
  2015.     inverse = *matrix;
  2016.     status = cairo_matrix_invert (&inverse);
  2017.     if (unlikely (status))
  2018.         status = _cairo_pattern_set_error (pattern, status);
  2019. }
  2020. slim_hidden_def (cairo_pattern_set_matrix);
  2021.  
  2022. /**
  2023.  * cairo_pattern_get_matrix:
  2024.  * @pattern: a #cairo_pattern_t
  2025.  * @matrix: return value for the matrix
  2026.  *
  2027.  * Stores the pattern's transformation matrix into @matrix.
  2028.  *
  2029.  * Since: 1.0
  2030.  **/
  2031. void
  2032. cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
  2033. {
  2034.     *matrix = pattern->matrix;
  2035. }
  2036.  
  2037. /**
  2038.  * cairo_pattern_set_filter:
  2039.  * @pattern: a #cairo_pattern_t
  2040.  * @filter: a #cairo_filter_t describing the filter to use for resizing
  2041.  * the pattern
  2042.  *
  2043.  * Sets the filter to be used for resizing when using this pattern.
  2044.  * See #cairo_filter_t for details on each filter.
  2045.  *
  2046.  * * Note that you might want to control filtering even when you do not
  2047.  * have an explicit #cairo_pattern_t object, (for example when using
  2048.  * cairo_set_source_surface()). In these cases, it is convenient to
  2049.  * use cairo_get_source() to get access to the pattern that cairo
  2050.  * creates implicitly. For example:
  2051.  *
  2052.  * <informalexample><programlisting>
  2053.  * cairo_set_source_surface (cr, image, x, y);
  2054.  * cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
  2055.  * </programlisting></informalexample>
  2056.  *
  2057.  * Since: 1.0
  2058.  **/
  2059. void
  2060. cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
  2061. {
  2062.     if (pattern->status)
  2063.         return;
  2064.  
  2065.     pattern->filter = filter;
  2066.     _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_FILTER);
  2067. }
  2068.  
  2069. /**
  2070.  * cairo_pattern_get_filter:
  2071.  * @pattern: a #cairo_pattern_t
  2072.  *
  2073.  * Gets the current filter for a pattern.  See #cairo_filter_t
  2074.  * for details on each filter.
  2075.  *
  2076.  * Return value: the current filter used for resizing the pattern.
  2077.  *
  2078.  * Since: 1.0
  2079.  **/
  2080. cairo_filter_t
  2081. cairo_pattern_get_filter (cairo_pattern_t *pattern)
  2082. {
  2083.     return pattern->filter;
  2084. }
  2085.  
  2086. /**
  2087.  * cairo_pattern_set_extend:
  2088.  * @pattern: a #cairo_pattern_t
  2089.  * @extend: a #cairo_extend_t describing how the area outside of the
  2090.  * pattern will be drawn
  2091.  *
  2092.  * Sets the mode to be used for drawing outside the area of a pattern.
  2093.  * See #cairo_extend_t for details on the semantics of each extend
  2094.  * strategy.
  2095.  *
  2096.  * The default extend mode is %CAIRO_EXTEND_NONE for surface patterns
  2097.  * and %CAIRO_EXTEND_PAD for gradient patterns.
  2098.  *
  2099.  * Since: 1.0
  2100.  **/
  2101. void
  2102. cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
  2103. {
  2104.     if (pattern->status)
  2105.         return;
  2106.  
  2107.     pattern->extend = extend;
  2108.     _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_EXTEND);
  2109. }
  2110.  
  2111. /**
  2112.  * cairo_pattern_get_extend:
  2113.  * @pattern: a #cairo_pattern_t
  2114.  *
  2115.  * Gets the current extend mode for a pattern.  See #cairo_extend_t
  2116.  * for details on the semantics of each extend strategy.
  2117.  *
  2118.  * Return value: the current extend strategy used for drawing the
  2119.  * pattern.
  2120.  *
  2121.  * Since: 1.0
  2122.  **/
  2123. cairo_extend_t
  2124. cairo_pattern_get_extend (cairo_pattern_t *pattern)
  2125. {
  2126.     return pattern->extend;
  2127. }
  2128. slim_hidden_def (cairo_pattern_get_extend);
  2129.  
  2130. void
  2131. _cairo_pattern_transform (cairo_pattern_t       *pattern,
  2132.                           const cairo_matrix_t  *ctm_inverse)
  2133. {
  2134.     if (pattern->status)
  2135.         return;
  2136.  
  2137.     cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix);
  2138. }
  2139.  
  2140. static cairo_bool_t
  2141. _linear_pattern_is_degenerate (const cairo_linear_pattern_t *linear)
  2142. {
  2143.     return fabs (linear->pd1.x - linear->pd2.x) < DBL_EPSILON &&
  2144.            fabs (linear->pd1.y - linear->pd2.y) < DBL_EPSILON;
  2145. }
  2146.  
  2147. static cairo_bool_t
  2148. _radial_pattern_is_degenerate (const cairo_radial_pattern_t *radial)
  2149. {
  2150.     /* A radial pattern is considered degenerate if it can be
  2151.      * represented as a solid or clear pattern.  This corresponds to
  2152.      * one of the two cases:
  2153.      *
  2154.      * 1) The radii are both very small:
  2155.      *      |dr| < DBL_EPSILON && min (r0, r1) < DBL_EPSILON
  2156.      *
  2157.      * 2) The two circles have about the same radius and are very
  2158.      *    close to each other (approximately a cylinder gradient that
  2159.      *    doesn't move with the parameter):
  2160.      *      |dr| < DBL_EPSILON && max (|dx|, |dy|) < 2 * DBL_EPSILON
  2161.      *
  2162.      * These checks are consistent with the assumptions used in
  2163.      * _cairo_radial_pattern_box_to_parameter ().
  2164.      */
  2165.  
  2166.     return fabs (radial->cd1.radius - radial->cd2.radius) < DBL_EPSILON &&
  2167.         (MIN (radial->cd1.radius, radial->cd2.radius) < DBL_EPSILON ||
  2168.          MAX (fabs (radial->cd1.center.x - radial->cd2.center.x),
  2169.               fabs (radial->cd1.center.y - radial->cd2.center.y)) < 2 * DBL_EPSILON);
  2170. }
  2171.  
  2172. static void
  2173. _cairo_linear_pattern_box_to_parameter (const cairo_linear_pattern_t *linear,
  2174.                                         double x0, double y0,
  2175.                                         double x1, double y1,
  2176.                                         double range[2])
  2177. {
  2178.     double t0, tdx, tdy;
  2179.     double p1x, p1y, pdx, pdy, invsqnorm;
  2180.  
  2181.     assert (! _linear_pattern_is_degenerate (linear));
  2182.  
  2183.     /*
  2184.      * Linear gradients are othrogonal to the line passing through
  2185.      * their extremes. Because of convexity, the parameter range can
  2186.      * be computed as the convex hull (one the real line) of the
  2187.      * parameter values of the 4 corners of the box.
  2188.      *
  2189.      * The parameter value t for a point (x,y) can be computed as:
  2190.      *
  2191.      *   t = (p2 - p1) . (x,y) / |p2 - p1|^2
  2192.      *
  2193.      * t0  is the t value for the top left corner
  2194.      * tdx is the difference between left and right corners
  2195.      * tdy is the difference between top and bottom corners
  2196.      */
  2197.  
  2198.     p1x = linear->pd1.x;
  2199.     p1y = linear->pd1.y;
  2200.     pdx = linear->pd2.x - p1x;
  2201.     pdy = linear->pd2.y - p1y;
  2202.     invsqnorm = 1.0 / (pdx * pdx + pdy * pdy);
  2203.     pdx *= invsqnorm;
  2204.     pdy *= invsqnorm;
  2205.  
  2206.     t0 = (x0 - p1x) * pdx + (y0 - p1y) * pdy;
  2207.     tdx = (x1 - x0) * pdx;
  2208.     tdy = (y1 - y0) * pdy;
  2209.  
  2210.     /*
  2211.      * Because of the linearity of the t value, tdx can simply be
  2212.      * added the t0 to move along the top edge. After this, range[0]
  2213.      * and range[1] represent the parameter range for the top edge, so
  2214.      * extending it to include the whole box simply requires adding
  2215.      * tdy to the correct extreme.
  2216.      */
  2217.  
  2218.     range[0] = range[1] = t0;
  2219.     if (tdx < 0)
  2220.         range[0] += tdx;
  2221.     else
  2222.         range[1] += tdx;
  2223.  
  2224.     if (tdy < 0)
  2225.         range[0] += tdy;
  2226.     else
  2227.         range[1] += tdy;
  2228. }
  2229.  
  2230. static cairo_bool_t
  2231. _extend_range (double range[2], double value, cairo_bool_t valid)
  2232. {
  2233.     if (!valid)
  2234.         range[0] = range[1] = value;
  2235.     else if (value < range[0])
  2236.         range[0] = value;
  2237.     else if (value > range[1])
  2238.         range[1] = value;
  2239.  
  2240.     return TRUE;
  2241. }
  2242.  
  2243. /*
  2244.  * _cairo_radial_pattern_focus_is_inside:
  2245.  *
  2246.  * Returns %TRUE if and only if the focus point exists and is
  2247.  * contained in one of the two extreme circles. This condition is
  2248.  * equivalent to one of the two extreme circles being completely
  2249.  * contained in the other one.
  2250.  *
  2251.  * Note: if the focus is on the border of one of the two circles (in
  2252.  * which case the circles are tangent in the focus point), it is not
  2253.  * considered as contained in the circle, hence this function returns
  2254.  * %FALSE.
  2255.  *
  2256.  */
  2257. cairo_bool_t
  2258. _cairo_radial_pattern_focus_is_inside (const cairo_radial_pattern_t *radial)
  2259. {
  2260.     double cx, cy, cr, dx, dy, dr;
  2261.  
  2262.     cx = radial->cd1.center.x;
  2263.     cy = radial->cd1.center.y;
  2264.     cr = radial->cd1.radius;
  2265.     dx = radial->cd2.center.x - cx;
  2266.     dy = radial->cd2.center.y - cy;
  2267.     dr = radial->cd2.radius   - cr;
  2268.  
  2269.     return dx*dx + dy*dy < dr*dr;
  2270. }
  2271.  
  2272. static void
  2273. _cairo_radial_pattern_box_to_parameter (const cairo_radial_pattern_t *radial,
  2274.                                         double x0, double y0,
  2275.                                         double x1, double y1,
  2276.                                         double tolerance,
  2277.                                         double range[2])
  2278. {
  2279.     double cx, cy, cr, dx, dy, dr;
  2280.     double a, x_focus, y_focus;
  2281.     double mindr, minx, miny, maxx, maxy;
  2282.     cairo_bool_t valid;
  2283.  
  2284.     assert (! _radial_pattern_is_degenerate (radial));
  2285.     assert (x0 < x1);
  2286.     assert (y0 < y1);
  2287.  
  2288.     tolerance = MAX (tolerance, DBL_EPSILON);
  2289.  
  2290.     range[0] = range[1] = 0;
  2291.     valid = FALSE;
  2292.  
  2293.     x_focus = y_focus = 0; /* silence gcc */
  2294.  
  2295.     cx = radial->cd1.center.x;
  2296.     cy = radial->cd1.center.y;
  2297.     cr = radial->cd1.radius;
  2298.     dx = radial->cd2.center.x - cx;
  2299.     dy = radial->cd2.center.y - cy;
  2300.     dr = radial->cd2.radius   - cr;
  2301.  
  2302.     /* translate by -(cx, cy) to simplify computations */
  2303.     x0 -= cx;
  2304.     y0 -= cy;
  2305.     x1 -= cx;
  2306.     y1 -= cy;
  2307.  
  2308.     /* enlarge boundaries slightly to avoid rounding problems in the
  2309.      * parameter range computation */
  2310.     x0 -= DBL_EPSILON;
  2311.     y0 -= DBL_EPSILON;
  2312.     x1 += DBL_EPSILON;
  2313.     y1 += DBL_EPSILON;
  2314.  
  2315.     /* enlarge boundaries even more to avoid rounding problems when
  2316.      * testing if a point belongs to the box */
  2317.     minx = x0 - DBL_EPSILON;
  2318.     miny = y0 - DBL_EPSILON;
  2319.     maxx = x1 + DBL_EPSILON;
  2320.     maxy = y1 + DBL_EPSILON;
  2321.  
  2322.     /* we dont' allow negative radiuses, so we will be checking that
  2323.      * t*dr >= mindr to consider t valid */
  2324.     mindr = -(cr + DBL_EPSILON);
  2325.  
  2326.     /*
  2327.      * After the previous transformations, the start circle is
  2328.      * centered in the origin and has radius cr. A 1-unit change in
  2329.      * the t parameter corresponds to dx,dy,dr changes in the x,y,r of
  2330.      * the circle (center coordinates, radius).
  2331.      *
  2332.      * To compute the minimum range needed to correctly draw the
  2333.      * pattern, we start with an empty range and extend it to include
  2334.      * the circles touching the bounding box or within it.
  2335.      */
  2336.  
  2337.     /*
  2338.      * Focus, the point where the circle has radius == 0.
  2339.      *
  2340.      * r = cr + t * dr = 0
  2341.      * t = -cr / dr
  2342.      *
  2343.      * If the radius is constant (dr == 0) there is no focus (the
  2344.      * gradient represents a cylinder instead of a cone).
  2345.      */
  2346.     if (fabs (dr) >= DBL_EPSILON) {
  2347.         double t_focus;
  2348.  
  2349.         t_focus = -cr / dr;
  2350.         x_focus = t_focus * dx;
  2351.         y_focus = t_focus * dy;
  2352.         if (minx <= x_focus && x_focus <= maxx &&
  2353.             miny <= y_focus && y_focus <= maxy)
  2354.         {
  2355.             valid = _extend_range (range, t_focus, valid);
  2356.         }
  2357.     }
  2358.  
  2359.     /*
  2360.      * Circles externally tangent to box edges.
  2361.      *
  2362.      * All circles have center in (dx, dy) * t
  2363.      *
  2364.      * If the circle is tangent to the line defined by the edge of the
  2365.      * box, then at least one of the following holds true:
  2366.      *
  2367.      *   (dx*t) + (cr + dr*t) == x0 (left   edge)
  2368.      *   (dx*t) - (cr + dr*t) == x1 (right  edge)
  2369.      *   (dy*t) + (cr + dr*t) == y0 (top    edge)
  2370.      *   (dy*t) - (cr + dr*t) == y1 (bottom edge)
  2371.      *
  2372.      * The solution is only valid if the tangent point is actually on
  2373.      * the edge, i.e. if its y coordinate is in [y0,y1] for left/right
  2374.      * edges and if its x coordinate is in [x0,x1] for top/bottom
  2375.      * edges.
  2376.      *
  2377.      * For the first equation:
  2378.      *
  2379.      *   (dx + dr) * t = x0 - cr
  2380.      *   t = (x0 - cr) / (dx + dr)
  2381.      *   y = dy * t
  2382.      *
  2383.      * in the code this becomes:
  2384.      *
  2385.      *   t_edge = (num) / (den)
  2386.      *   v = (delta) * t_edge
  2387.      *
  2388.      * If the denominator in t is 0, the pattern is tangent to a line
  2389.      * parallel to the edge under examination. The corner-case where
  2390.      * the boundary line is the same as the edge is handled by the
  2391.      * focus point case and/or by the a==0 case.
  2392.      */
  2393. #define T_EDGE(num,den,delta,lower,upper)                               \
  2394.     if (fabs (den) >= DBL_EPSILON) {                                    \
  2395.         double t_edge, v;                                               \
  2396.                                                                         \
  2397.         t_edge = (num) / (den);                                         \
  2398.         v = t_edge * (delta);                                           \
  2399.         if (t_edge * dr >= mindr && (lower) <= v && v <= (upper))       \
  2400.             valid = _extend_range (range, t_edge, valid);               \
  2401.     }
  2402.  
  2403.     /* circles tangent (externally) to left/right/top/bottom edge */
  2404.     T_EDGE (x0 - cr, dx + dr, dy, miny, maxy);
  2405.     T_EDGE (x1 + cr, dx - dr, dy, miny, maxy);
  2406.     T_EDGE (y0 - cr, dy + dr, dx, minx, maxx);
  2407.     T_EDGE (y1 + cr, dy - dr, dx, minx, maxx);
  2408.  
  2409. #undef T_EDGE
  2410.  
  2411.     /*
  2412.      * Circles passing through a corner.
  2413.      *
  2414.      * A circle passing through the point (x,y) satisfies:
  2415.      *
  2416.      * (x-t*dx)^2 + (y-t*dy)^2 == (cr + t*dr)^2
  2417.      *
  2418.      * If we set:
  2419.      *   a = dx^2 + dy^2 - dr^2
  2420.      *   b = x*dx + y*dy + cr*dr
  2421.      *   c = x^2 + y^2 - cr^2
  2422.      * we have:
  2423.      *   a*t^2 - 2*b*t + c == 0
  2424.      */
  2425.     a = dx * dx + dy * dy - dr * dr;
  2426.     if (fabs (a) < DBL_EPSILON * DBL_EPSILON) {
  2427.         double b, maxd2;
  2428.  
  2429.         /* Ensure that gradients with both a and dr small are
  2430.          * considered degenerate.
  2431.          * The floating point version of the degeneracy test implemented
  2432.          * in _radial_pattern_is_degenerate() is:
  2433.          *
  2434.          *  1) The circles are practically the same size:
  2435.          *     |dr| < DBL_EPSILON
  2436.          *  AND
  2437.          *  2a) The circles are both very small:
  2438.          *      min (r0, r1) < DBL_EPSILON
  2439.          *   OR
  2440.          *  2b) The circles are very close to each other:
  2441.          *      max (|dx|, |dy|) < 2 * DBL_EPSILON
  2442.          *
  2443.          * Assuming that the gradient is not degenerate, we want to
  2444.          * show that |a| < DBL_EPSILON^2 implies |dr| >= DBL_EPSILON.
  2445.          *
  2446.          * If the gradient is not degenerate yet it has |dr| <
  2447.          * DBL_EPSILON, (2b) is false, thus:
  2448.          *
  2449.          *   max (|dx|, |dy|) >= 2*DBL_EPSILON
  2450.          * which implies:
  2451.          *   4*DBL_EPSILON^2 <= max (|dx|, |dy|)^2 <= dx^2 + dy^2
  2452.          *
  2453.          * From the definition of a, we get:
  2454.          *   a = dx^2 + dy^2 - dr^2 < DBL_EPSILON^2
  2455.          *   dx^2 + dy^2 - DBL_EPSILON^2 < dr^2
  2456.          *   3*DBL_EPSILON^2 < dr^2
  2457.          *
  2458.          * which is inconsistent with the hypotheses, thus |dr| <
  2459.          * DBL_EPSILON is false or the gradient is degenerate.
  2460.          */
  2461.         assert (fabs (dr) >= DBL_EPSILON);
  2462.  
  2463.         /*
  2464.          * If a == 0, all the circles are tangent to a line in the
  2465.          * focus point. If this line is within the box extents, we
  2466.          * should add the circle with infinite radius, but this would
  2467.          * make the range unbounded, so we add the smallest circle whose
  2468.          * distance to the desired (degenerate) circle within the
  2469.          * bounding box does not exceed tolerance.
  2470.          *
  2471.          * The equation of the line is b==0, i.e.:
  2472.          *   x*dx + y*dy + cr*dr == 0
  2473.          *
  2474.          * We compute the intersection of the line with the box and
  2475.          * keep the intersection with maximum square distance (maxd2)
  2476.          * from the focus point.
  2477.          *
  2478.          * In the code the intersection is represented in another
  2479.          * coordinate system, whose origin is the focus point and
  2480.          * which has a u,v axes, which are respectively orthogonal and
  2481.          * parallel to the edge being intersected.
  2482.          *
  2483.          * The intersection is valid only if it belongs to the box,
  2484.          * otherwise it is ignored.
  2485.          *
  2486.          * For example:
  2487.          *
  2488.          *   y = y0
  2489.          *   x*dx + y0*dy + cr*dr == 0
  2490.          *   x = -(y0*dy + cr*dr) / dx
  2491.          *
  2492.          * which in (u,v) is:
  2493.          *   u = y0 - y_focus
  2494.          *   v = -(y0*dy + cr*dr) / dx - x_focus
  2495.          *
  2496.          * In the code:
  2497.          *   u = (edge) - (u_origin)
  2498.          *   v = -((edge) * (delta) + cr*dr) / (den) - v_focus
  2499.          */
  2500. #define T_EDGE(edge,delta,den,lower,upper,u_origin,v_origin)    \
  2501.         if (fabs (den) >= DBL_EPSILON) {                        \
  2502.             double v;                                           \
  2503.                                                                 \
  2504.             v = -((edge) * (delta) + cr * dr) / (den);          \
  2505.             if ((lower) <= v && v <= (upper)) {                 \
  2506.                 double u, d2;                                   \
  2507.                                                                 \
  2508.                 u = (edge) - (u_origin);                        \
  2509.                 v -= (v_origin);                                \
  2510.                 d2 = u*u + v*v;                                 \
  2511.                 if (maxd2 < d2)                                 \
  2512.                     maxd2 = d2;                                 \
  2513.             }                                                   \
  2514.         }
  2515.  
  2516.         maxd2 = 0;
  2517.  
  2518.         /* degenerate circles (lines) passing through each edge */
  2519.         T_EDGE (y0, dy, dx, minx, maxx, y_focus, x_focus);
  2520.         T_EDGE (y1, dy, dx, minx, maxx, y_focus, x_focus);
  2521.         T_EDGE (x0, dx, dy, miny, maxy, x_focus, y_focus);
  2522.         T_EDGE (x1, dx, dy, miny, maxy, x_focus, y_focus);
  2523.  
  2524. #undef T_EDGE
  2525.  
  2526.         /*
  2527.          * The limit circle can be transformed rigidly to the y=0 line
  2528.          * and the circles tangent to it in (0,0) are:
  2529.          *
  2530.          *   x^2 + (y-r)^2 = r^2  <=>  x^2 + y^2 - 2*y*r = 0
  2531.          *
  2532.          * y is the distance from the line, in our case tolerance;
  2533.          * x is the distance along the line, i.e. sqrt(maxd2),
  2534.          * so:
  2535.          *
  2536.          *   r = cr + dr * t = (maxd2 + tolerance^2) / (2*tolerance)
  2537.          *   t = (r - cr) / dr =
  2538.          *       (maxd2 + tolerance^2 - 2*tolerance*cr) / (2*tolerance*dr)
  2539.          */
  2540.         if (maxd2 > 0) {
  2541.             double t_limit = maxd2 + tolerance*tolerance - 2*tolerance*cr;
  2542.             t_limit /= 2 * tolerance * dr;
  2543.             valid = _extend_range (range, t_limit, valid);
  2544.         }
  2545.  
  2546.         /*
  2547.          * Nondegenerate, nonlimit circles passing through the corners.
  2548.          *
  2549.          * a == 0 && a*t^2 - 2*b*t + c == 0
  2550.          *
  2551.          * t = c / (2*b)
  2552.          *
  2553.          * The b == 0 case has just been handled, so we only have to
  2554.          * compute this if b != 0.
  2555.          */
  2556. #define T_CORNER(x,y)                                                   \
  2557.         b = (x) * dx + (y) * dy + cr * dr;                              \
  2558.         if (fabs (b) >= DBL_EPSILON) {                                  \
  2559.             double t_corner;                                            \
  2560.             double x2 = (x) * (x);                                      \
  2561.             double y2 = (y) * (y);                                      \
  2562.             double cr2 = (cr) * (cr);                                   \
  2563.             double c = x2 + y2 - cr2;                                   \
  2564.                                                                         \
  2565.             t_corner = 0.5 * c / b;                                     \
  2566.             if (t_corner * dr >= mindr)                                 \
  2567.                 valid = _extend_range (range, t_corner, valid);         \
  2568.         }
  2569.  
  2570.         /* circles touching each corner */
  2571.         T_CORNER (x0, y0);
  2572.         T_CORNER (x0, y1);
  2573.         T_CORNER (x1, y0);
  2574.         T_CORNER (x1, y1);
  2575.  
  2576. #undef T_CORNER
  2577.     } else {
  2578.         double inva, b, c, d;
  2579.  
  2580.         inva = 1 / a;
  2581.  
  2582.         /*
  2583.          * Nondegenerate, nonlimit circles passing through the corners.
  2584.          *
  2585.          * a != 0 && a*t^2 - 2*b*t + c == 0
  2586.          *
  2587.          * t = (b +- sqrt (b*b - a*c)) / a
  2588.          *
  2589.          * If the argument of sqrt() is negative, then no circle
  2590.          * passes through the corner.
  2591.          */
  2592. #define T_CORNER(x,y)                                                   \
  2593.         b = (x) * dx + (y) * dy + cr * dr;                              \
  2594.         c = (x) * (x) + (y) * (y) - cr * cr;                            \
  2595.         d = b * b - a * c;                                              \
  2596.         if (d >= 0) {                                                   \
  2597.             double t_corner;                                            \
  2598.                                                                         \
  2599.             d = sqrt (d);                                               \
  2600.             t_corner = (b + d) * inva;                                  \
  2601.             if (t_corner * dr >= mindr)                                 \
  2602.                 valid = _extend_range (range, t_corner, valid);         \
  2603.             t_corner = (b - d) * inva;                                  \
  2604.             if (t_corner * dr >= mindr)                                 \
  2605.                 valid = _extend_range (range, t_corner, valid);         \
  2606.         }
  2607.  
  2608.         /* circles touching each corner */
  2609.         T_CORNER (x0, y0);
  2610.         T_CORNER (x0, y1);
  2611.         T_CORNER (x1, y0);
  2612.         T_CORNER (x1, y1);
  2613.  
  2614. #undef T_CORNER
  2615.     }
  2616. }
  2617.  
  2618. /**
  2619.  * _cairo_gradient_pattern_box_to_parameter:
  2620.  *
  2621.  * Compute a interpolation range sufficient to draw (within the given
  2622.  * tolerance) the gradient in the given box getting the same result as
  2623.  * using the (-inf, +inf) range.
  2624.  *
  2625.  * Assumes that the pattern is not degenerate. This can be guaranteed
  2626.  * by simplifying it to a solid clear if _cairo_pattern_is_clear or to
  2627.  * a solid color if _cairo_gradient_pattern_is_solid.
  2628.  *
  2629.  * The range isn't guaranteed to be minimal, but it tries to.
  2630.  **/
  2631. void
  2632. _cairo_gradient_pattern_box_to_parameter (const cairo_gradient_pattern_t *gradient,
  2633.                                           double x0, double y0,
  2634.                                           double x1, double y1,
  2635.                                           double tolerance,
  2636.                                           double out_range[2])
  2637. {
  2638.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  2639.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  2640.  
  2641.     if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
  2642.         _cairo_linear_pattern_box_to_parameter ((cairo_linear_pattern_t *) gradient,
  2643.                                                 x0, y0, x1, y1, out_range);
  2644.     } else {
  2645.         _cairo_radial_pattern_box_to_parameter ((cairo_radial_pattern_t *) gradient,
  2646.                                                 x0, y0, x1, y1, tolerance, out_range);
  2647.     }
  2648. }
  2649.  
  2650. /**
  2651.  * _cairo_gradient_pattern_interpolate:
  2652.  *
  2653.  * Interpolate between the start and end objects of linear or radial
  2654.  * gradients.  The interpolated object is stored in out_circle, with
  2655.  * the radius being zero in the linear gradient case.
  2656.  **/
  2657. void
  2658. _cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient,
  2659.                                      double                          t,
  2660.                                      cairo_circle_double_t          *out_circle)
  2661. {
  2662.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  2663.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  2664.  
  2665. #define lerp(a,b) (a)*(1-t) + (b)*t
  2666.  
  2667.     if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
  2668.         cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
  2669.         out_circle->center.x = lerp (linear->pd1.x, linear->pd2.x);
  2670.         out_circle->center.y = lerp (linear->pd1.y, linear->pd2.y);
  2671.         out_circle->radius = 0;
  2672.     } else {
  2673.         cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient;
  2674.         out_circle->center.x = lerp (radial->cd1.center.x, radial->cd2.center.x);
  2675.         out_circle->center.y = lerp (radial->cd1.center.y, radial->cd2.center.y);
  2676.         out_circle->radius   = lerp (radial->cd1.radius  , radial->cd2.radius);
  2677.     }
  2678.  
  2679. #undef lerp
  2680. }
  2681.  
  2682.  
  2683. /**
  2684.  * _cairo_gradient_pattern_fit_to_range:
  2685.  *
  2686.  * Scale the extremes of a gradient to guarantee that the coordinates
  2687.  * and their deltas are within the range (-max_value, max_value). The
  2688.  * new extremes are stored in out_circle.
  2689.  *
  2690.  * The pattern matrix is scaled to guarantee that the aspect of the
  2691.  * gradient is the same and the result is stored in out_matrix.
  2692.  *
  2693.  **/
  2694. void
  2695. _cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient,
  2696.                                       double                          max_value,
  2697.                                       cairo_matrix_t                 *out_matrix,
  2698.                                       cairo_circle_double_t           out_circle[2])
  2699. {
  2700.     double dim;
  2701.  
  2702.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  2703.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  2704.  
  2705.     if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
  2706.         cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
  2707.  
  2708.         out_circle[0].center = linear->pd1;
  2709.         out_circle[0].radius = 0;
  2710.         out_circle[1].center = linear->pd2;
  2711.         out_circle[1].radius = 0;
  2712.  
  2713.         dim = fabs (linear->pd1.x);
  2714.         dim = MAX (dim, fabs (linear->pd1.y));
  2715.         dim = MAX (dim, fabs (linear->pd2.x));
  2716.         dim = MAX (dim, fabs (linear->pd2.y));
  2717.         dim = MAX (dim, fabs (linear->pd1.x - linear->pd2.x));
  2718.         dim = MAX (dim, fabs (linear->pd1.y - linear->pd2.y));
  2719.     } else {
  2720.         cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient;
  2721.  
  2722.         out_circle[0] = radial->cd1;
  2723.         out_circle[1] = radial->cd2;
  2724.  
  2725.         dim = fabs (radial->cd1.center.x);
  2726.         dim = MAX (dim, fabs (radial->cd1.center.y));
  2727.         dim = MAX (dim, fabs (radial->cd1.radius));
  2728.         dim = MAX (dim, fabs (radial->cd2.center.x));
  2729.         dim = MAX (dim, fabs (radial->cd2.center.y));
  2730.         dim = MAX (dim, fabs (radial->cd2.radius));
  2731.         dim = MAX (dim, fabs (radial->cd1.center.x - radial->cd2.center.x));
  2732.         dim = MAX (dim, fabs (radial->cd1.center.y - radial->cd2.center.y));
  2733.         dim = MAX (dim, fabs (radial->cd1.radius   - radial->cd2.radius));
  2734.     }
  2735.  
  2736.     if (unlikely (dim > max_value)) {
  2737.         cairo_matrix_t scale;
  2738.  
  2739.         dim = max_value / dim;
  2740.  
  2741.         out_circle[0].center.x *= dim;
  2742.         out_circle[0].center.y *= dim;
  2743.         out_circle[0].radius   *= dim;
  2744.         out_circle[1].center.x *= dim;
  2745.         out_circle[1].center.y *= dim;
  2746.         out_circle[1].radius   *= dim;
  2747.  
  2748.         cairo_matrix_init_scale (&scale, dim, dim);
  2749.         cairo_matrix_multiply (out_matrix, &gradient->base.matrix, &scale);
  2750.     } else {
  2751.         *out_matrix = gradient->base.matrix;
  2752.     }
  2753. }
  2754.  
  2755. static cairo_bool_t
  2756. _gradient_is_clear (const cairo_gradient_pattern_t *gradient,
  2757.                     const cairo_rectangle_int_t *extents)
  2758. {
  2759.     unsigned int i;
  2760.  
  2761.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  2762.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  2763.  
  2764.     if (gradient->n_stops == 0 ||
  2765.         (gradient->base.extend == CAIRO_EXTEND_NONE &&
  2766.          gradient->stops[0].offset == gradient->stops[gradient->n_stops - 1].offset))
  2767.         return TRUE;
  2768.  
  2769.     if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL) {
  2770.         /* degenerate radial gradients are clear */
  2771.         if (_radial_pattern_is_degenerate ((cairo_radial_pattern_t *) gradient))
  2772.             return TRUE;
  2773.     } else if (gradient->base.extend == CAIRO_EXTEND_NONE) {
  2774.         /* EXTEND_NONE degenerate linear gradients are clear */
  2775.         if (_linear_pattern_is_degenerate ((cairo_linear_pattern_t *) gradient))
  2776.             return TRUE;
  2777.     }
  2778.  
  2779.     /* Check if the extents intersect the drawn part of the pattern. */
  2780.     if (extents != NULL &&
  2781.         (gradient->base.extend == CAIRO_EXTEND_NONE ||
  2782.          gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL))
  2783.     {
  2784.         double t[2];
  2785.  
  2786.         _cairo_gradient_pattern_box_to_parameter (gradient,
  2787.                                                   extents->x,
  2788.                                                   extents->y,
  2789.                                                   extents->x + extents->width,
  2790.                                                   extents->y + extents->height,
  2791.                                                   DBL_EPSILON,
  2792.                                                   t);
  2793.  
  2794.         if (gradient->base.extend == CAIRO_EXTEND_NONE &&
  2795.             (t[0] >= gradient->stops[gradient->n_stops - 1].offset ||
  2796.              t[1] <= gradient->stops[0].offset))
  2797.         {
  2798.                 return TRUE;
  2799.         }
  2800.  
  2801.         if (t[0] == t[1])
  2802.             return TRUE;
  2803.     }
  2804.  
  2805.     for (i = 0; i < gradient->n_stops; i++)
  2806.         if (! CAIRO_COLOR_IS_CLEAR (&gradient->stops[i].color))
  2807.             return FALSE;
  2808.  
  2809.     return TRUE;
  2810. }
  2811.  
  2812. static void
  2813. _gradient_color_average (const cairo_gradient_pattern_t *gradient,
  2814.                          cairo_color_t *color)
  2815. {
  2816.     double delta0, delta1;
  2817.     double r, g, b, a;
  2818.     unsigned int i, start = 1, end;
  2819.  
  2820.     assert (gradient->n_stops > 0);
  2821.     assert (gradient->base.extend != CAIRO_EXTEND_NONE);
  2822.  
  2823.     if (gradient->n_stops == 1) {
  2824.         _cairo_color_init_rgba (color,
  2825.                                 gradient->stops[0].color.red,
  2826.                                 gradient->stops[0].color.green,
  2827.                                 gradient->stops[0].color.blue,
  2828.                                 gradient->stops[0].color.alpha);
  2829.         return;
  2830.     }
  2831.  
  2832.     end = gradient->n_stops - 1;
  2833.  
  2834.     switch (gradient->base.extend) {
  2835.     case CAIRO_EXTEND_REPEAT:
  2836.       /*
  2837.        * Sa, Sb and Sy, Sz are the first two and last two stops respectively.
  2838.        * The weight of the first and last stop can be computed as the area of
  2839.        * the following triangles (taken with height 1, since the whole [0-1]
  2840.        * will have total weight 1 this way): b*h/2
  2841.        *
  2842.        *              +                   +
  2843.        *            / |\                / | \
  2844.        *          /   | \             /   |   \
  2845.        *        /     |  \          /     |     \
  2846.        * ~~~~~+---+---+---+~~~~~~~+-------+---+---+~~~~~
  2847.        *   -1+Sz  0  Sa   Sb      Sy     Sz   1  1+Sa
  2848.        *
  2849.        * For the first stop: (Sb-(-1+Sz)/2 = (1+Sb-Sz)/2
  2850.        * For the last stop: ((1+Sa)-Sy)/2 = (1+Sa-Sy)/2
  2851.        * Halving the result is done after summing up all the areas.
  2852.        */
  2853.         delta0 = 1.0 + gradient->stops[1].offset - gradient->stops[end].offset;
  2854.         delta1 = 1.0 + gradient->stops[0].offset - gradient->stops[end-1].offset;
  2855.         break;
  2856.  
  2857.     case CAIRO_EXTEND_REFLECT:
  2858.       /*
  2859.        * Sa, Sb and Sy, Sz are the first two and last two stops respectively.
  2860.        * The weight of the first and last stop can be computed as the area of
  2861.        * the following trapezoids (taken with height 1, since the whole [0-1]
  2862.        * will have total weight 1 this way): (b+B)*h/2
  2863.        *
  2864.        * +-------+                   +---+
  2865.        * |       |\                / |   |
  2866.        * |       | \             /   |   |
  2867.        * |       |  \          /     |   |
  2868.        * +-------+---+~~~~~~~+-------+---+
  2869.        * 0      Sa   Sb      Sy     Sz   1
  2870.        *
  2871.        * For the first stop: (Sa+Sb)/2
  2872.        * For the last stop: ((1-Sz) + (1-Sy))/2 = (2-Sy-Sz)/2
  2873.        * Halving the result is done after summing up all the areas.
  2874.        */
  2875.         delta0 = gradient->stops[0].offset + gradient->stops[1].offset;
  2876.         delta1 = 2.0 - gradient->stops[end-1].offset - gradient->stops[end].offset;
  2877.         break;
  2878.  
  2879.     case CAIRO_EXTEND_PAD:
  2880.       /* PAD is computed as the average of the first and last stop:
  2881.        *  - take both of them with weight 1 (they will be halved
  2882.        *    after the whole sum has been computed).
  2883.        *  - avoid summing any of the inner stops.
  2884.        */
  2885.         delta0 = delta1 = 1.0;
  2886.         start = end;
  2887.         break;
  2888.  
  2889.     case CAIRO_EXTEND_NONE:
  2890.     default:
  2891.         ASSERT_NOT_REACHED;
  2892.         _cairo_color_init_rgba (color, 0, 0, 0, 0);
  2893.         return;
  2894.     }
  2895.  
  2896.     r = delta0 * gradient->stops[0].color.red;
  2897.     g = delta0 * gradient->stops[0].color.green;
  2898.     b = delta0 * gradient->stops[0].color.blue;
  2899.     a = delta0 * gradient->stops[0].color.alpha;
  2900.  
  2901.     for (i = start; i < end; ++i) {
  2902.       /* Inner stops weight is the same as the area of the triangle they influence
  2903.        * (which goes from the stop before to the stop after), again with height 1
  2904.        * since the whole must sum up to 1: b*h/2
  2905.        * Halving is done after the whole sum has been computed.
  2906.        */
  2907.         double delta = gradient->stops[i+1].offset - gradient->stops[i-1].offset;
  2908.         r += delta * gradient->stops[i].color.red;
  2909.         g += delta * gradient->stops[i].color.green;
  2910.         b += delta * gradient->stops[i].color.blue;
  2911.         a += delta * gradient->stops[i].color.alpha;
  2912.     }
  2913.  
  2914.     r += delta1 * gradient->stops[end].color.red;
  2915.     g += delta1 * gradient->stops[end].color.green;
  2916.     b += delta1 * gradient->stops[end].color.blue;
  2917.     a += delta1 * gradient->stops[end].color.alpha;
  2918.  
  2919.     _cairo_color_init_rgba (color, r * .5, g * .5, b * .5, a * .5);
  2920. }
  2921.  
  2922. /**
  2923.  * _cairo_pattern_alpha_range:
  2924.  *
  2925.  * Convenience function to determine the minimum and maximum alpha in
  2926.  * the drawn part of a pattern (i.e. ignoring clear parts caused by
  2927.  * extend modes and/or pattern shape).
  2928.  *
  2929.  * If not NULL, out_min and out_max will be set respectively to the
  2930.  * minimum and maximum alpha value of the pattern.
  2931.  **/
  2932. void
  2933. _cairo_pattern_alpha_range (const cairo_pattern_t *pattern,
  2934.                             double                *out_min,
  2935.                             double                *out_max)
  2936. {
  2937.     double alpha_min, alpha_max;
  2938.  
  2939.     switch (pattern->type) {
  2940.     case CAIRO_PATTERN_TYPE_SOLID: {
  2941.         const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
  2942.         alpha_min = alpha_max = solid->color.alpha;
  2943.         break;
  2944.     }
  2945.  
  2946.     case CAIRO_PATTERN_TYPE_LINEAR:
  2947.     case CAIRO_PATTERN_TYPE_RADIAL: {
  2948.         const cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern;
  2949.         unsigned int i;
  2950.  
  2951.         assert (gradient->n_stops >= 1);
  2952.  
  2953.         alpha_min = alpha_max = gradient->stops[0].color.alpha;
  2954.         for (i = 1; i < gradient->n_stops; i++) {
  2955.             if (alpha_min > gradient->stops[i].color.alpha)
  2956.                 alpha_min = gradient->stops[i].color.alpha;
  2957.             else if (alpha_max < gradient->stops[i].color.alpha)
  2958.                 alpha_max = gradient->stops[i].color.alpha;
  2959.         }
  2960.  
  2961.         break;
  2962.     }
  2963.  
  2964.     case CAIRO_PATTERN_TYPE_MESH: {
  2965.         const cairo_mesh_pattern_t *mesh = (const cairo_mesh_pattern_t *) pattern;
  2966.         const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0);
  2967.         unsigned int i, j, n = _cairo_array_num_elements (&mesh->patches);
  2968.  
  2969.         assert (n >= 1);
  2970.  
  2971.         alpha_min = alpha_max = patch[0].colors[0].alpha;
  2972.         for (i = 0; i < n; i++) {
  2973.             for (j = 0; j < 4; j++) {
  2974.                 if (patch[i].colors[j].alpha < alpha_min)
  2975.                     alpha_min = patch[i].colors[j].alpha;
  2976.                 else if (patch[i].colors[j].alpha > alpha_max)
  2977.                     alpha_max = patch[i].colors[j].alpha;
  2978.             }
  2979.         }
  2980.  
  2981.         break;
  2982.     }
  2983.  
  2984.     default:
  2985.         ASSERT_NOT_REACHED;
  2986.         /* fall through */
  2987.  
  2988.     case CAIRO_PATTERN_TYPE_SURFACE:
  2989.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  2990.         alpha_min = 0;
  2991.         alpha_max = 1;
  2992.         break;
  2993.     }
  2994.  
  2995.     if (out_min)
  2996.         *out_min = alpha_min;
  2997.     if (out_max)
  2998.         *out_max = alpha_max;
  2999. }
  3000.  
  3001. /**
  3002.  * _cairo_mesh_pattern_coord_box:
  3003.  *
  3004.  * Convenience function to determine the range of the coordinates of
  3005.  * the points used to define the patches of the mesh.
  3006.  *
  3007.  * This is guaranteed to contain the pattern extents, but might not be
  3008.  * tight, just like a Bezier curve is always inside the convex hull of
  3009.  * the control points.
  3010.  *
  3011.  * This function cannot be used while the mesh is being constructed.
  3012.  *
  3013.  * The function returns TRUE and sets the output parametes to define
  3014.  * the coodrinate range if the mesh pattern contains at least one
  3015.  * patch, otherwise it returns FALSE.
  3016.  **/
  3017. cairo_bool_t
  3018. _cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh,
  3019.                                double                     *out_xmin,
  3020.                                double                     *out_ymin,
  3021.                                double                     *out_xmax,
  3022.                                double                     *out_ymax)
  3023. {
  3024.     const cairo_mesh_patch_t *patch;
  3025.     unsigned int num_patches, i, j, k;
  3026.     double x0, y0, x1, y1;
  3027.  
  3028.     assert (mesh->current_patch == NULL);
  3029.  
  3030.     num_patches = _cairo_array_num_elements (&mesh->patches);
  3031.  
  3032.     if (num_patches == 0)
  3033.         return FALSE;
  3034.  
  3035.     patch = _cairo_array_index_const (&mesh->patches, 0);
  3036.     x0 = x1 = patch->points[0][0].x;
  3037.     y0 = y1 = patch->points[0][0].y;
  3038.  
  3039.     for (i = 0; i < num_patches; i++) {
  3040.         for (j = 0; j < 4; j++) {
  3041.             for (k = 0; k < 4; k++) {
  3042.                 x0 = MIN (x0, patch[i].points[j][k].x);
  3043.                 y0 = MIN (y0, patch[i].points[j][k].y);
  3044.                 x1 = MAX (x1, patch[i].points[j][k].x);
  3045.                 y1 = MAX (y1, patch[i].points[j][k].y);
  3046.             }
  3047.         }
  3048.     }
  3049.  
  3050.     *out_xmin = x0;
  3051.     *out_ymin = y0;
  3052.     *out_xmax = x1;
  3053.     *out_ymax = y1;
  3054.  
  3055.     return TRUE;
  3056. }
  3057.  
  3058. /**
  3059.  * _cairo_gradient_pattern_is_solid:
  3060.  *
  3061.  * Convenience function to determine whether a gradient pattern is
  3062.  * a solid color within the given extents. In this case the color
  3063.  * argument is initialized to the color the pattern represents.
  3064.  * This functions doesn't handle completely transparent gradients,
  3065.  * thus it should be called only after _cairo_pattern_is_clear has
  3066.  * returned FALSE.
  3067.  *
  3068.  * Return value: %TRUE if the pattern is a solid color.
  3069.  **/
  3070. cairo_bool_t
  3071. _cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient,
  3072.                                   const cairo_rectangle_int_t *extents,
  3073.                                   cairo_color_t *color)
  3074. {
  3075.     unsigned int i;
  3076.  
  3077.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  3078.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  3079.  
  3080.     /* TODO: radial */
  3081.     if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
  3082.         cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
  3083.         if (_linear_pattern_is_degenerate (linear)) {
  3084.             _gradient_color_average (gradient, color);
  3085.             return TRUE;
  3086.         }
  3087.  
  3088.         if (gradient->base.extend == CAIRO_EXTEND_NONE) {
  3089.             double t[2];
  3090.  
  3091.             /* We already know that the pattern is not clear, thus if some
  3092.              * part of it is clear, the whole is not solid.
  3093.              */
  3094.  
  3095.             if (extents == NULL)
  3096.                 return FALSE;
  3097.  
  3098.             _cairo_linear_pattern_box_to_parameter (linear,
  3099.                                                     extents->x,
  3100.                                                     extents->y,
  3101.                                                     extents->x + extents->width,
  3102.                                                     extents->y + extents->height,
  3103.                                                     t);
  3104.  
  3105.             if (t[0] < 0.0 || t[1] > 1.0)
  3106.                 return FALSE;
  3107.         }
  3108.     } else
  3109.         return FALSE;
  3110.  
  3111.     for (i = 1; i < gradient->n_stops; i++)
  3112.         if (! _cairo_color_stop_equal (&gradient->stops[0].color,
  3113.                                        &gradient->stops[i].color))
  3114.             return FALSE;
  3115.  
  3116.     _cairo_color_init_rgba (color,
  3117.                             gradient->stops[0].color.red,
  3118.                             gradient->stops[0].color.green,
  3119.                             gradient->stops[0].color.blue,
  3120.                             gradient->stops[0].color.alpha);
  3121.  
  3122.     return TRUE;
  3123. }
  3124.  
  3125. static cairo_bool_t
  3126. _mesh_is_clear (const cairo_mesh_pattern_t *mesh)
  3127. {
  3128.     double x1, y1, x2, y2;
  3129.     cairo_bool_t is_valid;
  3130.  
  3131.     is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2);
  3132.     if (!is_valid)
  3133.         return TRUE;
  3134.  
  3135.     if (x2 - x1 < DBL_EPSILON || y2 - y1 < DBL_EPSILON)
  3136.         return TRUE;
  3137.  
  3138.     return FALSE;
  3139. }
  3140.  
  3141. /**
  3142.  * _cairo_pattern_is_opaque_solid:
  3143.  *
  3144.  * Convenience function to determine whether a pattern is an opaque
  3145.  * (alpha==1.0) solid color pattern. This is done by testing whether
  3146.  * the pattern's alpha value when converted to a byte is 255, so if a
  3147.  * backend actually supported deep alpha channels this function might
  3148.  * not do the right thing.
  3149.  *
  3150.  * Return value: %TRUE if the pattern is an opaque, solid color.
  3151.  **/
  3152. cairo_bool_t
  3153. _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern)
  3154. {
  3155.     cairo_solid_pattern_t *solid;
  3156.  
  3157.     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
  3158.         return FALSE;
  3159.  
  3160.     solid = (cairo_solid_pattern_t *) pattern;
  3161.  
  3162.     return CAIRO_COLOR_IS_OPAQUE (&solid->color);
  3163. }
  3164.  
  3165. static cairo_bool_t
  3166. _surface_is_opaque (const cairo_surface_pattern_t *pattern,
  3167.                     const cairo_rectangle_int_t *sample)
  3168. {
  3169.     cairo_rectangle_int_t extents;
  3170.  
  3171.     if (pattern->surface->content & CAIRO_CONTENT_ALPHA)
  3172.         return FALSE;
  3173.  
  3174.     if (pattern->base.extend != CAIRO_EXTEND_NONE)
  3175.         return TRUE;
  3176.  
  3177.     if (! _cairo_surface_get_extents (pattern->surface, &extents))
  3178.         return TRUE;
  3179.  
  3180.     if (sample == NULL)
  3181.         return FALSE;
  3182.  
  3183.     return _cairo_rectangle_contains_rectangle (&extents, sample);
  3184. }
  3185.  
  3186. static cairo_bool_t
  3187. _raster_source_is_opaque (const cairo_raster_source_pattern_t *pattern,
  3188.                           const cairo_rectangle_int_t *sample)
  3189. {
  3190.     if (pattern->content & CAIRO_CONTENT_ALPHA)
  3191.         return FALSE;
  3192.  
  3193.     if (pattern->base.extend != CAIRO_EXTEND_NONE)
  3194.         return TRUE;
  3195.  
  3196.     if (sample == NULL)
  3197.         return FALSE;
  3198.  
  3199.     return _cairo_rectangle_contains_rectangle (&pattern->extents, sample);
  3200. }
  3201.  
  3202. static cairo_bool_t
  3203. _surface_is_clear (const cairo_surface_pattern_t *pattern)
  3204. {
  3205.     cairo_rectangle_int_t extents;
  3206.  
  3207.     if (_cairo_surface_get_extents (pattern->surface, &extents) &&
  3208.         (extents.width == 0 || extents.height == 0))
  3209.         return TRUE;
  3210.  
  3211.     return pattern->surface->is_clear &&
  3212.         pattern->surface->content & CAIRO_CONTENT_ALPHA;
  3213. }
  3214.  
  3215. static cairo_bool_t
  3216. _raster_source_is_clear (const cairo_raster_source_pattern_t *pattern)
  3217. {
  3218.     return pattern->extents.width == 0 || pattern->extents.height == 0;
  3219. }
  3220.  
  3221. static cairo_bool_t
  3222. _gradient_is_opaque (const cairo_gradient_pattern_t *gradient,
  3223.                      const cairo_rectangle_int_t *sample)
  3224. {
  3225.     unsigned int i;
  3226.  
  3227.     assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
  3228.             gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
  3229.  
  3230.     if (gradient->n_stops == 0 ||
  3231.         (gradient->base.extend == CAIRO_EXTEND_NONE &&
  3232.          gradient->stops[0].offset == gradient->stops[gradient->n_stops - 1].offset))
  3233.         return FALSE;
  3234.  
  3235.     if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
  3236.         if (gradient->base.extend == CAIRO_EXTEND_NONE) {
  3237.             double t[2];
  3238.             cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
  3239.  
  3240.             /* EXTEND_NONE degenerate radial gradients are clear */
  3241.             if (_linear_pattern_is_degenerate (linear))
  3242.                 return FALSE;
  3243.  
  3244.             if (sample == NULL)
  3245.                 return FALSE;
  3246.  
  3247.             _cairo_linear_pattern_box_to_parameter (linear,
  3248.                                                     sample->x,
  3249.                                                     sample->y,
  3250.                                                     sample->x + sample->width,
  3251.                                                     sample->y + sample->height,
  3252.                                                     t);
  3253.  
  3254.             if (t[0] < 0.0 || t[1] > 1.0)
  3255.                 return FALSE;
  3256.         }
  3257.     } else
  3258.         return FALSE; /* TODO: check actual intersection */
  3259.  
  3260.     for (i = 0; i < gradient->n_stops; i++)
  3261.         if (! CAIRO_COLOR_IS_OPAQUE (&gradient->stops[i].color))
  3262.             return FALSE;
  3263.  
  3264.     return TRUE;
  3265. }
  3266.  
  3267. /**
  3268.  * _cairo_pattern_is_opaque:
  3269.  *
  3270.  * Convenience function to determine whether a pattern is an opaque
  3271.  * pattern (of any type). The same caveats that apply to
  3272.  * _cairo_pattern_is_opaque_solid apply here as well.
  3273.  *
  3274.  * Return value: %TRUE if the pattern is a opaque.
  3275.  **/
  3276. cairo_bool_t
  3277. _cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern,
  3278.                           const cairo_rectangle_int_t *sample)
  3279. {
  3280.     const cairo_pattern_union_t *pattern;
  3281.  
  3282.     if (abstract_pattern->has_component_alpha)
  3283.         return FALSE;
  3284.  
  3285.     pattern = (cairo_pattern_union_t *) abstract_pattern;
  3286.     switch (pattern->base.type) {
  3287.     case CAIRO_PATTERN_TYPE_SOLID:
  3288.         return _cairo_pattern_is_opaque_solid (abstract_pattern);
  3289.     case CAIRO_PATTERN_TYPE_SURFACE:
  3290.         return _surface_is_opaque (&pattern->surface, sample);
  3291.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  3292.         return _raster_source_is_opaque (&pattern->raster_source, sample);
  3293.     case CAIRO_PATTERN_TYPE_LINEAR:
  3294.     case CAIRO_PATTERN_TYPE_RADIAL:
  3295.         return _gradient_is_opaque (&pattern->gradient.base, sample);
  3296.     case CAIRO_PATTERN_TYPE_MESH:
  3297.         return FALSE;
  3298.     }
  3299.  
  3300.     ASSERT_NOT_REACHED;
  3301.     return FALSE;
  3302. }
  3303.  
  3304. cairo_bool_t
  3305. _cairo_pattern_is_clear (const cairo_pattern_t *abstract_pattern)
  3306. {
  3307.     const cairo_pattern_union_t *pattern;
  3308.  
  3309.     if (abstract_pattern->has_component_alpha)
  3310.         return FALSE;
  3311.  
  3312.     pattern = (cairo_pattern_union_t *) abstract_pattern;
  3313.     switch (abstract_pattern->type) {
  3314.     case CAIRO_PATTERN_TYPE_SOLID:
  3315.         return CAIRO_COLOR_IS_CLEAR (&pattern->solid.color);
  3316.     case CAIRO_PATTERN_TYPE_SURFACE:
  3317.         return _surface_is_clear (&pattern->surface);
  3318.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  3319.         return _raster_source_is_clear (&pattern->raster_source);
  3320.     case CAIRO_PATTERN_TYPE_LINEAR:
  3321.     case CAIRO_PATTERN_TYPE_RADIAL:
  3322.         return _gradient_is_clear (&pattern->gradient.base, NULL);
  3323.     case CAIRO_PATTERN_TYPE_MESH:
  3324.         return _mesh_is_clear (&pattern->mesh);
  3325.     }
  3326.  
  3327.     ASSERT_NOT_REACHED;
  3328.     return FALSE;
  3329. }
  3330.  
  3331. /**
  3332.  * _cairo_pattern_analyze_filter:
  3333.  * @pattern: surface pattern
  3334.  * @pad_out: location to store necessary padding in the source image, or %NULL
  3335.  * Returns: the optimized #cairo_filter_t to use with @pattern.
  3336.  *
  3337.  * Analyze the filter to determine how much extra needs to be sampled
  3338.  * from the source image to account for the filter radius and whether
  3339.  * we can optimize the filter to a simpler value.
  3340.  *
  3341.  * XXX: We don't actually have any way of querying the backend for
  3342.  *      the filter radius, so we just guess base on what we know that
  3343.  *      backends do currently (see bug #10508)
  3344.  **/
  3345. cairo_filter_t
  3346. _cairo_pattern_analyze_filter (const cairo_pattern_t    *pattern,
  3347.                                double                   *pad_out)
  3348. {
  3349.     double pad;
  3350.     cairo_filter_t optimized_filter;
  3351.  
  3352.     switch (pattern->filter) {
  3353.     case CAIRO_FILTER_GOOD:
  3354.     case CAIRO_FILTER_BEST:
  3355.     case CAIRO_FILTER_BILINEAR:
  3356.         /* If source pixels map 1:1 onto destination pixels, we do
  3357.          * not need to filter (and do not want to filter, since it
  3358.          * will cause blurriness)
  3359.          */
  3360.         if (_cairo_matrix_is_pixel_exact (&pattern->matrix)) {
  3361.             pad = 0.;
  3362.             optimized_filter = CAIRO_FILTER_NEAREST;
  3363.         } else {
  3364.             /* 0.5 is enough for a bilinear filter. It's possible we
  3365.              * should defensively use more for CAIRO_FILTER_BEST, but
  3366.              * without a single example, it's hard to know how much
  3367.              * more would be defensive...
  3368.              */
  3369.             pad = 0.5;
  3370.             optimized_filter = pattern->filter;
  3371.         }
  3372.         break;
  3373.  
  3374.     case CAIRO_FILTER_FAST:
  3375.     case CAIRO_FILTER_NEAREST:
  3376.     case CAIRO_FILTER_GAUSSIAN:
  3377.     default:
  3378.         pad = 0.;
  3379.         optimized_filter = pattern->filter;
  3380.         break;
  3381.     }
  3382.  
  3383.     if (pad_out)
  3384.         *pad_out = pad;
  3385.  
  3386.     return optimized_filter;
  3387. }
  3388.  
  3389. cairo_filter_t
  3390. _cairo_pattern_sampled_area (const cairo_pattern_t *pattern,
  3391.                              const cairo_rectangle_int_t *extents,
  3392.                              cairo_rectangle_int_t *sample)
  3393. {
  3394.     cairo_filter_t filter;
  3395.     double x1, x2, y1, y2;
  3396.     double pad;
  3397.  
  3398.     filter = _cairo_pattern_analyze_filter (pattern, &pad);
  3399.     if (pad == 0.0 && _cairo_matrix_is_identity (&pattern->matrix)) {
  3400.         *sample = *extents;
  3401.         return filter;
  3402.     }
  3403.  
  3404.     x1 = extents->x;
  3405.     y1 = extents->y;
  3406.     x2 = extents->x + (int) extents->width;
  3407.     y2 = extents->y + (int) extents->height;
  3408.  
  3409.     _cairo_matrix_transform_bounding_box (&pattern->matrix,
  3410.                                           &x1, &y1, &x2, &y2,
  3411.                                           NULL);
  3412.     if (x1 > CAIRO_RECT_INT_MIN)
  3413.         sample->x = floor (x1 - pad);
  3414.     else
  3415.         sample->x = CAIRO_RECT_INT_MIN;
  3416.  
  3417.     if (y1 > CAIRO_RECT_INT_MIN)
  3418.         sample->y = floor (y1 - pad);
  3419.     else
  3420.         sample->y = CAIRO_RECT_INT_MIN;
  3421.  
  3422.     if (x2 < CAIRO_RECT_INT_MAX)
  3423.         sample->width = ceil (x2 + pad);
  3424.     else
  3425.         sample->width = CAIRO_RECT_INT_MAX;
  3426.  
  3427.     if (y2 < CAIRO_RECT_INT_MAX)
  3428.         sample->height = ceil (y2 + pad);
  3429.     else
  3430.         sample->height = CAIRO_RECT_INT_MAX;
  3431.  
  3432.     sample->width  -= sample->x;
  3433.     sample->height -= sample->y;
  3434.  
  3435.     return filter;
  3436. }
  3437.  
  3438. /**
  3439.  * _cairo_pattern_get_extents:
  3440.  *
  3441.  * Return the "target-space" extents of @pattern in @extents.
  3442.  *
  3443.  * For unbounded patterns, the @extents will be initialized with
  3444.  * "infinite" extents, (minimum and maximum fixed-point values).
  3445.  *
  3446.  * XXX: Currently, bounded gradient patterns will also return
  3447.  * "infinite" extents, though it would be possible to optimize these
  3448.  * with a little more work.
  3449.  **/
  3450. void
  3451. _cairo_pattern_get_extents (const cairo_pattern_t         *pattern,
  3452.                             cairo_rectangle_int_t         *extents)
  3453. {
  3454.     double x1, y1, x2, y2;
  3455.     cairo_status_t status;
  3456.  
  3457.     switch (pattern->type) {
  3458.     case CAIRO_PATTERN_TYPE_SOLID:
  3459.         goto UNBOUNDED;
  3460.  
  3461.     case CAIRO_PATTERN_TYPE_SURFACE:
  3462.         {
  3463.             cairo_rectangle_int_t surface_extents;
  3464.             const cairo_surface_pattern_t *surface_pattern =
  3465.                 (const cairo_surface_pattern_t *) pattern;
  3466.             cairo_surface_t *surface = surface_pattern->surface;
  3467.             double pad;
  3468.  
  3469.             if (! _cairo_surface_get_extents (surface, &surface_extents))
  3470.                 goto UNBOUNDED;
  3471.  
  3472.             if (surface_extents.width == 0 || surface_extents.height == 0)
  3473.                 goto EMPTY;
  3474.  
  3475.             if (pattern->extend != CAIRO_EXTEND_NONE)
  3476.                 goto UNBOUNDED;
  3477.  
  3478.             /* The filter can effectively enlarge the extents of the
  3479.              * pattern, so extend as necessary.
  3480.              */
  3481.             _cairo_pattern_analyze_filter (&surface_pattern->base, &pad);
  3482.             x1 = surface_extents.x - pad;
  3483.             y1 = surface_extents.y - pad;
  3484.             x2 = surface_extents.x + (int) surface_extents.width  + pad;
  3485.             y2 = surface_extents.y + (int) surface_extents.height + pad;
  3486.         }
  3487.         break;
  3488.  
  3489.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  3490.         {
  3491.             const cairo_raster_source_pattern_t *raster =
  3492.                 (const cairo_raster_source_pattern_t *) pattern;
  3493.             double pad;
  3494.  
  3495.             if (raster->extents.width == 0 || raster->extents.height == 0)
  3496.                 goto EMPTY;
  3497.  
  3498.             if (pattern->extend != CAIRO_EXTEND_NONE)
  3499.                 goto UNBOUNDED;
  3500.  
  3501.             /* The filter can effectively enlarge the extents of the
  3502.              * pattern, so extend as necessary.
  3503.              */
  3504.             _cairo_pattern_analyze_filter (pattern, &pad);
  3505.             x1 = raster->extents.x - pad;
  3506.             y1 = raster->extents.y - pad;
  3507.             x2 = raster->extents.x + (int) raster->extents.width  + pad;
  3508.             y2 = raster->extents.y + (int) raster->extents.height + pad;
  3509.         }
  3510.         break;
  3511.  
  3512.     case CAIRO_PATTERN_TYPE_RADIAL:
  3513.         {
  3514.             const cairo_radial_pattern_t *radial =
  3515.                 (const cairo_radial_pattern_t *) pattern;
  3516.             double cx1, cy1;
  3517.             double cx2, cy2;
  3518.             double r1, r2;
  3519.  
  3520.             if (_radial_pattern_is_degenerate (radial)) {
  3521.                 /* cairo-gstate should have optimised degenerate
  3522.                  * patterns to solid clear patterns, so we can ignore
  3523.                  * them here. */
  3524.                 goto EMPTY;
  3525.             }
  3526.  
  3527.             /* TODO: in some cases (focus outside/on the circle) it is
  3528.              * half-bounded. */
  3529.             if (pattern->extend != CAIRO_EXTEND_NONE)
  3530.                 goto UNBOUNDED;
  3531.  
  3532.             cx1 = radial->cd1.center.x;
  3533.             cy1 = radial->cd1.center.y;
  3534.             r1  = radial->cd1.radius;
  3535.  
  3536.             cx2 = radial->cd2.center.x;
  3537.             cy2 = radial->cd2.center.y;
  3538.             r2  = radial->cd2.radius;
  3539.  
  3540.             x1 = MIN (cx1 - r1, cx2 - r2);
  3541.             y1 = MIN (cy1 - r1, cy2 - r2);
  3542.             x2 = MAX (cx1 + r1, cx2 + r2);
  3543.             y2 = MAX (cy1 + r1, cy2 + r2);
  3544.         }
  3545.         break;
  3546.  
  3547.     case CAIRO_PATTERN_TYPE_LINEAR:
  3548.         {
  3549.             const cairo_linear_pattern_t *linear =
  3550.                 (const cairo_linear_pattern_t *) pattern;
  3551.  
  3552.             if (pattern->extend != CAIRO_EXTEND_NONE)
  3553.                 goto UNBOUNDED;
  3554.  
  3555.             if (_linear_pattern_is_degenerate (linear)) {
  3556.                 /* cairo-gstate should have optimised degenerate
  3557.                  * patterns to solid ones, so we can again ignore
  3558.                  * them here. */
  3559.                 goto EMPTY;
  3560.             }
  3561.  
  3562.             /* TODO: to get tight extents, use the matrix to transform
  3563.              * the pattern instead of transforming the extents later. */
  3564.             if (pattern->matrix.xy != 0. || pattern->matrix.yx != 0.)
  3565.                 goto UNBOUNDED;
  3566.  
  3567.             if (linear->pd1.x == linear->pd2.x) {
  3568.                 x1 = -HUGE_VAL;
  3569.                 x2 = HUGE_VAL;
  3570.                 y1 = MIN (linear->pd1.y, linear->pd2.y);
  3571.                 y2 = MAX (linear->pd1.y, linear->pd2.y);
  3572.             } else if (linear->pd1.y == linear->pd2.y) {
  3573.                 x1 = MIN (linear->pd1.x, linear->pd2.x);
  3574.                 x2 = MAX (linear->pd1.x, linear->pd2.x);
  3575.                 y1 = -HUGE_VAL;
  3576.                 y2 = HUGE_VAL;
  3577.             } else {
  3578.                 goto  UNBOUNDED;
  3579.             }
  3580.         }
  3581.         break;
  3582.  
  3583.     case CAIRO_PATTERN_TYPE_MESH:
  3584.         {
  3585.             const cairo_mesh_pattern_t *mesh =
  3586.                 (const cairo_mesh_pattern_t *) pattern;
  3587.             double padx, pady;
  3588.             cairo_bool_t is_valid;
  3589.  
  3590.             is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2);
  3591.             if (!is_valid)
  3592.                 goto EMPTY;
  3593.  
  3594.             padx = pady = 1.;
  3595.             cairo_matrix_transform_distance (&pattern->matrix, &padx, &pady);
  3596.             padx = fabs (padx);
  3597.             pady = fabs (pady);
  3598.  
  3599.             x1 -= padx;
  3600.             y1 -= pady;
  3601.             x2 += padx;
  3602.             y2 += pady;
  3603.         }
  3604.         break;
  3605.  
  3606.     default:
  3607.         ASSERT_NOT_REACHED;
  3608.     }
  3609.  
  3610.     if (_cairo_matrix_is_translation (&pattern->matrix)) {
  3611.         x1 -= pattern->matrix.x0; x2 -= pattern->matrix.x0;
  3612.         y1 -= pattern->matrix.y0; y2 -= pattern->matrix.y0;
  3613.     } else {
  3614.         cairo_matrix_t imatrix;
  3615.  
  3616.         imatrix = pattern->matrix;
  3617.         status = cairo_matrix_invert (&imatrix);
  3618.         /* cairo_pattern_set_matrix ensures the matrix is invertible */
  3619.         assert (status == CAIRO_STATUS_SUCCESS);
  3620.  
  3621.         _cairo_matrix_transform_bounding_box (&imatrix,
  3622.                                               &x1, &y1, &x2, &y2,
  3623.                                               NULL);
  3624.     }
  3625.  
  3626.     x1 = floor (x1);
  3627.     if (x1 < CAIRO_RECT_INT_MIN)
  3628.         x1 = CAIRO_RECT_INT_MIN;
  3629.     y1 = floor (y1);
  3630.     if (y1 < CAIRO_RECT_INT_MIN)
  3631.         y1 = CAIRO_RECT_INT_MIN;
  3632.  
  3633.     x2 = ceil (x2);
  3634.     if (x2 > CAIRO_RECT_INT_MAX)
  3635.         x2 = CAIRO_RECT_INT_MAX;
  3636.     y2 = ceil (y2);
  3637.     if (y2 > CAIRO_RECT_INT_MAX)
  3638.         y2 = CAIRO_RECT_INT_MAX;
  3639.  
  3640.     extents->x = x1; extents->width  = x2 - x1;
  3641.     extents->y = y1; extents->height = y2 - y1;
  3642.     return;
  3643.  
  3644.   UNBOUNDED:
  3645.     /* unbounded patterns -> 'infinite' extents */
  3646.     _cairo_unbounded_rectangle_init (extents);
  3647.     return;
  3648.  
  3649.   EMPTY:
  3650.     extents->x = extents->y = 0;
  3651.     extents->width = extents->height = 0;
  3652.     return;
  3653. }
  3654.  
  3655. /**
  3656.  * _cairo_pattern_get_ink_extents:
  3657.  *
  3658.  * Return the "target-space" inked extents of @pattern in @extents.
  3659.  **/
  3660. cairo_int_status_t
  3661. _cairo_pattern_get_ink_extents (const cairo_pattern_t         *pattern,
  3662.                                 cairo_rectangle_int_t         *extents)
  3663. {
  3664.     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
  3665.         pattern->extend == CAIRO_EXTEND_NONE)
  3666.     {
  3667.         const cairo_surface_pattern_t *surface_pattern =
  3668.             (const cairo_surface_pattern_t *) pattern;
  3669.         cairo_surface_t *surface = surface_pattern->surface;
  3670.  
  3671.         surface = _cairo_surface_get_source (surface, NULL);
  3672.         if (_cairo_surface_is_recording (surface)) {
  3673.             cairo_matrix_t imatrix;
  3674.             cairo_box_t box;
  3675.             cairo_status_t status;
  3676.  
  3677.             imatrix = pattern->matrix;
  3678.             status = cairo_matrix_invert (&imatrix);
  3679.             /* cairo_pattern_set_matrix ensures the matrix is invertible */
  3680.             assert (status == CAIRO_STATUS_SUCCESS);
  3681.  
  3682.             status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)surface,
  3683.                                                    &box, &imatrix);
  3684.             if (unlikely (status))
  3685.                 return status;
  3686.  
  3687.             _cairo_box_round_to_rectangle (&box, extents);
  3688.             return CAIRO_STATUS_SUCCESS;
  3689.         }
  3690.     }
  3691.  
  3692.     _cairo_pattern_get_extents (pattern, extents);
  3693.     return CAIRO_STATUS_SUCCESS;
  3694. }
  3695.  
  3696. static unsigned long
  3697. _cairo_solid_pattern_hash (unsigned long hash,
  3698.                            const cairo_solid_pattern_t *solid)
  3699. {
  3700.     hash = _cairo_hash_bytes (hash, &solid->color, sizeof (solid->color));
  3701.  
  3702.     return hash;
  3703. }
  3704.  
  3705. static unsigned long
  3706. _cairo_gradient_color_stops_hash (unsigned long hash,
  3707.                                   const cairo_gradient_pattern_t *gradient)
  3708. {
  3709.     unsigned int n;
  3710.  
  3711.     hash = _cairo_hash_bytes (hash,
  3712.                               &gradient->n_stops,
  3713.                               sizeof (gradient->n_stops));
  3714.  
  3715.     for (n = 0; n < gradient->n_stops; n++) {
  3716.         hash = _cairo_hash_bytes (hash,
  3717.                                   &gradient->stops[n].offset,
  3718.                                   sizeof (double));
  3719.         hash = _cairo_hash_bytes (hash,
  3720.                                   &gradient->stops[n].color,
  3721.                                   sizeof (cairo_color_stop_t));
  3722.     }
  3723.  
  3724.     return hash;
  3725. }
  3726.  
  3727. unsigned long
  3728. _cairo_linear_pattern_hash (unsigned long hash,
  3729.                             const cairo_linear_pattern_t *linear)
  3730. {
  3731.     hash = _cairo_hash_bytes (hash, &linear->pd1, sizeof (linear->pd1));
  3732.     hash = _cairo_hash_bytes (hash, &linear->pd2, sizeof (linear->pd2));
  3733.  
  3734.     return _cairo_gradient_color_stops_hash (hash, &linear->base);
  3735. }
  3736.  
  3737. unsigned long
  3738. _cairo_radial_pattern_hash (unsigned long hash,
  3739.                             const cairo_radial_pattern_t *radial)
  3740. {
  3741.     hash = _cairo_hash_bytes (hash, &radial->cd1.center, sizeof (radial->cd1.center));
  3742.     hash = _cairo_hash_bytes (hash, &radial->cd1.radius, sizeof (radial->cd1.radius));
  3743.     hash = _cairo_hash_bytes (hash, &radial->cd2.center, sizeof (radial->cd2.center));
  3744.     hash = _cairo_hash_bytes (hash, &radial->cd2.radius, sizeof (radial->cd2.radius));
  3745.  
  3746.     return _cairo_gradient_color_stops_hash (hash, &radial->base);
  3747. }
  3748.  
  3749. static unsigned long
  3750. _cairo_mesh_pattern_hash (unsigned long hash, const cairo_mesh_pattern_t *mesh)
  3751. {
  3752.     const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0);
  3753.     unsigned int i, n = _cairo_array_num_elements (&mesh->patches);
  3754.  
  3755.     for (i = 0; i < n; i++)
  3756.        hash = _cairo_hash_bytes (hash, patch + i, sizeof (cairo_mesh_patch_t));
  3757.  
  3758.     return hash;
  3759. }
  3760.  
  3761. static unsigned long
  3762. _cairo_surface_pattern_hash (unsigned long hash,
  3763.                              const cairo_surface_pattern_t *surface)
  3764. {
  3765.     hash ^= surface->surface->unique_id;
  3766.  
  3767.     return hash;
  3768. }
  3769.  
  3770. static unsigned long
  3771. _cairo_raster_source_pattern_hash (unsigned long hash,
  3772.                                    const cairo_raster_source_pattern_t *raster)
  3773. {
  3774.     hash ^= (uintptr_t)raster->user_data;
  3775.  
  3776.     return hash;
  3777. }
  3778.  
  3779. unsigned long
  3780. _cairo_pattern_hash (const cairo_pattern_t *pattern)
  3781. {
  3782.     unsigned long hash = _CAIRO_HASH_INIT_VALUE;
  3783.  
  3784.     if (pattern->status)
  3785.         return 0;
  3786.  
  3787.     hash = _cairo_hash_bytes (hash, &pattern->type, sizeof (pattern->type));
  3788.     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
  3789.         hash = _cairo_hash_bytes (hash,
  3790.                                   &pattern->matrix, sizeof (pattern->matrix));
  3791.         hash = _cairo_hash_bytes (hash,
  3792.                                   &pattern->filter, sizeof (pattern->filter));
  3793.         hash = _cairo_hash_bytes (hash,
  3794.                                   &pattern->extend, sizeof (pattern->extend));
  3795.         hash = _cairo_hash_bytes (hash,
  3796.                                   &pattern->has_component_alpha,
  3797.                                   sizeof (pattern->has_component_alpha));
  3798.     }
  3799.  
  3800.     switch (pattern->type) {
  3801.     case CAIRO_PATTERN_TYPE_SOLID:
  3802.         return _cairo_solid_pattern_hash (hash, (cairo_solid_pattern_t *) pattern);
  3803.     case CAIRO_PATTERN_TYPE_LINEAR:
  3804.         return _cairo_linear_pattern_hash (hash, (cairo_linear_pattern_t *) pattern);
  3805.     case CAIRO_PATTERN_TYPE_RADIAL:
  3806.         return _cairo_radial_pattern_hash (hash, (cairo_radial_pattern_t *) pattern);
  3807.     case CAIRO_PATTERN_TYPE_MESH:
  3808.         return _cairo_mesh_pattern_hash (hash, (cairo_mesh_pattern_t *) pattern);
  3809.     case CAIRO_PATTERN_TYPE_SURFACE:
  3810.         return _cairo_surface_pattern_hash (hash, (cairo_surface_pattern_t *) pattern);
  3811.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  3812.         return _cairo_raster_source_pattern_hash (hash, (cairo_raster_source_pattern_t *) pattern);
  3813.     default:
  3814.         ASSERT_NOT_REACHED;
  3815.         return FALSE;
  3816.     }
  3817. }
  3818.  
  3819. static cairo_bool_t
  3820. _cairo_solid_pattern_equal (const cairo_solid_pattern_t *a,
  3821.                             const cairo_solid_pattern_t *b)
  3822. {
  3823.     return _cairo_color_equal (&a->color, &b->color);
  3824. }
  3825.  
  3826. static cairo_bool_t
  3827. _cairo_gradient_color_stops_equal (const cairo_gradient_pattern_t *a,
  3828.                                    const cairo_gradient_pattern_t *b)
  3829. {
  3830.     unsigned int n;
  3831.  
  3832.     if (a->n_stops != b->n_stops)
  3833.         return FALSE;
  3834.  
  3835.     for (n = 0; n < a->n_stops; n++) {
  3836.         if (a->stops[n].offset != b->stops[n].offset)
  3837.             return FALSE;
  3838.         if (! _cairo_color_stop_equal (&a->stops[n].color, &b->stops[n].color))
  3839.             return FALSE;
  3840.     }
  3841.  
  3842.     return TRUE;
  3843. }
  3844.  
  3845. cairo_bool_t
  3846. _cairo_linear_pattern_equal (const cairo_linear_pattern_t *a,
  3847.                              const cairo_linear_pattern_t *b)
  3848. {
  3849.     if (a->pd1.x != b->pd1.x)
  3850.         return FALSE;
  3851.  
  3852.     if (a->pd1.y != b->pd1.y)
  3853.         return FALSE;
  3854.  
  3855.     if (a->pd2.x != b->pd2.x)
  3856.         return FALSE;
  3857.  
  3858.     if (a->pd2.y != b->pd2.y)
  3859.         return FALSE;
  3860.  
  3861.     return _cairo_gradient_color_stops_equal (&a->base, &b->base);
  3862. }
  3863.  
  3864. cairo_bool_t
  3865. _cairo_radial_pattern_equal (const cairo_radial_pattern_t *a,
  3866.                              const cairo_radial_pattern_t *b)
  3867. {
  3868.     if (a->cd1.center.x != b->cd1.center.x)
  3869.         return FALSE;
  3870.  
  3871.     if (a->cd1.center.y != b->cd1.center.y)
  3872.         return FALSE;
  3873.  
  3874.     if (a->cd1.radius != b->cd1.radius)
  3875.         return FALSE;
  3876.  
  3877.     if (a->cd2.center.x != b->cd2.center.x)
  3878.         return FALSE;
  3879.  
  3880.     if (a->cd2.center.y != b->cd2.center.y)
  3881.         return FALSE;
  3882.  
  3883.     if (a->cd2.radius != b->cd2.radius)
  3884.         return FALSE;
  3885.  
  3886.     return _cairo_gradient_color_stops_equal (&a->base, &b->base);
  3887. }
  3888.  
  3889. static cairo_bool_t
  3890. _cairo_mesh_pattern_equal (const cairo_mesh_pattern_t *a,
  3891.                            const cairo_mesh_pattern_t *b)
  3892. {
  3893.     const cairo_mesh_patch_t *patch_a, *patch_b;
  3894.     unsigned int i, num_patches_a, num_patches_b;
  3895.  
  3896.     num_patches_a = _cairo_array_num_elements (&a->patches);
  3897.     num_patches_b = _cairo_array_num_elements (&b->patches);
  3898.  
  3899.     if (num_patches_a != num_patches_b)
  3900.         return FALSE;
  3901.  
  3902.     for (i = 0; i < num_patches_a; i++) {
  3903.         patch_a = _cairo_array_index_const (&a->patches, i);
  3904.         patch_b = _cairo_array_index_const (&a->patches, i);
  3905.         if (memcmp (patch_a, patch_b, sizeof(cairo_mesh_patch_t)) != 0)
  3906.             return FALSE;
  3907.     }
  3908.  
  3909.     return TRUE;
  3910. }
  3911.  
  3912. static cairo_bool_t
  3913. _cairo_surface_pattern_equal (const cairo_surface_pattern_t *a,
  3914.                               const cairo_surface_pattern_t *b)
  3915. {
  3916.     return a->surface->unique_id == b->surface->unique_id;
  3917. }
  3918.  
  3919. static cairo_bool_t
  3920. _cairo_raster_source_pattern_equal (const cairo_raster_source_pattern_t *a,
  3921.                                     const cairo_raster_source_pattern_t *b)
  3922. {
  3923.     return a->user_data == b->user_data;
  3924. }
  3925.  
  3926. cairo_bool_t
  3927. _cairo_pattern_equal (const cairo_pattern_t *a, const cairo_pattern_t *b)
  3928. {
  3929.     if (a->status || b->status)
  3930.         return FALSE;
  3931.  
  3932.     if (a == b)
  3933.         return TRUE;
  3934.  
  3935.     if (a->type != b->type)
  3936.         return FALSE;
  3937.  
  3938.     if (a->has_component_alpha != b->has_component_alpha)
  3939.         return FALSE;
  3940.  
  3941.     if (a->type != CAIRO_PATTERN_TYPE_SOLID) {
  3942.         if (memcmp (&a->matrix, &b->matrix, sizeof (cairo_matrix_t)))
  3943.             return FALSE;
  3944.  
  3945.         if (a->filter != b->filter)
  3946.             return FALSE;
  3947.  
  3948.         if (a->extend != b->extend)
  3949.             return FALSE;
  3950.     }
  3951.  
  3952.     switch (a->type) {
  3953.     case CAIRO_PATTERN_TYPE_SOLID:
  3954.         return _cairo_solid_pattern_equal ((cairo_solid_pattern_t *) a,
  3955.                                            (cairo_solid_pattern_t *) b);
  3956.     case CAIRO_PATTERN_TYPE_LINEAR:
  3957.         return _cairo_linear_pattern_equal ((cairo_linear_pattern_t *) a,
  3958.                                             (cairo_linear_pattern_t *) b);
  3959.     case CAIRO_PATTERN_TYPE_RADIAL:
  3960.         return _cairo_radial_pattern_equal ((cairo_radial_pattern_t *) a,
  3961.                                             (cairo_radial_pattern_t *) b);
  3962.     case CAIRO_PATTERN_TYPE_MESH:
  3963.         return _cairo_mesh_pattern_equal ((cairo_mesh_pattern_t *) a,
  3964.                                           (cairo_mesh_pattern_t *) b);
  3965.     case CAIRO_PATTERN_TYPE_SURFACE:
  3966.         return _cairo_surface_pattern_equal ((cairo_surface_pattern_t *) a,
  3967.                                              (cairo_surface_pattern_t *) b);
  3968.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  3969.         return _cairo_raster_source_pattern_equal ((cairo_raster_source_pattern_t *) a,
  3970.                                                    (cairo_raster_source_pattern_t *) b);
  3971.     default:
  3972.         ASSERT_NOT_REACHED;
  3973.         return FALSE;
  3974.     }
  3975. }
  3976.  
  3977. /**
  3978.  * cairo_pattern_get_rgba:
  3979.  * @pattern: a #cairo_pattern_t
  3980.  * @red: return value for red component of color, or %NULL
  3981.  * @green: return value for green component of color, or %NULL
  3982.  * @blue: return value for blue component of color, or %NULL
  3983.  * @alpha: return value for alpha component of color, or %NULL
  3984.  *
  3985.  * Gets the solid color for a solid color pattern.
  3986.  *
  3987.  * Return value: %CAIRO_STATUS_SUCCESS, or
  3988.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a solid
  3989.  * color pattern.
  3990.  *
  3991.  * Since: 1.4
  3992.  **/
  3993. cairo_status_t
  3994. cairo_pattern_get_rgba (cairo_pattern_t *pattern,
  3995.                         double *red, double *green,
  3996.                         double *blue, double *alpha)
  3997. {
  3998.     cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern;
  3999.     double r0, g0, b0, a0;
  4000.  
  4001.     if (pattern->status)
  4002.         return pattern->status;
  4003.  
  4004.     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
  4005.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4006.  
  4007.     _cairo_color_get_rgba (&solid->color, &r0, &g0, &b0, &a0);
  4008.  
  4009.     if (red)
  4010.         *red = r0;
  4011.     if (green)
  4012.         *green = g0;
  4013.     if (blue)
  4014.         *blue = b0;
  4015.     if (alpha)
  4016.         *alpha = a0;
  4017.  
  4018.     return CAIRO_STATUS_SUCCESS;
  4019. }
  4020.  
  4021. /**
  4022.  * cairo_pattern_get_surface:
  4023.  * @pattern: a #cairo_pattern_t
  4024.  * @surface: return value for surface of pattern, or %NULL
  4025.  *
  4026.  * Gets the surface of a surface pattern.  The reference returned in
  4027.  * @surface is owned by the pattern; the caller should call
  4028.  * cairo_surface_reference() if the surface is to be retained.
  4029.  *
  4030.  * Return value: %CAIRO_STATUS_SUCCESS, or
  4031.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a surface
  4032.  * pattern.
  4033.  *
  4034.  * Since: 1.4
  4035.  **/
  4036. cairo_status_t
  4037. cairo_pattern_get_surface (cairo_pattern_t *pattern,
  4038.                            cairo_surface_t **surface)
  4039. {
  4040.     cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern;
  4041.  
  4042.     if (pattern->status)
  4043.         return pattern->status;
  4044.  
  4045.     if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
  4046.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4047.  
  4048.     if (surface)
  4049.         *surface = spat->surface;
  4050.  
  4051.     return CAIRO_STATUS_SUCCESS;
  4052. }
  4053.  
  4054. /**
  4055.  * cairo_pattern_get_color_stop_rgba:
  4056.  * @pattern: a #cairo_pattern_t
  4057.  * @index: index of the stop to return data for
  4058.  * @offset: return value for the offset of the stop, or %NULL
  4059.  * @red: return value for red component of color, or %NULL
  4060.  * @green: return value for green component of color, or %NULL
  4061.  * @blue: return value for blue component of color, or %NULL
  4062.  * @alpha: return value for alpha component of color, or %NULL
  4063.  *
  4064.  * Gets the color and offset information at the given @index for a
  4065.  * gradient pattern.  Values of @index are 0 to 1 less than the number
  4066.  * returned by cairo_pattern_get_color_stop_count().
  4067.  *
  4068.  * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX
  4069.  * if @index is not valid for the given pattern.  If the pattern is
  4070.  * not a gradient pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is
  4071.  * returned.
  4072.  *
  4073.  * Since: 1.4
  4074.  **/
  4075. cairo_status_t
  4076. cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
  4077.                                    int index, double *offset,
  4078.                                    double *red, double *green,
  4079.                                    double *blue, double *alpha)
  4080. {
  4081.     cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern;
  4082.  
  4083.     if (pattern->status)
  4084.         return pattern->status;
  4085.  
  4086.     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
  4087.         pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
  4088.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4089.  
  4090.     if (index < 0 || (unsigned int) index >= gradient->n_stops)
  4091.         return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
  4092.  
  4093.     if (offset)
  4094.         *offset = gradient->stops[index].offset;
  4095.     if (red)
  4096.         *red = gradient->stops[index].color.red;
  4097.     if (green)
  4098.         *green = gradient->stops[index].color.green;
  4099.     if (blue)
  4100.         *blue = gradient->stops[index].color.blue;
  4101.     if (alpha)
  4102.         *alpha = gradient->stops[index].color.alpha;
  4103.  
  4104.     return CAIRO_STATUS_SUCCESS;
  4105. }
  4106.  
  4107. /**
  4108.  * cairo_pattern_get_color_stop_count:
  4109.  * @pattern: a #cairo_pattern_t
  4110.  * @count: return value for the number of color stops, or %NULL
  4111.  *
  4112.  * Gets the number of color stops specified in the given gradient
  4113.  * pattern.
  4114.  *
  4115.  * Return value: %CAIRO_STATUS_SUCCESS, or
  4116.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a gradient
  4117.  * pattern.
  4118.  *
  4119.  * Since: 1.4
  4120.  **/
  4121. cairo_status_t
  4122. cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
  4123.                                     int *count)
  4124. {
  4125.     cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern;
  4126.  
  4127.     if (pattern->status)
  4128.         return pattern->status;
  4129.  
  4130.     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
  4131.         pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
  4132.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4133.  
  4134.     if (count)
  4135.         *count = gradient->n_stops;
  4136.  
  4137.     return CAIRO_STATUS_SUCCESS;
  4138. }
  4139.  
  4140. /**
  4141.  * cairo_pattern_get_linear_points:
  4142.  * @pattern: a #cairo_pattern_t
  4143.  * @x0: return value for the x coordinate of the first point, or %NULL
  4144.  * @y0: return value for the y coordinate of the first point, or %NULL
  4145.  * @x1: return value for the x coordinate of the second point, or %NULL
  4146.  * @y1: return value for the y coordinate of the second point, or %NULL
  4147.  *
  4148.  * Gets the gradient endpoints for a linear gradient.
  4149.  *
  4150.  * Return value: %CAIRO_STATUS_SUCCESS, or
  4151.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a linear
  4152.  * gradient pattern.
  4153.  *
  4154.  * Since: 1.4
  4155.  **/
  4156. cairo_status_t
  4157. cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
  4158.                                  double *x0, double *y0,
  4159.                                  double *x1, double *y1)
  4160. {
  4161.     cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern;
  4162.  
  4163.     if (pattern->status)
  4164.         return pattern->status;
  4165.  
  4166.     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR)
  4167.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4168.  
  4169.     if (x0)
  4170.         *x0 = linear->pd1.x;
  4171.     if (y0)
  4172.         *y0 = linear->pd1.y;
  4173.     if (x1)
  4174.         *x1 = linear->pd2.x;
  4175.     if (y1)
  4176.         *y1 = linear->pd2.y;
  4177.  
  4178.     return CAIRO_STATUS_SUCCESS;
  4179. }
  4180.  
  4181. /**
  4182.  * cairo_pattern_get_radial_circles:
  4183.  * @pattern: a #cairo_pattern_t
  4184.  * @x0: return value for the x coordinate of the center of the first circle, or %NULL
  4185.  * @y0: return value for the y coordinate of the center of the first circle, or %NULL
  4186.  * @r0: return value for the radius of the first circle, or %NULL
  4187.  * @x1: return value for the x coordinate of the center of the second circle, or %NULL
  4188.  * @y1: return value for the y coordinate of the center of the second circle, or %NULL
  4189.  * @r1: return value for the radius of the second circle, or %NULL
  4190.  *
  4191.  * Gets the gradient endpoint circles for a radial gradient, each
  4192.  * specified as a center coordinate and a radius.
  4193.  *
  4194.  * Return value: %CAIRO_STATUS_SUCCESS, or
  4195.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a radial
  4196.  * gradient pattern.
  4197.  *
  4198.  * Since: 1.4
  4199.  **/
  4200. cairo_status_t
  4201. cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
  4202.                                   double *x0, double *y0, double *r0,
  4203.                                   double *x1, double *y1, double *r1)
  4204. {
  4205.     cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern;
  4206.  
  4207.     if (pattern->status)
  4208.         return pattern->status;
  4209.  
  4210.     if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
  4211.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4212.  
  4213.     if (x0)
  4214.         *x0 = radial->cd1.center.x;
  4215.     if (y0)
  4216.         *y0 = radial->cd1.center.y;
  4217.     if (r0)
  4218.         *r0 = radial->cd1.radius;
  4219.     if (x1)
  4220.         *x1 = radial->cd2.center.x;
  4221.     if (y1)
  4222.         *y1 = radial->cd2.center.y;
  4223.     if (r1)
  4224.         *r1 = radial->cd2.radius;
  4225.  
  4226.     return CAIRO_STATUS_SUCCESS;
  4227. }
  4228.  
  4229. /**
  4230.  * cairo_mesh_pattern_get_patch_count:
  4231.  * @pattern: a #cairo_pattern_t
  4232.  * @count: return value for the number patches, or %NULL
  4233.  *
  4234.  * Gets the number of patches specified in the given mesh pattern.
  4235.  *
  4236.  * The number only includes patches which have been finished by
  4237.  * calling cairo_mesh_pattern_end_patch(). For example it will be 0
  4238.  * during the definition of the first patch.
  4239.  *
  4240.  * Return value: %CAIRO_STATUS_SUCCESS, or
  4241.  * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a mesh
  4242.  * pattern.
  4243.  *
  4244.  * Since: 1.12
  4245.  **/
  4246. cairo_status_t
  4247. cairo_mesh_pattern_get_patch_count (cairo_pattern_t *pattern,
  4248.                                     unsigned int *count)
  4249. {
  4250.     cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern;
  4251.  
  4252.     if (unlikely (pattern->status))
  4253.         return pattern->status;
  4254.  
  4255.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH))
  4256.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4257.  
  4258.     if (count) {
  4259.         *count = _cairo_array_num_elements (&mesh->patches);
  4260.         if (mesh->current_patch)
  4261.             *count -= 1;
  4262.     }
  4263.  
  4264.     return CAIRO_STATUS_SUCCESS;
  4265. }
  4266. slim_hidden_def (cairo_mesh_pattern_get_patch_count);
  4267.  
  4268. /**
  4269.  * cairo_mesh_pattern_get_path:
  4270.  * @pattern: a #cairo_pattern_t
  4271.  * @patch_num: the patch number to return data for
  4272.  *
  4273.  * Gets path defining the patch @patch_num for a mesh
  4274.  * pattern.
  4275.  *
  4276.  * @patch_num can range 0 to 1 less than the number returned by
  4277.  * cairo_mesh_pattern_get_patch_count().
  4278.  *
  4279.  * Return value: the path defining the patch, or a path with status
  4280.  * %CAIRO_STATUS_INVALID_INDEX if @patch_num or @point_num is not
  4281.  * valid for @pattern. If @pattern is not a mesh pattern, a path with
  4282.  * status %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is returned.
  4283.  *
  4284.  * Since: 1.12
  4285.  **/
  4286. cairo_path_t *
  4287. cairo_mesh_pattern_get_path (cairo_pattern_t *pattern,
  4288.                              unsigned int patch_num)
  4289. {
  4290.     cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern;
  4291.     const cairo_mesh_patch_t *patch;
  4292.     cairo_path_t *path;
  4293.     cairo_path_data_t *data;
  4294.     unsigned int patch_count;
  4295.     int l, current_point;
  4296.  
  4297.     if (unlikely (pattern->status))
  4298.         return _cairo_path_create_in_error (pattern->status);
  4299.  
  4300.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH))
  4301.         return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH));
  4302.  
  4303.     patch_count = _cairo_array_num_elements (&mesh->patches);
  4304.     if (mesh->current_patch)
  4305.         patch_count--;
  4306.  
  4307.     if (unlikely (patch_num >= patch_count))
  4308.         return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_INDEX));
  4309.  
  4310.     patch = _cairo_array_index_const (&mesh->patches, patch_num);
  4311.  
  4312.     path = malloc (sizeof (cairo_path_t));
  4313.     if (path == NULL)
  4314.         return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
  4315.  
  4316.     path->num_data = 18;
  4317.     path->data = _cairo_malloc_ab (path->num_data,
  4318.                                    sizeof (cairo_path_data_t));
  4319.     if (path->data == NULL) {
  4320.         free (path);
  4321.         return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
  4322.     }
  4323.  
  4324.     data = path->data;
  4325.     data[0].header.type = CAIRO_PATH_MOVE_TO;
  4326.     data[0].header.length = 2;
  4327.     data[1].point.x = patch->points[0][0].x;
  4328.     data[1].point.y = patch->points[0][0].y;
  4329.     data += data[0].header.length;
  4330.  
  4331.     current_point = 0;
  4332.  
  4333.     for (l = 0; l < 4; l++) {
  4334.         int i, j, k;
  4335.  
  4336.         data[0].header.type = CAIRO_PATH_CURVE_TO;
  4337.         data[0].header.length = 4;
  4338.  
  4339.         for (k = 1; k < 4; k++) {
  4340.             current_point = (current_point + 1) % 12;
  4341.             i = mesh_path_point_i[current_point];
  4342.             j = mesh_path_point_j[current_point];
  4343.             data[k].point.x = patch->points[i][j].x;
  4344.             data[k].point.y = patch->points[i][j].y;
  4345.         }
  4346.  
  4347.         data += data[0].header.length;
  4348.     }
  4349.  
  4350.     path->status = CAIRO_STATUS_SUCCESS;
  4351.  
  4352.     return path;
  4353. }
  4354. slim_hidden_def (cairo_mesh_pattern_get_path);
  4355.  
  4356. /**
  4357.  * cairo_mesh_pattern_get_corner_color_rgba:
  4358.  * @pattern: a #cairo_pattern_t
  4359.  * @patch_num: the patch number to return data for
  4360.  * @corner_num: the corner number to return data for
  4361.  * @red: return value for red component of color, or %NULL
  4362.  * @green: return value for green component of color, or %NULL
  4363.  * @blue: return value for blue component of color, or %NULL
  4364.  * @alpha: return value for alpha component of color, or %NULL
  4365.  *
  4366.  * Gets the color information in corner @corner_num of patch
  4367.  * @patch_num for a mesh pattern.
  4368.  *
  4369.  * @patch_num can range 0 to 1 less than the number returned by
  4370.  * cairo_mesh_pattern_get_patch_count().
  4371.  *
  4372.  * Valid values for @corner_num are from 0 to 3 and identify the
  4373.  * corners as explained in cairo_pattern_create_mesh().
  4374.  *
  4375.  * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX
  4376.  * if @patch_num or @corner_num is not valid for @pattern. If
  4377.  * @pattern is not a mesh pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH
  4378.  * is returned.
  4379.  *
  4380.  * Since: 1.12
  4381.  **/
  4382. cairo_status_t
  4383. cairo_mesh_pattern_get_corner_color_rgba (cairo_pattern_t *pattern,
  4384.                                           unsigned int patch_num,
  4385.                                           unsigned int corner_num,
  4386.                                           double *red, double *green,
  4387.                                           double *blue, double *alpha)
  4388. {
  4389.     cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern;
  4390.     unsigned int patch_count;
  4391.     const cairo_mesh_patch_t *patch;
  4392.  
  4393.     if (unlikely (pattern->status))
  4394.         return pattern->status;
  4395.  
  4396.     if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH))
  4397.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4398.  
  4399.     if (unlikely (corner_num > 3))
  4400.         return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
  4401.  
  4402.     patch_count = _cairo_array_num_elements (&mesh->patches);
  4403.     if (mesh->current_patch)
  4404.         patch_count--;
  4405.  
  4406.     if (unlikely (patch_num >= patch_count))
  4407.         return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
  4408.  
  4409.     patch = _cairo_array_index_const (&mesh->patches, patch_num);
  4410.  
  4411.     if (red)
  4412.         *red = patch->colors[corner_num].red;
  4413.     if (green)
  4414.         *green = patch->colors[corner_num].green;
  4415.     if (blue)
  4416.         *blue = patch->colors[corner_num].blue;
  4417.     if (alpha)
  4418.         *alpha = patch->colors[corner_num].alpha;
  4419.  
  4420.     return CAIRO_STATUS_SUCCESS;
  4421. }
  4422. slim_hidden_def (cairo_mesh_pattern_get_corner_color_rgba);
  4423.  
  4424. /**
  4425.  * cairo_mesh_pattern_get_control_point:
  4426.  * @pattern: a #cairo_pattern_t
  4427.  * @patch_num: the patch number to return data for
  4428.  * @point_num: the control point number to return data for
  4429.  * @x: return value for the x coordinate of the control point, or %NULL
  4430.  * @y: return value for the y coordinate of the control point, or %NULL
  4431.  *
  4432.  * Gets the control point @point_num of patch @patch_num for a mesh
  4433.  * pattern.
  4434.  *
  4435.  * @patch_num can range 0 to 1 less than the number returned by
  4436.  * cairo_mesh_pattern_get_patch_count().
  4437.  *
  4438.  * Valid values for @point_num are from 0 to 3 and identify the
  4439.  * control points as explained in cairo_pattern_create_mesh().
  4440.  *
  4441.  * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX
  4442.  * if @patch_num or @point_num is not valid for @pattern. If @pattern
  4443.  * is not a mesh pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is
  4444.  * returned.
  4445.  *
  4446.  * Since: 1.12
  4447.  **/
  4448. cairo_status_t
  4449. cairo_mesh_pattern_get_control_point (cairo_pattern_t *pattern,
  4450.                                       unsigned int patch_num,
  4451.                                       unsigned int point_num,
  4452.                                       double *x, double *y)
  4453. {
  4454.     cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern;
  4455.     const cairo_mesh_patch_t *patch;
  4456.     unsigned int patch_count;
  4457.     int i, j;
  4458.  
  4459.     if (pattern->status)
  4460.         return pattern->status;
  4461.  
  4462.     if (pattern->type != CAIRO_PATTERN_TYPE_MESH)
  4463.         return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
  4464.  
  4465.     if (point_num > 3)
  4466.         return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
  4467.  
  4468.     patch_count = _cairo_array_num_elements (&mesh->patches);
  4469.     if (mesh->current_patch)
  4470.         patch_count--;
  4471.  
  4472.     if (unlikely (patch_num >= patch_count))
  4473.         return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
  4474.  
  4475.     patch = _cairo_array_index_const (&mesh->patches, patch_num);
  4476.  
  4477.     i = mesh_control_point_i[point_num];
  4478.     j = mesh_control_point_j[point_num];
  4479.  
  4480.     if (x)
  4481.         *x = patch->points[i][j].x;
  4482.     if (y)
  4483.         *y = patch->points[i][j].y;
  4484.  
  4485.     return CAIRO_STATUS_SUCCESS;
  4486. }
  4487. slim_hidden_def (cairo_mesh_pattern_get_control_point);
  4488.  
  4489. void
  4490. _cairo_pattern_reset_static_data (void)
  4491. {
  4492.     int i;
  4493.  
  4494.     for (i = 0; i < ARRAY_LENGTH (freed_pattern_pool); i++)
  4495.         _freed_pool_reset (&freed_pattern_pool[i]);
  4496. }
  4497.  
  4498. static void
  4499. _cairo_debug_print_surface_pattern (FILE *file,
  4500.                                     const cairo_surface_pattern_t *pattern)
  4501. {
  4502.     printf ("  surface type: %d\n", pattern->surface->type);
  4503. }
  4504.  
  4505. static void
  4506. _cairo_debug_print_raster_source_pattern (FILE *file,
  4507.                                           const cairo_raster_source_pattern_t *raster)
  4508. {
  4509.     printf ("  content: %x, size %dx%d\n", raster->content, raster->extents.width, raster->extents.height);
  4510. }
  4511.  
  4512. static void
  4513. _cairo_debug_print_linear_pattern (FILE *file,
  4514.                                     const cairo_linear_pattern_t *pattern)
  4515. {
  4516. }
  4517.  
  4518. static void
  4519. _cairo_debug_print_radial_pattern (FILE *file,
  4520.                                    const cairo_radial_pattern_t *pattern)
  4521. {
  4522. }
  4523.  
  4524. static void
  4525. _cairo_debug_print_mesh_pattern (FILE *file,
  4526.                                  const cairo_mesh_pattern_t *pattern)
  4527. {
  4528. }
  4529.  
  4530. void
  4531. _cairo_debug_print_pattern (FILE *file, const cairo_pattern_t *pattern)
  4532. {
  4533.     const char *s;
  4534.     switch (pattern->type) {
  4535.     case CAIRO_PATTERN_TYPE_SOLID: s = "solid"; break;
  4536.     case CAIRO_PATTERN_TYPE_SURFACE: s = "surface"; break;
  4537.     case CAIRO_PATTERN_TYPE_LINEAR: s = "linear"; break;
  4538.     case CAIRO_PATTERN_TYPE_RADIAL: s = "radial"; break;
  4539.     case CAIRO_PATTERN_TYPE_MESH: s = "mesh"; break;
  4540.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE: s = "raster"; break;
  4541.     default: s = "invalid"; ASSERT_NOT_REACHED; break;
  4542.     }
  4543.  
  4544.     fprintf (file, "pattern: %s\n", s);
  4545.     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
  4546.         return;
  4547.  
  4548.     switch (pattern->extend) {
  4549.     case CAIRO_EXTEND_NONE: s = "none"; break;
  4550.     case CAIRO_EXTEND_REPEAT: s = "repeat"; break;
  4551.     case CAIRO_EXTEND_REFLECT: s = "reflect"; break;
  4552.     case CAIRO_EXTEND_PAD: s = "pad"; break;
  4553.     default: s = "invalid"; ASSERT_NOT_REACHED; break;
  4554.     }
  4555.     fprintf (file, "  extend: %s\n", s);
  4556.  
  4557.     switch (pattern->filter) {
  4558.     case CAIRO_FILTER_FAST: s = "fast"; break;
  4559.     case CAIRO_FILTER_GOOD: s = "good"; break;
  4560.     case CAIRO_FILTER_BEST: s = "best"; break;
  4561.     case CAIRO_FILTER_NEAREST: s = "nearest"; break;
  4562.     case CAIRO_FILTER_BILINEAR: s = "bilinear"; break;
  4563.     case CAIRO_FILTER_GAUSSIAN: s = "guassian"; break;
  4564.     default: s = "invalid"; ASSERT_NOT_REACHED; break;
  4565.     }
  4566.     fprintf (file, "  filter: %s\n", s);
  4567.     fprintf (file, "  matrix: [%g %g %g %g %g %g]\n",
  4568.              pattern->matrix.xx, pattern->matrix.yx,
  4569.              pattern->matrix.xy, pattern->matrix.yy,
  4570.              pattern->matrix.x0, pattern->matrix.y0);
  4571.     switch (pattern->type) {
  4572.     default:
  4573.     case CAIRO_PATTERN_TYPE_SOLID:
  4574.         break;
  4575.     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
  4576.         _cairo_debug_print_raster_source_pattern (file, (cairo_raster_source_pattern_t *)pattern);
  4577.         break;
  4578.     case CAIRO_PATTERN_TYPE_SURFACE:
  4579.         _cairo_debug_print_surface_pattern (file, (cairo_surface_pattern_t *)pattern);
  4580.         break;
  4581.     case CAIRO_PATTERN_TYPE_LINEAR:
  4582.         _cairo_debug_print_linear_pattern (file, (cairo_linear_pattern_t *)pattern);
  4583.         break;
  4584.     case CAIRO_PATTERN_TYPE_RADIAL:
  4585.         _cairo_debug_print_radial_pattern (file, (cairo_radial_pattern_t *)pattern);
  4586.         break;
  4587.     case CAIRO_PATTERN_TYPE_MESH:
  4588.         _cairo_debug_print_mesh_pattern (file, (cairo_mesh_pattern_t *)pattern);
  4589.         break;
  4590.     }
  4591. }
  4592.