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