Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | For PHP Version 8 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 2015 Elizabeth M Smith |
6 : +----------------------------------------------------------------------+
7 : | http://www.opensource.org/licenses/mit-license.php MIT License |
8 : | Also available in LICENSE |
9 : +----------------------------------------------------------------------+
10 : | Authors: Elizabeth M Smith <auroraeosrose@gmail.com> |
11 : | Swen Zanon <swen.zanon@geoglis.de> |
12 : +----------------------------------------------------------------------+
13 : */
14 :
15 : #ifdef HAVE_CONFIG_H
16 : #include "config.h"
17 : #endif
18 :
19 : #include <cairo.h>
20 : #include <php.h>
21 : #include <zend_exceptions.h>
22 :
23 : #include "php_cairo.h"
24 : #include "php_cairo_internal.h"
25 : #include "pattern_arginfo.h"
26 :
27 : zend_class_entry *ce_cairo_pattern;
28 : zend_class_entry *ce_cairo_pattern_solid;
29 : zend_class_entry *ce_cairo_pattern_gradient;
30 : zend_class_entry *ce_cairo_pattern_gradient_linear;
31 : zend_class_entry *ce_cairo_pattern_gradient_radial;
32 : zend_class_entry *ce_cairo_pattern_surface;
33 : zend_class_entry *ce_cairo_pattern_mesh;
34 : zend_class_entry *ce_cairo_pattern_raster;
35 :
36 : zend_class_entry *ce_cairo_pattern_type;
37 : zend_class_entry *ce_cairo_extend;
38 : zend_class_entry *ce_cairo_filter;
39 : zend_class_entry *ce_cairo_dither;
40 :
41 : static zend_object_handlers cairo_pattern_object_handlers;
42 :
43 : static cairo_user_data_key_t matrix_key;
44 :
45 4 : void cairo_pattern_destroy_func (void *data)
46 : {
47 : Z_DELREF_P(data);
48 4 : efree(data);
49 4 : }
50 :
51 284 : cairo_pattern_object *cairo_pattern_fetch_object(zend_object *object)
52 : {
53 284 : return (cairo_pattern_object *) ((char*)(object) - XtOffsetOf(cairo_pattern_object, std));
54 : }
55 :
56 139 : static inline cairo_pattern_object *cairo_pattern_object_get(zval *zv)
57 : {
58 139 : cairo_pattern_object *object = Z_CAIRO_PATTERN_P(zv);
59 139 : if (object->pattern == NULL) {
60 3 : zend_throw_exception_ex(ce_cairo_exception, 0,
61 : "Internal pattern object missing in %s, you must call parent::__construct in extended classes.",
62 3 : ZSTR_VAL(Z_OBJCE_P(zv)->name));
63 3 : return NULL;
64 : }
65 136 : return object;
66 : }
67 :
68 :
69 : /* ----------------------------------------------------------------
70 : Cairo\Pattern C API
71 : ------------------------------------------------------------------*/
72 :
73 6 : zend_class_entry* php_cairo_get_pattern_ce(cairo_pattern_t *pattern)
74 : {
75 : zend_class_entry *type;
76 6 : if (pattern == NULL) {
77 0 : return ce_cairo_pattern;
78 : }
79 :
80 6 : switch(cairo_pattern_get_type(pattern)) {
81 4 : case CAIRO_PATTERN_TYPE_SOLID:
82 4 : type = ce_cairo_pattern_solid;
83 4 : break;
84 2 : case CAIRO_PATTERN_TYPE_SURFACE:
85 2 : type = ce_cairo_pattern_surface;
86 2 : break;
87 0 : case CAIRO_PATTERN_TYPE_LINEAR:
88 0 : type = ce_cairo_pattern_gradient_linear;
89 0 : break;
90 0 : case CAIRO_PATTERN_TYPE_RADIAL:
91 0 : type = ce_cairo_pattern_gradient_radial;
92 0 : break;
93 0 : case CAIRO_PATTERN_TYPE_MESH:
94 0 : type = ce_cairo_pattern_mesh;
95 0 : break;
96 0 : case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
97 0 : type = ce_cairo_pattern_raster;
98 0 : break;
99 0 : default:
100 0 : php_error(E_WARNING, "Unsupported Cairo Surface Type");
101 0 : return NULL;
102 : }
103 6 : return type;
104 : }
105 :
106 :
107 : /* ----------------------------------------------------------------
108 : Cairo\Pattern Class API
109 : ------------------------------------------------------------------ */
110 :
111 : /* {{{ proto void contruct()
112 : \Cairo\Pattern CANNOT be extended in userspace, this will throw an exception on use */
113 2 : PHP_METHOD(Cairo_Pattern, __construct)
114 : {
115 2 : ZEND_PARSE_PARAMETERS_NONE();
116 2 : zend_throw_exception(ce_cairo_exception, "Cairo\\Pattern cannot be constructed", 0);
117 : }
118 : /* }}} */
119 :
120 : /* {{{ proto \Cairo\Status \Cairo\Pattern::getStatus()
121 : Returns the current integer status of the CairoPattern */
122 5 : PHP_METHOD(Cairo_Pattern, getStatus)
123 : {
124 : cairo_pattern_object *pattern_object;
125 : zval status_case;
126 :
127 9 : ZEND_PARSE_PARAMETERS_NONE();
128 :
129 8 : pattern_object = cairo_pattern_object_get(getThis());
130 4 : if (!pattern_object) {
131 3 : RETURN_THROWS();
132 : }
133 :
134 1 : status_case = php_enum_from_cairo_c_enum(
135 : ce_cairo_status,
136 1 : cairo_pattern_status(pattern_object->pattern)
137 : );
138 :
139 1 : if (Z_TYPE(status_case) == IS_OBJECT) {
140 2 : RETURN_ZVAL(&status_case, 1, 1);
141 : }
142 : }
143 : /* }}} */
144 :
145 : /* {{{ proto void \Cairo\Pattern::getType()
146 : This function returns the Cairo\Pattern\Type of a pattern */
147 2 : PHP_METHOD(Cairo_Pattern, getType)
148 : {
149 : cairo_pattern_object *pattern_object;
150 : zval pattern_case;
151 :
152 3 : ZEND_PARSE_PARAMETERS_NONE();
153 :
154 2 : pattern_object = cairo_pattern_object_get(getThis());
155 1 : if (!pattern_object) {
156 0 : RETURN_THROWS();
157 : }
158 :
159 1 : pattern_case = php_enum_from_cairo_c_enum(
160 : ce_cairo_pattern_type,
161 1 : cairo_pattern_get_type(pattern_object->pattern)
162 : );
163 :
164 1 : if (Z_TYPE(pattern_case) == IS_OBJECT) {
165 2 : RETURN_ZVAL(&pattern_case, 1, 1);
166 : }
167 : }
168 :
169 : /* }}} */
170 :
171 : /* {{{ proto int \Cairo\Pattern::getExtend()
172 : Gets the current extend mode for a pattern */
173 6 : PHP_METHOD(Cairo_Pattern, getExtend)
174 : {
175 : cairo_pattern_object *pattern_object;
176 : zval extend_case;
177 :
178 10 : ZEND_PARSE_PARAMETERS_NONE();
179 :
180 8 : pattern_object = cairo_pattern_object_get(getThis());
181 4 : if (!pattern_object) {
182 0 : RETURN_THROWS();
183 : }
184 :
185 4 : extend_case = php_enum_from_cairo_c_enum(
186 : ce_cairo_extend,
187 4 : cairo_pattern_get_extend(pattern_object->pattern)
188 : );
189 :
190 4 : if (Z_TYPE(extend_case) == IS_OBJECT) {
191 8 : RETURN_ZVAL(&extend_case, 1, 1);
192 : }
193 : }
194 : /* }}} */
195 :
196 : /* {{{ proto void \Cairo\Pattern::setExtend(object)
197 : Sets the mode to be used for drawing outside the area of a pattern */
198 9 : PHP_METHOD(Cairo_Pattern, setExtend)
199 : {
200 : cairo_pattern_object *pattern_object;
201 : zval *extend_case;
202 :
203 9 : ZEND_PARSE_PARAMETERS_START(1, 1)
204 10 : Z_PARAM_OBJECT_OF_CLASS(extend_case, ce_cairo_extend)
205 9 : ZEND_PARSE_PARAMETERS_END();
206 :
207 4 : pattern_object = cairo_pattern_object_get(getThis());
208 2 : if (!pattern_object) {
209 0 : RETURN_THROWS();
210 : }
211 :
212 2 : cairo_pattern_set_extend(
213 : pattern_object->pattern,
214 4 : Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(extend_case)))
215 : );
216 :
217 2 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
218 0 : RETURN_THROWS();
219 : }
220 : }
221 : /* }}} */
222 :
223 : /* {{{ proto int \Cairo\Pattern::getFilter()
224 : Gets the current filter mode for a pattern */
225 6 : PHP_METHOD(Cairo_Pattern, getFilter)
226 : {
227 : cairo_pattern_object *pattern_object;
228 : zval filter_case;
229 :
230 10 : ZEND_PARSE_PARAMETERS_NONE();
231 :
232 8 : pattern_object = cairo_pattern_object_get(getThis());
233 4 : if (!pattern_object) {
234 0 : RETURN_THROWS();
235 : }
236 :
237 4 : filter_case = php_enum_from_cairo_c_enum(
238 : ce_cairo_filter,
239 4 : cairo_pattern_get_filter(pattern_object->pattern)
240 : );
241 :
242 4 : if (Z_TYPE(filter_case) == IS_OBJECT) {
243 8 : RETURN_ZVAL(&filter_case, 1, 1);
244 : }
245 : }
246 : /* }}} */
247 :
248 : /* {{{ proto void \Cairo\Pattern::setFilter(Cairo\Filter filter)
249 : Sets the filter to be used for resizing when using this pattern */
250 10 : PHP_METHOD(Cairo_Pattern, setFilter)
251 : {
252 : cairo_pattern_object *pattern_object;
253 : zval *filter_case;
254 :
255 10 : ZEND_PARSE_PARAMETERS_START(1, 1)
256 12 : Z_PARAM_OBJECT_OF_CLASS(filter_case, ce_cairo_filter)
257 10 : ZEND_PARSE_PARAMETERS_END();
258 :
259 6 : pattern_object = cairo_pattern_object_get(getThis());
260 3 : if (!pattern_object) {
261 0 : RETURN_THROWS();
262 : }
263 :
264 3 : cairo_pattern_set_filter(
265 : pattern_object->pattern,
266 6 : Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(filter_case)))
267 : );
268 3 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
269 0 : RETURN_THROWS();
270 : }
271 : }
272 :
273 : /* }}} */
274 :
275 : /* {{{ proto object \Cairo\Pattern::getMatrix()
276 : Returns the pattern's transformation matrix */
277 5 : PHP_METHOD(Cairo_Pattern, getMatrix)
278 : {
279 : cairo_pattern_object *pattern_object;
280 5 : zval *matrix = NULL;
281 :
282 5 : ZEND_PARSE_PARAMETERS_NONE();
283 :
284 8 : pattern_object = cairo_pattern_object_get(getThis());
285 4 : if (!pattern_object) {
286 0 : RETURN_THROWS();
287 : }
288 :
289 4 : matrix = cairo_pattern_get_user_data(pattern_object->pattern, &matrix_key);
290 4 : if (matrix) {
291 6 : RETURN_COPY(matrix);
292 : }
293 :
294 1 : zval *matrix_store = emalloc(sizeof(zval));
295 : cairo_status_t status;
296 :
297 1 : object_init_ex(return_value, php_cairo_get_matrix_ce());
298 1 : cairo_pattern_get_matrix(pattern_object->pattern, cairo_matrix_object_get_matrix(return_value));
299 1 : ZVAL_COPY(matrix_store, return_value);
300 1 : status = cairo_pattern_set_user_data(
301 : pattern_object->pattern,
302 : &matrix_key,
303 : (void *)matrix_store, cairo_pattern_destroy_func
304 : );
305 :
306 1 : if (php_cairo_throw_exception(status)) {
307 0 : RETURN_THROWS();
308 : }
309 : }
310 : /* }}} */
311 :
312 : /* {{{ proto void \Cairo\Pattern::setMatrix(\Cairo\Matrix object)
313 : Sets the pattern's transformation matrix using the created matrix object.
314 : This matrix is a transformation from user space to pattern space. */
315 6 : PHP_METHOD(Cairo_Pattern, setMatrix)
316 : {
317 : zval *matrix_zval;
318 : cairo_pattern_object *pattern_object;
319 :
320 6 : ZEND_PARSE_PARAMETERS_START(1, 1)
321 8 : Z_PARAM_OBJECT_OF_CLASS(matrix_zval, ce_cairo_matrix)
322 6 : ZEND_PARSE_PARAMETERS_END();
323 :
324 6 : pattern_object = cairo_pattern_object_get(getThis());
325 3 : if (!pattern_object) {
326 0 : RETURN_THROWS();
327 : }
328 :
329 3 : cairo_pattern_set_matrix(pattern_object->pattern, cairo_matrix_object_get_matrix(matrix_zval));
330 :
331 3 : zval *matrix_store = emalloc(sizeof(zval));
332 : cairo_status_t status;
333 :
334 3 : ZVAL_COPY(matrix_store, matrix_zval);
335 :
336 3 : status = cairo_pattern_set_user_data(pattern_object->pattern, &matrix_key,
337 : (void *)matrix_store, cairo_pattern_destroy_func
338 : );
339 :
340 3 : if (php_cairo_throw_exception(status)) {
341 0 : RETURN_THROWS();
342 : }
343 : }
344 : /* }}} */
345 :
346 : #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 18, 0)
347 : /* {{{ proto object \Cairo\Pattern::getDither()
348 : Returns the pattern's dithering mode */
349 3 : PHP_METHOD(Cairo_Pattern, getDither)
350 : {
351 : cairo_pattern_object *pattern_object;
352 : zval dither_case;
353 :
354 5 : ZEND_PARSE_PARAMETERS_NONE();
355 :
356 4 : pattern_object = cairo_pattern_object_get(getThis());
357 2 : if (!pattern_object) {
358 0 : RETURN_THROWS();
359 : }
360 :
361 2 : dither_case = php_enum_from_cairo_c_enum(
362 : ce_cairo_dither,
363 2 : cairo_pattern_get_dither(pattern_object->pattern)
364 : );
365 :
366 2 : if (Z_TYPE(dither_case) == IS_OBJECT) {
367 4 : RETURN_ZVAL(&dither_case, 1, 1);
368 : }
369 : }
370 : /* }}} */
371 :
372 : /* {{{ proto void \Cairo\Pattern::setDither(Cairo\Dither dither)
373 : Sets the dithering mode to be used for this pattern */
374 4 : PHP_METHOD(Cairo_Pattern, setDither)
375 : {
376 : cairo_pattern_object *pattern_object;
377 : zval *dither_case;
378 :
379 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
380 4 : Z_PARAM_OBJECT_OF_CLASS(dither_case, ce_cairo_dither)
381 4 : ZEND_PARSE_PARAMETERS_END();
382 :
383 2 : pattern_object = cairo_pattern_object_get(getThis());
384 1 : if (!pattern_object) {
385 0 : RETURN_THROWS();
386 : }
387 :
388 1 : cairo_pattern_set_dither(
389 : pattern_object->pattern,
390 2 : Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(dither_case)))
391 : );
392 :
393 1 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
394 0 : RETURN_THROWS();
395 : }
396 : }
397 : /* }}} */
398 : #endif
399 :
400 :
401 : /* ----------------------------------------------------------------
402 : \Cairo\Pattern\Solid Class API
403 : ------------------------------------------------------------------ */
404 :
405 : /* {{{ proto void contruct(float red, float green, float blue[, float alpha])
406 : Returns new \Cairo\Pattern\Solid using rgb and optionally alpha */
407 25 : PHP_METHOD(Cairo_Pattern_Solid, __construct)
408 : {
409 25 : double red = 0.0, green = 0.0, blue = 0.0;
410 : double alpha;
411 25 : bool alpha_is_null = true;
412 : cairo_pattern_object *pattern_object;
413 :
414 25 : ZEND_PARSE_PARAMETERS_START(3, 4)
415 42 : Z_PARAM_DOUBLE(red)
416 40 : Z_PARAM_DOUBLE(green)
417 38 : Z_PARAM_DOUBLE(blue)
418 18 : Z_PARAM_OPTIONAL
419 21 : Z_PARAM_DOUBLE_OR_NULL(alpha, alpha_is_null)
420 25 : ZEND_PARSE_PARAMETERS_END();
421 :
422 34 : pattern_object = Z_CAIRO_PATTERN_P(getThis());
423 17 : if (!pattern_object) {
424 0 : RETURN_NULL();
425 : }
426 :
427 17 : if (alpha_is_null) {
428 15 : pattern_object->pattern = cairo_pattern_create_rgb(red, green, blue);
429 : } else {
430 2 : pattern_object->pattern = cairo_pattern_create_rgba(red, green, blue, alpha);
431 : }
432 :
433 17 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
434 0 : RETURN_THROWS();
435 : }
436 : }
437 : /* }}} */
438 :
439 : /* {{{ proto array \Cairo\Pattern\Solid::getRgba()
440 : This function returns an array with four elements,
441 : the float values of red, green, blue, and alpha from the solid pattern */
442 9 : PHP_METHOD(Cairo_Pattern_Solid, getRgba)
443 : {
444 : cairo_pattern_object *pattern_object;
445 : double red, green, blue, alpha;
446 : cairo_status_t status;
447 :
448 9 : ZEND_PARSE_PARAMETERS_NONE();
449 :
450 16 : pattern_object = cairo_pattern_object_get(getThis());
451 8 : if (!pattern_object) {
452 0 : RETURN_THROWS();
453 : }
454 :
455 8 : status = cairo_pattern_get_rgba(pattern_object->pattern, &red, &green, &blue, &alpha);
456 8 : if (php_cairo_throw_exception(status)) {
457 0 : RETURN_THROWS();
458 : }
459 :
460 8 : array_init(return_value);
461 8 : add_assoc_double(return_value, "red", red);
462 8 : add_assoc_double(return_value, "green", green);
463 8 : add_assoc_double(return_value, "blue", blue);
464 8 : add_assoc_double(return_value, "alpha", alpha);
465 : }
466 : /* }}} */
467 :
468 :
469 : /* ----------------------------------------------------------------
470 : \Cairo\Pattern\Gradient Class API
471 : ------------------------------------------------------------------ */
472 :
473 : /* {{{ proto void \Cairo\Pattern\Gradient::addColorStopRgb(float offset, float red, float green, float blue)
474 : Adds an opaque color stop to a gradient pattern.
475 : The offset specifies the location along the gradient's control vector. */
476 10 : PHP_METHOD(Cairo_Pattern_Gradient, addColorStopRgb)
477 : {
478 10 : double offset = 0.0, red = 0.0, green = 0.0, blue = 0.0;
479 : cairo_pattern_object *pattern_object;
480 :
481 10 : ZEND_PARSE_PARAMETERS_START(4, 4)
482 10 : Z_PARAM_DOUBLE(offset)
483 8 : Z_PARAM_DOUBLE(red)
484 6 : Z_PARAM_DOUBLE(green)
485 4 : Z_PARAM_DOUBLE(blue)
486 10 : ZEND_PARSE_PARAMETERS_END();
487 :
488 2 : pattern_object = cairo_pattern_object_get(getThis());
489 1 : if (!pattern_object) {
490 0 : RETURN_THROWS();
491 : }
492 :
493 1 : cairo_pattern_add_color_stop_rgb(pattern_object->pattern, offset, red, green, blue);
494 :
495 1 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
496 0 : RETURN_THROWS();
497 : }
498 : }
499 : /* }}} */
500 :
501 : /* {{{ proto void \Cairo\Pattern\Gradient::addColorStopRgba(float offset, float red, float green, float blue, float alpha)
502 : Adds a transparent color stop to a gradient pattern.
503 : The offset specifies the location along the gradient's control vector. */
504 16 : PHP_METHOD(Cairo_Pattern_Gradient, addColorStopRgba)
505 : {
506 16 : double offset = 0.0, red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
507 : cairo_pattern_object *pattern_object;
508 :
509 16 : ZEND_PARSE_PARAMETERS_START(5, 5)
510 20 : Z_PARAM_DOUBLE(offset)
511 18 : Z_PARAM_DOUBLE(red)
512 16 : Z_PARAM_DOUBLE(green)
513 14 : Z_PARAM_DOUBLE(blue)
514 12 : Z_PARAM_DOUBLE(alpha)
515 16 : ZEND_PARSE_PARAMETERS_END();
516 :
517 10 : pattern_object = cairo_pattern_object_get(getThis());
518 5 : if (!pattern_object) {
519 0 : RETURN_THROWS();
520 : }
521 :
522 5 : cairo_pattern_add_color_stop_rgba(pattern_object->pattern, offset, red, green, blue, alpha);
523 :
524 5 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
525 0 : RETURN_THROWS();
526 : }
527 : }
528 : /* }}} */
529 :
530 : /* {{{ proto array \Cairo\Pattern\Gradient::getColorStopRgba()
531 : Gets the color and offset information at the given index for a gradient pattern */
532 6 : PHP_METHOD(Cairo_Pattern_Gradient, getColorStopRgba)
533 : {
534 : zend_long index;
535 : double offset, red, green, blue, alpha;
536 : cairo_pattern_object *pattern_object;
537 : cairo_status_t status;
538 :
539 6 : ZEND_PARSE_PARAMETERS_START(1, 1)
540 8 : Z_PARAM_LONG(index)
541 6 : ZEND_PARSE_PARAMETERS_END();
542 :
543 6 : pattern_object = cairo_pattern_object_get(getThis());
544 3 : if (!pattern_object) {
545 0 : RETURN_THROWS();
546 : }
547 :
548 3 : status = cairo_pattern_get_color_stop_rgba(pattern_object->pattern, index, &offset, &red, &green, &blue, &alpha);
549 3 : if (php_cairo_throw_exception(status)) {
550 0 : RETURN_THROWS();
551 : }
552 :
553 3 : array_init(return_value);
554 3 : add_assoc_double(return_value, "offset", offset);
555 3 : add_assoc_double(return_value, "red", red);
556 3 : add_assoc_double(return_value, "green", green);
557 3 : add_assoc_double(return_value, "blue", blue);
558 3 : add_assoc_double(return_value, "alpha", alpha);
559 : }
560 : /* }}} */
561 :
562 : /* {{{ proto int \Cairo\Pattern\Gradient::getColorStopCount()
563 : Gets the number of color stops specified in the given gradient pattern */
564 3 : PHP_METHOD(Cairo_Pattern_Gradient, getColorStopCount)
565 : {
566 : int count;
567 : cairo_pattern_object *pattern_object;
568 : cairo_status_t status;
569 :
570 3 : ZEND_PARSE_PARAMETERS_NONE();
571 :
572 4 : pattern_object = cairo_pattern_object_get(getThis());
573 2 : if (!pattern_object) {
574 0 : RETURN_THROWS();
575 : }
576 :
577 2 : status = cairo_pattern_get_color_stop_count(pattern_object->pattern, &count);
578 2 : if (php_cairo_throw_exception(status)) {
579 0 : RETURN_THROWS();
580 : }
581 :
582 2 : RETURN_LONG(count);
583 : }
584 : /* }}} */
585 :
586 :
587 : /* ----------------------------------------------------------------
588 : \Cairo\Pattern\Gradient\Radial Class API
589 : ------------------------------------------------------------------ */
590 :
591 : /* {{{ proto void construct(float x0, float y0, float r0, float x1, float y1, float r1)
592 : Create a new Gradient along the line defined by (x0, y0) and (x1, y1).
593 : Before using the gradient pattern, a number of color stops should be defined. */
594 19 : PHP_METHOD(Cairo_Pattern_Gradient_Radial, __construct)
595 : {
596 : cairo_pattern_object *pattern_object;
597 19 : double x0 = 0.0, y0 = 0.0, r0 = 0.0, x1 = 0.0, y1 = 0.0, r1 = 0.0;
598 :
599 19 : ZEND_PARSE_PARAMETERS_START(6, 6)
600 24 : Z_PARAM_DOUBLE(x0)
601 22 : Z_PARAM_DOUBLE(y0)
602 20 : Z_PARAM_DOUBLE(r0)
603 18 : Z_PARAM_DOUBLE(x1)
604 16 : Z_PARAM_DOUBLE(y1)
605 14 : Z_PARAM_DOUBLE(r1)
606 19 : ZEND_PARSE_PARAMETERS_END();
607 :
608 12 : pattern_object = Z_CAIRO_PATTERN_P(getThis());
609 6 : if (!pattern_object) {
610 0 : RETURN_NULL();
611 : }
612 6 : pattern_object->pattern = cairo_pattern_create_radial(x0, y0, r0, x1, y1, r1);
613 6 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
614 0 : RETURN_THROWS();
615 : }
616 : }
617 : /* }}} */
618 :
619 : /* {{{ proto array \Cairo\Pattern\Gradient\Radial::getCircles()
620 : Gets the gradient endpoint circles for a radial gradient
621 : each specified as a center coordinate and a radius.*/
622 2 : PHP_METHOD(Cairo_Pattern_Gradient_Radial, getCircles)
623 : {
624 : cairo_pattern_object *pattern_object;
625 2 : double x0 = 0.0, y0 = 0.0, r0 = 0.0, x1 = 0.0, y1 = 0.0, r1 = 0.0;
626 : cairo_status_t status;
627 :
628 2 : ZEND_PARSE_PARAMETERS_NONE();
629 :
630 2 : pattern_object = cairo_pattern_object_get(getThis());
631 1 : if (!pattern_object) {
632 0 : RETURN_THROWS();
633 : }
634 :
635 1 : status = cairo_pattern_get_radial_circles(pattern_object->pattern, &x0, &y0, &r0, &x1, &y1, &r1);
636 :
637 1 : if (php_cairo_throw_exception(status)) {
638 0 : RETURN_THROWS();
639 : }
640 :
641 1 : array_init(return_value);
642 1 : add_assoc_double(return_value, "x0", x0);
643 1 : add_assoc_double(return_value, "y0", y0);
644 1 : add_assoc_double(return_value, "r0", r0);
645 1 : add_assoc_double(return_value, "x1", x1);
646 1 : add_assoc_double(return_value, "y1", y1);
647 1 : add_assoc_double(return_value, "r1", r1);
648 : }
649 : /* }}} */
650 :
651 :
652 : /* ----------------------------------------------------------------
653 : \Cairo\Pattern\Gradient\Linear Class API
654 : ------------------------------------------------------------------ */
655 :
656 : /* {{{ proto void construct(float x0, float y0, float x1, float y1)
657 : Create a new CairoLinearGradient along the line defined by (x0, y0) and (x1, y1).
658 : Before using the gradient pattern, a number of color stops should be defined. */
659 11 : PHP_METHOD(Cairo_Pattern_Gradient_Linear, __construct)
660 : {
661 : cairo_pattern_object *pattern_object;
662 11 : double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0;
663 :
664 11 : ZEND_PARSE_PARAMETERS_START(4, 4)
665 12 : Z_PARAM_DOUBLE(x0)
666 10 : Z_PARAM_DOUBLE(y0)
667 8 : Z_PARAM_DOUBLE(x1)
668 6 : Z_PARAM_DOUBLE(y1)
669 11 : ZEND_PARSE_PARAMETERS_END();
670 :
671 4 : pattern_object = Z_CAIRO_PATTERN_P(getThis());
672 2 : if (!pattern_object) {
673 0 : RETURN_NULL();
674 : }
675 :
676 2 : pattern_object->pattern = cairo_pattern_create_linear(x0, y0, x1, y1);
677 :
678 2 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
679 0 : RETURN_THROWS();
680 : }
681 : }
682 : /* }}} */
683 :
684 : /* {{{ proto void cairo_pattern_get_linear_points(CairoLinearGradient object)
685 : proto void \Cairo\Pattern\Gradient\Linear::getPoints()
686 : Gets the gradient endpoints for a linear gradient. */
687 2 : PHP_METHOD(Cairo_Pattern_Gradient_Linear, getPoints)
688 : {
689 : cairo_pattern_object *pattern_object;
690 : double x0, y0, x1, y1;
691 : cairo_status_t status;
692 :
693 2 : ZEND_PARSE_PARAMETERS_NONE();
694 :
695 2 : pattern_object = cairo_pattern_object_get(getThis());
696 1 : if (!pattern_object) {
697 0 : RETURN_THROWS();
698 : }
699 :
700 1 : status = cairo_pattern_get_linear_points(pattern_object->pattern, &x0, &y0, &x1, &y1);
701 :
702 1 : if (php_cairo_throw_exception(status)) {
703 0 : RETURN_THROWS();
704 : }
705 :
706 1 : array_init(return_value);
707 1 : add_assoc_double(return_value, "x0", x0);
708 1 : add_assoc_double(return_value, "y0", y0);
709 1 : add_assoc_double(return_value, "x1", x1);
710 1 : add_assoc_double(return_value, "y1", y1);
711 : }
712 : /* }}} */
713 :
714 :
715 : /* ----------------------------------------------------------------
716 : \Cairo\Pattern\Surface Class API
717 : ------------------------------------------------------------------ */
718 :
719 : /* {{{ proto void contruct([object surface])
720 : Returns new \Cairo\Pattern\Surface using supplied surface */
721 9 : PHP_METHOD(Cairo_Pattern_Surface, __construct)
722 : {
723 : cairo_pattern_object *pattern_object;
724 : cairo_surface_object *surface_object;
725 : zval *surface_zval;
726 :
727 9 : ZEND_PARSE_PARAMETERS_START(1, 1)
728 14 : Z_PARAM_OBJECT_OF_CLASS(surface_zval, ce_cairo_surface)
729 9 : ZEND_PARSE_PARAMETERS_END();
730 :
731 12 : pattern_object = Z_CAIRO_PATTERN_P(getThis());
732 6 : if (!pattern_object) {
733 0 : RETURN_NULL();
734 : }
735 :
736 6 : surface_object = cairo_surface_object_get(surface_zval);
737 6 : if (!surface_object) {
738 0 : RETURN_THROWS();
739 : }
740 :
741 6 : pattern_object->pattern = cairo_pattern_create_for_surface(surface_object->surface);
742 6 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
743 0 : RETURN_THROWS();
744 : }
745 :
746 : /* we need to be able to get these zvals out later, so store it*/
747 6 : ZVAL_COPY(&pattern_object->surface, surface_zval);
748 : }
749 : /* }}} */
750 :
751 : /* {{{ proto CairoSurface object \Cairo\Pattern\Surface::getSurface()
752 : This function returns the surface object */
753 2 : PHP_METHOD(Cairo_Pattern_Surface, getSurface)
754 : {
755 : cairo_pattern_object *pattern_object;
756 : cairo_surface_object *surface_object;
757 : cairo_surface_t *surface;
758 :
759 3 : ZEND_PARSE_PARAMETERS_NONE();
760 :
761 2 : pattern_object = cairo_pattern_object_get(getThis());
762 1 : if (!pattern_object) {
763 0 : RETURN_THROWS();
764 : }
765 :
766 1 : if (php_cairo_throw_exception(cairo_pattern_get_surface(pattern_object->pattern, &surface))) {
767 0 : RETURN_THROWS();
768 : }
769 :
770 : /* If we have a surface, grab that zval to use */
771 5 : CAIRO_RETURN_IF_REF(pattern_object->surface);
772 :
773 : /* Otherwise we spawn a new object */
774 : /* we can't always rely on the same type of surface being returned, so we use php_cairo_get_surface_ce */
775 0 : object_init_ex(return_value, php_cairo_get_surface_ce(surface));
776 :
777 : // cairo_surface_create_object(php_cairo_get_surface_ce(surface));
778 0 : surface_object = Z_CAIRO_SURFACE_P(return_value);
779 :
780 : /* if there IS a value in surface, destroy it cause we're getting a new one */
781 0 : if (surface_object->surface != NULL) {
782 0 : cairo_surface_destroy(surface_object->surface);
783 : }
784 :
785 0 : surface_object->surface = surface;
786 0 : cairo_surface_reference(surface_object->surface);
787 : }
788 : /* }}} */
789 :
790 :
791 : /* ----------------------------------------------------------------
792 : \Cairo\Pattern\Mesh Class API
793 : ------------------------------------------------------------------ */
794 :
795 : /* {{{ proto void contruct()
796 : Returns new \Cairo\Pattern\Mesh */
797 15 : PHP_METHOD(Cairo_Pattern_Mesh, __construct)
798 : {
799 : cairo_pattern_object *pattern_object;
800 :
801 15 : ZEND_PARSE_PARAMETERS_NONE();
802 :
803 28 : pattern_object = Z_CAIRO_PATTERN_P(getThis());
804 14 : if (!pattern_object) {
805 0 : RETURN_NULL();
806 : }
807 :
808 14 : pattern_object->pattern = cairo_pattern_create_mesh();
809 :
810 14 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
811 0 : RETURN_THROWS();
812 : }
813 : }
814 : /* }}} */
815 :
816 : /* {{{ proto void \Cairo\Pattern\Mesh::beginPatch()
817 : begin a patch in a mesh pattern */
818 15 : PHP_METHOD(Cairo_Pattern_Mesh, beginPatch)
819 : {
820 : cairo_pattern_object *pattern_object;
821 :
822 15 : ZEND_PARSE_PARAMETERS_NONE();
823 :
824 28 : pattern_object = cairo_pattern_object_get(getThis());
825 14 : if (!pattern_object) {
826 0 : RETURN_THROWS();
827 : }
828 :
829 14 : cairo_mesh_pattern_begin_patch(pattern_object->pattern);
830 :
831 14 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
832 1 : RETURN_THROWS();
833 : }
834 : }
835 : /* }}} */
836 :
837 : /* {{{ proto void \Cairo\Pattern\Mesh::endPatch()
838 : end a patch in a mesh pattern*/
839 14 : PHP_METHOD(Cairo_Pattern_Mesh, endPatch)
840 : {
841 : cairo_pattern_object *pattern_object;
842 :
843 14 : ZEND_PARSE_PARAMETERS_NONE();
844 :
845 26 : pattern_object = cairo_pattern_object_get(getThis());
846 13 : if (!pattern_object) {
847 0 : RETURN_THROWS();
848 : }
849 :
850 13 : cairo_mesh_pattern_end_patch(pattern_object->pattern);
851 :
852 13 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
853 1 : RETURN_THROWS();
854 : }
855 : }
856 : /* }}} */
857 :
858 : /* {{{ proto void \Cairo\Pattern\Mesh::moveTo(float x, float y)
859 : move to a new starting point position in the patch */
860 12 : PHP_METHOD(Cairo_Pattern_Mesh, moveTo)
861 : {
862 : cairo_pattern_object *pattern_object;
863 : double x, y;
864 :
865 12 : ZEND_PARSE_PARAMETERS_START(2, 2)
866 18 : Z_PARAM_DOUBLE(x)
867 16 : Z_PARAM_DOUBLE(y)
868 12 : ZEND_PARSE_PARAMETERS_END();
869 :
870 14 : pattern_object = cairo_pattern_object_get(getThis());
871 7 : if (!pattern_object) {
872 0 : RETURN_THROWS();
873 : }
874 :
875 7 : cairo_mesh_pattern_move_to(pattern_object->pattern, x, y);
876 :
877 7 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
878 0 : RETURN_THROWS();
879 : }
880 : }
881 : /* }}} */
882 :
883 : /* {{{ proto void \Cairo\Pattern\Mesh::lineTo(float x, float y)
884 : add a line from the current point to position in the patch */
885 15 : PHP_METHOD(Cairo_Pattern_Mesh, lineTo)
886 : {
887 : cairo_pattern_object *pattern_object;
888 : double x, y;
889 :
890 15 : ZEND_PARSE_PARAMETERS_START(2, 2)
891 24 : Z_PARAM_DOUBLE(x)
892 22 : Z_PARAM_DOUBLE(y)
893 15 : ZEND_PARSE_PARAMETERS_END();
894 :
895 20 : pattern_object = cairo_pattern_object_get(getThis());
896 10 : if (!pattern_object) {
897 0 : RETURN_THROWS();
898 : }
899 :
900 10 : cairo_mesh_pattern_line_to(pattern_object->pattern, x, y);
901 :
902 10 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
903 0 : RETURN_THROWS();
904 : }
905 : }
906 : /* }}} */
907 :
908 : /* {{{ proto void \Cairo\Pattern\Mesh::curveTo(float x1, float y1, float x2,
909 : * float y2, float x3, float y3)
910 : cubic bezier spline added to current path */
911 10 : PHP_METHOD(Cairo_Pattern_Mesh, curveTo)
912 : {
913 : cairo_pattern_object *pattern_object;
914 : double x1, y1, x2, y2, x3, y3;
915 :
916 10 : ZEND_PARSE_PARAMETERS_START(6, 6)
917 14 : Z_PARAM_DOUBLE(x1)
918 12 : Z_PARAM_DOUBLE(y1)
919 10 : Z_PARAM_DOUBLE(x2)
920 8 : Z_PARAM_DOUBLE(y2)
921 6 : Z_PARAM_DOUBLE(x3)
922 4 : Z_PARAM_DOUBLE(y3)
923 10 : ZEND_PARSE_PARAMETERS_END();
924 :
925 2 : pattern_object = cairo_pattern_object_get(getThis());
926 1 : if (!pattern_object) {
927 0 : RETURN_THROWS();
928 : }
929 :
930 1 : cairo_mesh_pattern_curve_to(pattern_object->pattern, x1, y1, x2, y2, x3, y3);
931 :
932 1 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
933 0 : RETURN_THROWS();
934 : }
935 : }
936 : /* }}} */
937 :
938 : /* {{{ proto void \Cairo\Pattern\Mesh::setControlPoint(int point_num,
939 : float x, float y)
940 : Set an internal control point of the current patch. */
941 11 : PHP_METHOD(Cairo_Pattern_Mesh, setControlPoint)
942 : {
943 : cairo_pattern_object *pattern_object;
944 : zend_long point_num;
945 : double x, y;
946 :
947 11 : ZEND_PARSE_PARAMETERS_START(3, 3)
948 16 : Z_PARAM_LONG(point_num)
949 14 : Z_PARAM_DOUBLE(x)
950 12 : Z_PARAM_DOUBLE(y)
951 11 : ZEND_PARSE_PARAMETERS_END();
952 :
953 10 : pattern_object = cairo_pattern_object_get(getThis());
954 5 : if (!pattern_object) {
955 0 : RETURN_THROWS();
956 : }
957 :
958 5 : if (point_num < 0 || point_num > 3) {
959 2 : zend_throw_error(ce_cairo_exception, "Invalid $point_num. Expected 0, 1, 2, or 3.");
960 2 : RETURN_THROWS();
961 : }
962 :
963 3 : cairo_mesh_pattern_set_control_point(pattern_object->pattern, point_num, x, y);
964 :
965 3 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
966 0 : RETURN_THROWS();
967 : }
968 : }
969 : /* }}} */
970 :
971 : // TODO: combine setCornerColorRgb and setCornerColorRgba to setCornerColor
972 : // default value for alpha = 1.0
973 :
974 : /* {{{ proto void \Cairo\Pattern\Mesh::setCornerColorRgb(int corner_num,
975 : float red, float blue, float green)
976 : Sets the color of a corner of the current patch in a mesh pattern. */
977 12 : PHP_METHOD(Cairo_Pattern_Mesh, setCornerColorRgb)
978 : {
979 : cairo_pattern_object *pattern_object;
980 : zend_long corner_num;
981 : double red, green, blue;
982 :
983 12 : ZEND_PARSE_PARAMETERS_START(4, 4)
984 14 : Z_PARAM_LONG(corner_num)
985 12 : Z_PARAM_DOUBLE(red)
986 10 : Z_PARAM_DOUBLE(green)
987 8 : Z_PARAM_DOUBLE(blue)
988 12 : ZEND_PARSE_PARAMETERS_END();
989 :
990 6 : pattern_object = cairo_pattern_object_get(getThis());
991 3 : if (!pattern_object) {
992 0 : RETURN_THROWS();
993 : }
994 :
995 3 : if (corner_num < 0 || corner_num > 3) {
996 2 : zend_throw_error(ce_cairo_exception, "Invalid $corner_num. Expected 0, 1, 2, or 3.");
997 2 : RETURN_THROWS();
998 : }
999 :
1000 1 : cairo_mesh_pattern_set_corner_color_rgb(pattern_object->pattern, corner_num, red, green, blue);
1001 :
1002 1 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
1003 0 : RETURN_THROWS();
1004 : }
1005 : }
1006 : /* }}} */
1007 :
1008 : /* {{{ proto void \Cairo\Pattern\Mesh::setCornerColorRgba(int corner_num,
1009 : float red, float blue, float green, float alpha)
1010 : Sets the color of a corner of the current patch in a mesh pattern. */
1011 18 : PHP_METHOD(Cairo_Pattern_Mesh, setCornerColorRgba)
1012 : {
1013 : cairo_pattern_object *pattern_object;
1014 : zend_long corner_num;
1015 : double red, green, blue, alpha;
1016 :
1017 18 : ZEND_PARSE_PARAMETERS_START(5, 5)
1018 24 : Z_PARAM_LONG(corner_num)
1019 22 : Z_PARAM_DOUBLE(red)
1020 20 : Z_PARAM_DOUBLE(green)
1021 18 : Z_PARAM_DOUBLE(blue)
1022 16 : Z_PARAM_DOUBLE(alpha)
1023 18 : ZEND_PARSE_PARAMETERS_END();
1024 :
1025 14 : pattern_object = cairo_pattern_object_get(getThis());
1026 7 : if (!pattern_object) {
1027 0 : RETURN_THROWS();
1028 : }
1029 :
1030 7 : if (corner_num < 0 || corner_num > 3) {
1031 2 : zend_throw_error(ce_cairo_exception, "Invalid $corner_num. Expected 0, 1, 2, or 3.");
1032 2 : RETURN_THROWS();
1033 : }
1034 :
1035 5 : cairo_mesh_pattern_set_corner_color_rgba(pattern_object->pattern, corner_num, red, green, blue, alpha);
1036 :
1037 5 : if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
1038 0 : RETURN_THROWS();
1039 : }
1040 : }
1041 : /* }}} */
1042 :
1043 : /* {{{ proto void \Cairo\Pattern\Mesh::getPatchCount()
1044 : Gets the number of patches specified in the given mesh pattern. */
1045 12 : PHP_METHOD(Cairo_Pattern_Mesh, getPatchCount)
1046 : {
1047 : cairo_pattern_object *pattern_object;
1048 : unsigned int count;
1049 :
1050 12 : ZEND_PARSE_PARAMETERS_NONE();
1051 :
1052 24 : pattern_object = cairo_pattern_object_get(getThis());
1053 12 : if (!pattern_object) {
1054 0 : RETURN_THROWS();
1055 : }
1056 :
1057 12 : if (php_cairo_throw_exception(cairo_mesh_pattern_get_patch_count(pattern_object->pattern, &count))) {
1058 0 : RETURN_THROWS();
1059 : }
1060 :
1061 12 : RETURN_LONG(count);
1062 : }
1063 : /* }}} */
1064 :
1065 : /* {{{ proto void \Cairo\Pattern\Mesh::getPath()
1066 : Gets path defining the patch patch_num for a mesh pattern. */
1067 4 : PHP_METHOD(Cairo_Pattern_Mesh, getPath)
1068 : {
1069 : cairo_pattern_object *pattern_object;
1070 : cairo_path_object *path_object;
1071 : cairo_path_t *path;
1072 : zend_long patch_num;
1073 :
1074 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
1075 4 : Z_PARAM_LONG(patch_num)
1076 4 : ZEND_PARSE_PARAMETERS_END();
1077 :
1078 2 : pattern_object = cairo_pattern_object_get(getThis());
1079 1 : if (!pattern_object) {
1080 0 : RETURN_THROWS();
1081 : }
1082 :
1083 1 : path = cairo_mesh_pattern_get_path(pattern_object->pattern, patch_num);
1084 :
1085 1 : object_init_ex(return_value, php_cairo_get_path_ce());
1086 :
1087 1 : path_object = Z_CAIRO_PATH_P(return_value);
1088 1 : if (!path_object) {
1089 0 : RETURN_NULL();
1090 : }
1091 :
1092 1 : path_object->path = path;
1093 : }
1094 : /* }}} */
1095 :
1096 : /* {{{ proto array \Cairo\Pattern\Mesh::getControlPoint()
1097 : Gets the control point point_num of patch patch_num for a mesh pattern. */
1098 13 : PHP_METHOD(Cairo_Pattern_Mesh, getControlPoint)
1099 : {
1100 : cairo_pattern_object *pattern_object;
1101 : zend_long patch_num, point_num;
1102 : double x, y;
1103 : unsigned int count, max_patch_id;
1104 :
1105 13 : ZEND_PARSE_PARAMETERS_START(2, 2)
1106 20 : Z_PARAM_LONG(patch_num)
1107 18 : Z_PARAM_LONG(point_num)
1108 13 : ZEND_PARSE_PARAMETERS_END();
1109 :
1110 16 : pattern_object = cairo_pattern_object_get(getThis());
1111 8 : if (!pattern_object) {
1112 0 : RETURN_THROWS();
1113 : }
1114 :
1115 8 : cairo_mesh_pattern_get_patch_count(pattern_object->pattern, &count);
1116 8 : max_patch_id = count - 1;
1117 8 : if (count == 0) {
1118 2 : zend_throw_error(ce_cairo_exception, "No patches found or first patch not finished with endPatch().");
1119 2 : RETURN_THROWS();
1120 6 : } else if (patch_num < 0 || (unsigned int)patch_num > max_patch_id) {
1121 2 : zend_throw_error(ce_cairo_exception, "Invalid $patch_num. Expected 0 to %d.", max_patch_id);
1122 2 : RETURN_THROWS();
1123 : }
1124 :
1125 4 : if (point_num < 0 || point_num > 3) {
1126 2 : zend_throw_error(ce_cairo_exception, "Invalid $point_num. Expected 0, 1, 2, or 3.");
1127 2 : RETURN_THROWS();
1128 : }
1129 :
1130 2 : if (php_cairo_throw_exception(cairo_mesh_pattern_get_control_point(
1131 : pattern_object->pattern, patch_num, point_num, &x, &y))) {
1132 0 : RETURN_THROWS();
1133 : }
1134 :
1135 2 : array_init(return_value);
1136 2 : add_assoc_double(return_value, "x", x);
1137 2 : add_assoc_double(return_value, "y", y);
1138 : }
1139 : /* }}} */
1140 :
1141 : /* {{{ proto void \Cairo\Pattern\Mesh::getCornerColorRgba()
1142 : Gets the color information in corner of path for a mesh pattern */
1143 13 : PHP_METHOD(Cairo_Pattern_Mesh, getCornerColorRgba)
1144 : {
1145 : cairo_pattern_object *pattern_object;
1146 : zend_long patch_num, corner_num;
1147 : double red, green, blue, alpha;
1148 : unsigned int count, max_patch_id;
1149 :
1150 13 : ZEND_PARSE_PARAMETERS_START(2, 2)
1151 20 : Z_PARAM_LONG(patch_num)
1152 18 : Z_PARAM_LONG(corner_num)
1153 13 : ZEND_PARSE_PARAMETERS_END();
1154 :
1155 16 : pattern_object = cairo_pattern_object_get(getThis());
1156 8 : if (!pattern_object) {
1157 0 : RETURN_THROWS();
1158 : }
1159 :
1160 8 : cairo_mesh_pattern_get_patch_count(pattern_object->pattern, &count);
1161 8 : max_patch_id = count - 1;
1162 8 : if (count == 0) {
1163 0 : zend_throw_error(ce_cairo_exception, "No patches found or first patch not finished with endPatch().");
1164 0 : RETURN_THROWS();
1165 8 : } else if (patch_num < 0 || (unsigned int)patch_num > max_patch_id) {
1166 2 : zend_throw_error(ce_cairo_exception, "Invalid $patch_num. Expected 0 to %d.", max_patch_id);
1167 2 : RETURN_THROWS();
1168 : }
1169 :
1170 6 : if (corner_num < 0 || corner_num > 3) {
1171 2 : zend_throw_error(ce_cairo_exception, "Invalid $corner_num. Expected 0, 1, 2, or 3.");
1172 2 : RETURN_THROWS();
1173 : }
1174 :
1175 4 : if (php_cairo_throw_exception(cairo_mesh_pattern_get_corner_color_rgba(
1176 : pattern_object->pattern, patch_num, corner_num, &red, &green, &blue, &alpha))) {
1177 0 : RETURN_THROWS();
1178 : }
1179 :
1180 4 : array_init(return_value);
1181 4 : add_assoc_double(return_value, "red", red);
1182 4 : add_assoc_double(return_value, "green", green);
1183 4 : add_assoc_double(return_value, "blue", blue);
1184 4 : add_assoc_double(return_value, "alpha", alpha);
1185 : }
1186 : /* }}} */
1187 :
1188 :
1189 : /* ----------------------------------------------------------------
1190 : \Cairo\Pattern\RasterSource Class API
1191 : ------------------------------------------------------------------ */
1192 :
1193 : /* {{{ proto void construct(enum \Cairo\Surface\Content, int width, int height)
1194 : Returns new \Cairo\Pattern\RasterSource using supplied surface */
1195 : // PHP_METHOD(CairoPatternRasterSource, __construct)
1196 : // {
1197 : // cairo_pattern_object *pattern_object;
1198 : // zend_long width, height;
1199 : // zval *content;
1200 :
1201 : // ZEND_PARSE_PARAMETERS_START(3, 3)
1202 : // Z_PARAM_OBJECT_OF_CLASS(content, ce_cairo_content)
1203 : // Z_PARAM_LONG(width)
1204 : // Z_PARAM_LONG(height)
1205 : // ZEND_PARSE_PARAMETERS_END();
1206 :
1207 : // pattern_object = Z_CAIRO_PATTERN_P(getThis());
1208 : // if (!pattern_object) {
1209 : // RETURN_NULL();
1210 : // }
1211 :
1212 : // // TODO: create callbacks in C that feed to php methods as callbacks
1213 : // // register them all, and do the create
1214 : // // also figure out callback data - varargs?
1215 : // if (php_cairo_throw_exception(cairo_pattern_status(pattern_object->pattern))) {
1216 : // RETURN_THROWS();
1217 : // }
1218 : // }
1219 : /* }}} */
1220 :
1221 :
1222 : /* ----------------------------------------------------------------
1223 : \Cairo\Pattern Object management
1224 : ------------------------------------------------------------------*/
1225 :
1226 : /* {{{ */
1227 90 : static void cairo_pattern_free_obj(zend_object *object)
1228 : {
1229 90 : cairo_pattern_object *intern = cairo_pattern_fetch_object(object);
1230 :
1231 90 : if (!intern) {
1232 0 : return;
1233 : }
1234 :
1235 90 : zval_ptr_dtor(&intern->surface);
1236 :
1237 90 : if (intern->pattern) {
1238 51 : cairo_pattern_destroy(intern->pattern);
1239 51 : intern->pattern = NULL;
1240 : }
1241 :
1242 90 : zend_object_std_dtor(&intern->std);
1243 : }
1244 : /* }}} */
1245 :
1246 : /* {{{ */
1247 90 : static zend_object* cairo_pattern_obj_ctor(zend_class_entry *ce, cairo_pattern_object **intern)
1248 : {
1249 90 : cairo_pattern_object *object = ecalloc(1, sizeof(cairo_pattern_object) + zend_object_properties_size(ce));
1250 :
1251 90 : ZVAL_UNDEF(&object->surface);
1252 90 : object->pattern = NULL;
1253 :
1254 90 : zend_object_std_init(&object->std, ce);
1255 90 : object->std.handlers = &cairo_pattern_object_handlers;
1256 90 : *intern = object;
1257 :
1258 90 : return &object->std;
1259 : }
1260 : /* }}} */
1261 :
1262 : /* {{{ */
1263 90 : static zend_object* cairo_pattern_create_object(zend_class_entry *ce)
1264 : {
1265 90 : cairo_pattern_object *pattern = NULL;
1266 90 : zend_object *return_value = cairo_pattern_obj_ctor(ce, &pattern);
1267 :
1268 90 : object_properties_init(&pattern->std, ce);
1269 90 : return return_value;
1270 : }
1271 : /* }}} */
1272 :
1273 :
1274 : /* ----------------------------------------------------------------
1275 : \Cairo\Pattern Definition and registration
1276 : ------------------------------------------------------------------*/
1277 :
1278 : /* {{{ PHP_MINIT_FUNCTION */
1279 424 : PHP_MINIT_FUNCTION(cairo_pattern)
1280 : {
1281 424 : memcpy(
1282 : &cairo_pattern_object_handlers,
1283 : zend_get_std_object_handlers(),
1284 : sizeof(zend_object_handlers)
1285 : );
1286 :
1287 : // Pattern
1288 424 : cairo_pattern_object_handlers.offset = XtOffsetOf(cairo_pattern_object, std);
1289 424 : cairo_pattern_object_handlers.free_obj = cairo_pattern_free_obj;
1290 :
1291 424 : ce_cairo_pattern = register_class_Cairo_Pattern();
1292 424 : ce_cairo_pattern->create_object = cairo_pattern_create_object;
1293 :
1294 : // Pattern\Solid
1295 424 : ce_cairo_pattern_solid = register_class_Cairo_Pattern_Solid(ce_cairo_pattern);
1296 :
1297 : // Pattern\Gradient
1298 424 : ce_cairo_pattern_gradient = register_class_Cairo_Pattern_Gradient(ce_cairo_pattern);
1299 :
1300 : // Pattern\Gradient\Radial
1301 424 : ce_cairo_pattern_gradient_radial = register_class_Cairo_Pattern_Gradient_Radial(ce_cairo_pattern_gradient);
1302 :
1303 : // Pattern\Gradient\Linear
1304 424 : ce_cairo_pattern_gradient_linear = register_class_Cairo_Pattern_Gradient_Linear(ce_cairo_pattern_gradient);
1305 :
1306 : // Pattern\Surface
1307 424 : ce_cairo_pattern_surface = register_class_Cairo_Pattern_Surface(ce_cairo_pattern);
1308 :
1309 : // Pattern\Mesh
1310 424 : ce_cairo_pattern_mesh = register_class_Cairo_Pattern_Mesh(ce_cairo_pattern);
1311 :
1312 : // Pattern\RasterSource
1313 : // not implemented yet
1314 : // ce_cairo_pattern_raster = register_class_Cairo_Pattern_RasterSource(ce_cairo_pattern);
1315 :
1316 : // Pattern\Type
1317 424 : ce_cairo_pattern_type = register_class_Cairo_Pattern_Type();
1318 :
1319 : // Extend
1320 424 : ce_cairo_extend = register_class_Cairo_Extend();
1321 :
1322 : // Filter
1323 424 : ce_cairo_filter = register_class_Cairo_Filter();
1324 :
1325 : // Dither
1326 424 : ce_cairo_dither = register_class_Cairo_Dither();
1327 :
1328 424 : return SUCCESS;
1329 : }
|