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 "region_arginfo.h"
26 :
27 : zend_class_entry *ce_cairo_region;
28 : zend_class_entry *ce_cairo_region_overlap;
29 :
30 : static zend_object_handlers cairo_region_object_handlers;
31 :
32 : typedef struct _cairo_region_object {
33 : cairo_region_t *region;
34 : zend_object std;
35 : } cairo_region_object;
36 :
37 197 : static inline cairo_region_object *cairo_region_fetch_object(zend_object *object)
38 : {
39 197 : return (cairo_region_object *) ((char*)(object) - XtOffsetOf(cairo_region_object, std));
40 : }
41 :
42 : #define Z_CAIRO_REGION_P(zv) cairo_region_fetch_object(Z_OBJ_P(zv))
43 :
44 92 : cairo_region_object *cairo_region_object_get(zval *zv)
45 : {
46 92 : cairo_region_object *object = Z_CAIRO_REGION_P(zv);
47 92 : if (object->region == NULL) {
48 0 : zend_throw_exception_ex(ce_cairo_exception, 0,
49 : "Internal region object missing in %s, you must call parent::__construct in extended classes.",
50 0 : ZSTR_VAL(Z_OBJCE_P(zv)->name));
51 0 : return NULL;
52 : }
53 92 : return object;
54 : }
55 :
56 : /* ----------------------------------------------------------------
57 : \Cairo\Region Object management
58 : ------------------------------------------------------------------*/
59 :
60 : /* {{{ */
61 47 : static void cairo_region_free_obj(zend_object *object)
62 : {
63 47 : cairo_region_object *intern = cairo_region_fetch_object(object);
64 :
65 47 : if (!intern) {
66 0 : return;
67 : }
68 :
69 47 : if (intern->region) {
70 44 : cairo_region_destroy(intern->region);
71 44 : intern->region = NULL;
72 : }
73 :
74 47 : zend_object_std_dtor(&intern->std);
75 : }
76 :
77 : /* {{{ */
78 47 : static zend_object* cairo_region_obj_ctor(zend_class_entry *ce, cairo_region_object **intern)
79 : {
80 47 : cairo_region_object *object = ecalloc(1, sizeof(cairo_region_object) + zend_object_properties_size(ce));
81 :
82 47 : object->region = NULL;
83 :
84 47 : zend_object_std_init(&object->std, ce);
85 47 : object->std.handlers = &cairo_region_object_handlers;
86 47 : *intern = object;
87 :
88 47 : return &object->std;
89 : }
90 : /* }}} */
91 :
92 : /* {{{ */
93 45 : static zend_object* cairo_region_create_object(zend_class_entry *ce)
94 : {
95 45 : cairo_region_object *region_obj = NULL;
96 45 : zend_object *return_value = cairo_region_obj_ctor(ce, ®ion_obj);
97 :
98 45 : object_properties_init(®ion_obj->std, ce);
99 45 : return return_value;
100 : }
101 : /* }}} */
102 :
103 : /* {{{ */
104 2 : static zend_object* cairo_region_clone_obj(zend_object *old_object)
105 : {
106 : cairo_region_object *new_region;
107 2 : cairo_region_object *old_region = cairo_region_fetch_object(old_object);
108 2 : zend_object *return_value = cairo_region_obj_ctor(old_object->ce, &new_region);
109 :
110 2 : new_region->region = old_region->region;
111 2 : cairo_region_reference(old_region->region);
112 :
113 2 : zend_objects_clone_members(&new_region->std, &old_region->std);
114 :
115 2 : return return_value;
116 : }
117 : /* }}} */
118 :
119 :
120 : /* ----------------------------------------------------------------
121 : \Cairo\Region Class API
122 : ------------------------------------------------------------------ */
123 :
124 : /* {{{ proto void __contruct([void | Cairo\Rectangle $rect | array Cairo\Rectangle $rects])
125 : Creates a new region - optionally with a single or union of multiple rectangles inside */
126 45 : PHP_METHOD(Cairo_Region, __construct)
127 : {
128 : cairo_region_object *region_object;
129 45 : zval *rectangles_zval = NULL;
130 45 : long num_rectangles = 0;
131 : HashTable *rectangles_hash;
132 : cairo_rectangle_t *rectangle;
133 : cairo_rectangle_int_t *rectangles_array;
134 : cairo_rectangle_int_t int_rect;
135 45 : int i = 0;
136 : zval *pzval;
137 :
138 45 : ZEND_PARSE_PARAMETERS_START(0, 1)
139 44 : Z_PARAM_OPTIONAL
140 44 : Z_PARAM_ZVAL(rectangles_zval)
141 47 : ZEND_PARSE_PARAMETERS_END();
142 :
143 88 : region_object = Z_CAIRO_REGION_P(getThis());
144 44 : if (!region_object) {
145 0 : RETURN_NULL();
146 : }
147 :
148 44 : if (rectangles_zval == NULL) {
149 17 : region_object->region = cairo_region_create();
150 54 : } else if (Z_TYPE_P(rectangles_zval) == IS_OBJECT) {
151 19 : rectangle = cairo_rectangle_object_get_rect(rectangles_zval);
152 19 : int_rect = cairo_expand_to_rectangle_int(rectangle);
153 19 : region_object->region = cairo_region_create_rectangle(&int_rect);
154 16 : } else if (Z_TYPE_P(rectangles_zval) == IS_ARRAY) {
155 :
156 : /* Grab the zend hash and see how big our array will be */
157 7 : rectangles_hash = Z_ARRVAL_P(rectangles_zval);
158 7 : num_rectangles = zend_hash_num_elements(rectangles_hash);
159 7 : rectangles_array = ecalloc(num_rectangles, sizeof(cairo_rectangle_int_t));
160 :
161 : /* iterate over the array*/
162 34 : ZEND_HASH_FOREACH_VAL(rectangles_hash, pzval) {
163 14 : if (Z_TYPE_P(pzval) != IS_OBJECT || Z_OBJCE_P(pzval) != ce_cairo_rectangle) {
164 1 : zend_throw_exception(zend_ce_type_error, "Cairo\\Region::__construct(): Argument #1 ($rectangle) must be empty, a Cairo\\Rectangle object, or an array of Cairo\\Rectangle objects.", 0);
165 1 : efree(rectangles_array);
166 1 : RETURN_THROWS();
167 : }
168 13 : rectangles_array[i++] = cairo_expand_to_rectangle_int(cairo_rectangle_object_get_rect(pzval));
169 : } ZEND_HASH_FOREACH_END();
170 :
171 6 : region_object->region = cairo_region_create_rectangles(rectangles_array, i);
172 6 : efree(rectangles_array);
173 :
174 : } else {
175 1 : zend_throw_exception(zend_ce_type_error, "Cairo\\Region::__construct(): Argument #1 ($rectangle) must be empty, a Cairo\\Rectangle object, or an array of Cairo\\Rectangle objects.", 0);
176 1 : RETURN_THROWS();
177 : }
178 :
179 42 : if (php_cairo_throw_exception(cairo_region_status(region_object->region))) {
180 0 : RETURN_THROWS();
181 : }
182 : }
183 : /* }}} */
184 :
185 : /* {{{ proto \Cairo\Status \Cairo\Region::getStatus()
186 : Checks whether an error has previous occurred for this region object. Returns CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY */
187 2 : PHP_METHOD(Cairo_Region, getStatus)
188 : {
189 : cairo_region_object *region_object;
190 : zval status_case;
191 :
192 3 : ZEND_PARSE_PARAMETERS_NONE();
193 :
194 2 : region_object = cairo_region_object_get(getThis());
195 1 : if (!region_object) {
196 0 : RETURN_THROWS();
197 : }
198 :
199 1 : status_case = php_enum_from_cairo_c_enum(
200 : ce_cairo_status,
201 1 : cairo_region_status(region_object->region)
202 : );
203 :
204 1 : if (Z_TYPE(status_case) == IS_OBJECT) {
205 2 : RETURN_ZVAL(&status_case, 1, 1);
206 : }
207 : }
208 : /* }}} */
209 :
210 : /* {{{ proto long \Cairo\Region::getExtents()
211 : Gets the bounding rectangle of a region. Returns a \Cairo\Rectangle. */
212 27 : PHP_METHOD(Cairo_Region, getExtents)
213 : {
214 : cairo_region_object *region_object;
215 : cairo_rectangle_object *rectangle_object;
216 : cairo_rectangle_int_t *int_rect;
217 :
218 27 : ZEND_PARSE_PARAMETERS_NONE();
219 :
220 52 : region_object = cairo_region_object_get(getThis());
221 26 : if (!region_object) {
222 0 : RETURN_THROWS();
223 : }
224 :
225 26 : cairo_region_get_extents(region_object->region, int_rect);
226 :
227 26 : object_init_ex(return_value, php_cairo_get_rectangle_ce());
228 26 : rectangle_object = Z_CAIRO_RECTANGLE_P(return_value);
229 26 : cairo_rectangle_int_to_double(int_rect, rectangle_object->rect);
230 : }
231 : /* }}} */
232 :
233 : /* {{{ proto long \Cairo\Region::getNumRectangles()
234 : Returns the number of rectangles contained in region. */
235 27 : PHP_METHOD(Cairo_Region, getNumRectangles)
236 : {
237 : cairo_region_object *region_object;
238 :
239 27 : ZEND_PARSE_PARAMETERS_NONE();
240 :
241 52 : region_object = cairo_region_object_get(getThis());
242 26 : if (!region_object) {
243 0 : RETURN_THROWS();
244 : }
245 :
246 26 : RETVAL_LONG(cairo_region_num_rectangles(region_object->region));
247 : }
248 : /* }}} */
249 :
250 : /* {{{ proto long \Cairo\Region::getRectangle(int number).
251 : Returns the nth rectangle in region or false if rectangle does not exist. */
252 5 : PHP_METHOD(Cairo_Region, getRectangle)
253 : {
254 : long rectId;
255 : cairo_region_object *region_object;
256 : cairo_rectangle_object *rectangle_object;
257 : cairo_rectangle_int_t int_rect;
258 :
259 5 : ZEND_PARSE_PARAMETERS_START(1, 1)
260 10 : Z_PARAM_LONG(rectId)
261 5 : ZEND_PARSE_PARAMETERS_END();
262 :
263 8 : region_object = cairo_region_object_get(getThis());
264 4 : if (!region_object) {
265 0 : RETURN_THROWS();
266 : }
267 :
268 4 : if (rectId > cairo_region_num_rectangles(region_object->region) - 1) {
269 1 : RETURN_FALSE;
270 : }
271 :
272 3 : cairo_region_get_rectangle(region_object->region, rectId, &int_rect);
273 :
274 3 : object_init_ex(return_value, php_cairo_get_rectangle_ce());
275 3 : rectangle_object = Z_CAIRO_RECTANGLE_P(return_value);
276 3 : cairo_rectangle_int_to_double(&int_rect, rectangle_object->rect);
277 : }
278 : /* }}} */
279 :
280 : /* {{{ proto bool \Cairo\Region::isEmpty()
281 : Checks whether region is empty. Returns TRUE if region is empty, FALSE if it isn't. */
282 2 : PHP_METHOD(Cairo_Region, isEmpty)
283 : {
284 : cairo_region_object *region_object;
285 :
286 2 : ZEND_PARSE_PARAMETERS_NONE();
287 :
288 2 : region_object = cairo_region_object_get(getThis());
289 1 : if (!region_object) {
290 0 : RETURN_THROWS();
291 : }
292 :
293 1 : RETVAL_BOOL(cairo_region_is_empty(region_object->region));
294 : }
295 : /* }}} */
296 :
297 : /* {{{ proto long \Cairo\Region::containsPoint(long x, long y)
298 : Checks whether (x, y) is contained in region. Returns TRUE if (x, y) is contained in region, FALSE if it is not. */
299 11 : PHP_METHOD(Cairo_Region, containsPoint)
300 : {
301 : long x, y;
302 : cairo_region_object *region_object;
303 :
304 11 : ZEND_PARSE_PARAMETERS_START(2, 2)
305 18 : Z_PARAM_LONG(x)
306 18 : Z_PARAM_LONG(y)
307 11 : ZEND_PARSE_PARAMETERS_END();
308 :
309 18 : region_object = cairo_region_object_get(getThis());
310 9 : if (!region_object) {
311 0 : RETURN_THROWS();
312 : }
313 :
314 9 : RETVAL_BOOL(cairo_region_contains_point(region_object->region, x, y));
315 : }
316 : /* }}} */
317 :
318 : /* {{{ proto \Cairo\Region\Overlap \Cairo\Region::containsRectangle(Cairo\Rectangle $rect)
319 : Checks whether rectangle is inside, outside or partially contained in region.
320 : Returns OVERLAP::IN if rectangle is entirely inside region,
321 : OVERLAP::OUT if rectangle is entirely outside region, or
322 : OVERLAP::PART if rectangle is partially inside and partially outside region. */
323 7 : PHP_METHOD(Cairo_Region, containsRectangle)
324 : {
325 : cairo_rectangle_object *rectangle_object;
326 : cairo_region_object *region_object;
327 : zval *rectangle_zval;
328 : zval region_overlap_case;
329 : cairo_rectangle_int_t int_rect;
330 :
331 7 : ZEND_PARSE_PARAMETERS_START(1, 1)
332 10 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
333 11 : ZEND_PARSE_PARAMETERS_END();
334 :
335 8 : region_object = cairo_region_object_get(getThis());
336 4 : if (!region_object) {
337 0 : RETURN_THROWS();
338 : }
339 :
340 4 : rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
341 4 : if (!rectangle_object) {
342 0 : RETURN_NULL();
343 : }
344 :
345 4 : int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
346 :
347 4 : region_overlap_case = php_enum_from_cairo_c_enum(
348 : ce_cairo_region_overlap,
349 4 : cairo_region_contains_rectangle(region_object->region, &int_rect)
350 : );
351 :
352 4 : if (Z_TYPE(region_overlap_case) == IS_OBJECT) {
353 8 : RETURN_ZVAL(®ion_overlap_case, 1, 1);
354 : }
355 : }
356 : /* }}} */
357 :
358 : /* {{{ proto long \Cairo\Region::equal(\Cairo\Region region)
359 : Compares whether region_a is equivalent to region_b. NULL as an argument is equal to itself, but not to any non-NULL region. */
360 7 : PHP_METHOD(Cairo_Region, equal)
361 : {
362 7 : zval *other_region = NULL;
363 : cairo_region_object *region_obj, *other_region_obj;
364 :
365 7 : ZEND_PARSE_PARAMETERS_START(1, 1)
366 12 : Z_PARAM_OBJECT_OF_CLASS_OR_NULL(other_region, ce_cairo_region)
367 8 : ZEND_PARSE_PARAMETERS_END();
368 :
369 10 : region_obj = cairo_region_object_get(getThis());
370 5 : if (!region_obj) {
371 0 : RETURN_THROWS();
372 : }
373 :
374 5 : if (other_region == NULL) {
375 1 : RETURN_TRUE;
376 : }
377 :
378 4 : other_region_obj = Z_CAIRO_REGION_P(other_region);
379 4 : RETVAL_BOOL(cairo_region_equal(region_obj->region, other_region_obj->region));
380 : }
381 : /* }}} */
382 :
383 : /* {{{ proto long \Cairo\Region::translate(long dx, long dy)
384 : Translates region by (dx, dy). */
385 5 : PHP_METHOD(Cairo_Region, translate)
386 : {
387 : long dx, dy;
388 : cairo_region_object *region_object;
389 :
390 5 : ZEND_PARSE_PARAMETERS_START(2, 2)
391 4 : Z_PARAM_LONG(dx)
392 4 : Z_PARAM_LONG(dy)
393 5 : ZEND_PARSE_PARAMETERS_END();
394 :
395 4 : region_object = cairo_region_object_get(getThis());
396 2 : if (!region_object) {
397 0 : RETURN_THROWS();
398 : }
399 :
400 2 : cairo_region_translate(region_object->region, dx, dy);
401 2 : if (php_cairo_throw_exception(cairo_region_status(region_object->region))) {
402 0 : RETURN_THROWS();
403 : }
404 : }
405 : /* }}} */
406 :
407 : /* {{{ proto \Cairo\Status \Cairo\Region::intersect(\Cairo\Region other_region)
408 : Computes the intersection with other_region and stores the result. */
409 4 : PHP_METHOD(Cairo_Region, intersect)
410 : {
411 : cairo_region_object *region_obj, *other_region_obj;
412 : zval *other_region;
413 : zval status_case;
414 :
415 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
416 6 : Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
417 6 : ZEND_PARSE_PARAMETERS_END();
418 :
419 4 : region_obj = cairo_region_object_get(getThis());
420 2 : if (!region_obj) {
421 0 : RETURN_THROWS();
422 : }
423 :
424 2 : other_region_obj = Z_CAIRO_REGION_P(other_region);
425 :
426 2 : status_case = php_enum_from_cairo_c_enum(
427 : ce_cairo_status,
428 2 : cairo_region_intersect(region_obj->region, other_region_obj->region)
429 : );
430 :
431 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
432 4 : RETURN_ZVAL(&status_case, 1, 1);
433 : }
434 : }
435 : /* }}} */
436 :
437 : /* {{{ proto \Cairo\Status \Cairo\Region::intersectRectangle(Cairo\Rectangle $rect)
438 : Computes the intersection with rectangle and stores the result. */
439 3 : PHP_METHOD(Cairo_Region, intersectRectangle)
440 : {
441 : cairo_rectangle_object *rectangle_object;
442 : cairo_region_object *region_object;
443 : zval *rectangle_zval;
444 : zval status_case;
445 : cairo_rectangle_int_t int_rect;
446 :
447 3 : ZEND_PARSE_PARAMETERS_START(1, 1)
448 4 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
449 4 : ZEND_PARSE_PARAMETERS_END();
450 :
451 2 : region_object = cairo_region_object_get(getThis());
452 1 : if (!region_object) {
453 0 : RETURN_THROWS();
454 : }
455 :
456 1 : rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
457 1 : if (!rectangle_object) {
458 0 : RETURN_NULL();
459 : }
460 :
461 1 : int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
462 :
463 1 : status_case = php_enum_from_cairo_c_enum(
464 : ce_cairo_status,
465 1 : cairo_region_intersect_rectangle(region_object->region, &int_rect)
466 : );
467 :
468 1 : if (Z_TYPE(status_case) == IS_OBJECT) {
469 2 : RETURN_ZVAL(&status_case, 1, 1);
470 : }
471 : }
472 : /* }}} */
473 :
474 : /* {{{ proto \Cairo\Status \Cairo\Region::subtract(\Cairo\Region other_region)
475 : Subtracts other_region and stores the result. */
476 4 : PHP_METHOD(Cairo_Region, subtract)
477 : {
478 : zval *other_region;
479 : cairo_region_object *region_obj, *other_region_obj;
480 : zval status_case;
481 :
482 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
483 6 : Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
484 6 : ZEND_PARSE_PARAMETERS_END();
485 :
486 4 : region_obj = cairo_region_object_get(getThis());
487 2 : if (!region_obj) {
488 0 : RETURN_THROWS();
489 : }
490 :
491 2 : other_region_obj = Z_CAIRO_REGION_P(other_region);
492 :
493 2 : status_case = php_enum_from_cairo_c_enum(
494 : ce_cairo_status,
495 2 : cairo_region_subtract(region_obj->region, other_region_obj->region)
496 : );
497 :
498 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
499 4 : RETURN_ZVAL(&status_case, 1, 1);
500 : }
501 : }
502 : /* }}} */
503 :
504 : /* {{{ proto \Cairo\Status \Cairo\Region::subtractRectangle(Cairo\Rectangle $rect)
505 : Subtracts rectangle from region and stores the result. */
506 3 : PHP_METHOD(Cairo_Region, subtractRectangle)
507 : {
508 : zval *rectangle_zval;
509 : cairo_rectangle_object *rectangle_object;
510 : cairo_region_object *region_object;
511 : zval status_case;
512 : cairo_rectangle_int_t int_rect;
513 :
514 3 : ZEND_PARSE_PARAMETERS_START(1, 1)
515 4 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
516 4 : ZEND_PARSE_PARAMETERS_END();
517 :
518 2 : region_object = cairo_region_object_get(getThis());
519 1 : if (!region_object) {
520 0 : RETURN_THROWS();
521 : }
522 :
523 1 : rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
524 1 : if (!rectangle_object) {
525 0 : RETURN_NULL();
526 : }
527 :
528 1 : int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
529 :
530 1 : status_case = php_enum_from_cairo_c_enum(
531 : ce_cairo_status,
532 1 : cairo_region_subtract_rectangle(region_object->region, &int_rect)
533 : );
534 :
535 1 : if (Z_TYPE(status_case) == IS_OBJECT) {
536 2 : RETURN_ZVAL(&status_case, 1, 1);
537 : }
538 : }
539 : /* }}} */
540 :
541 : /* {{{ proto \Cairo\Status \Cairo\Region::union(\Cairo\Region other_region)
542 : Computes the union with other_region and stores the result. */
543 4 : PHP_METHOD(Cairo_Region, union)
544 : {
545 : zval *other_region;
546 : cairo_region_object *region_obj, *other_region_obj;
547 : zval status_case;
548 :
549 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
550 6 : Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
551 6 : ZEND_PARSE_PARAMETERS_END();
552 :
553 4 : region_obj = cairo_region_object_get(getThis());
554 2 : if (!region_obj) {
555 0 : RETURN_THROWS();
556 : }
557 :
558 2 : other_region_obj = Z_CAIRO_REGION_P(other_region);
559 :
560 2 : status_case = php_enum_from_cairo_c_enum(
561 : ce_cairo_status,
562 2 : cairo_region_union(region_obj->region, other_region_obj->region)
563 : );
564 :
565 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
566 4 : RETURN_ZVAL(&status_case, 1, 1);
567 : }
568 : }
569 : /* }}} */
570 :
571 : /* {{{ proto \Cairo\Status \Cairo\Region::unionRectangle(Cairo\Rectangle $rect)
572 : Computes the union of region with rectangle and stores the result. */
573 4 : PHP_METHOD(Cairo_Region, unionRectangle)
574 : {
575 : zval *rectangle_zval;
576 : cairo_rectangle_object *rectangle_object;
577 : cairo_region_object *region_object;
578 : zval status_case;
579 : cairo_rectangle_int_t int_rect;
580 :
581 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
582 6 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
583 6 : ZEND_PARSE_PARAMETERS_END();
584 :
585 4 : region_object = cairo_region_object_get(getThis());
586 2 : if (!region_object) {
587 0 : RETURN_THROWS();
588 : }
589 :
590 2 : rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
591 2 : if (!rectangle_object) {
592 0 : RETURN_NULL();
593 : }
594 :
595 2 : int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
596 :
597 2 : status_case = php_enum_from_cairo_c_enum(
598 : ce_cairo_status,
599 2 : cairo_region_union_rectangle(region_object->region, &int_rect)
600 : );
601 :
602 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
603 4 : RETURN_ZVAL(&status_case, 1, 1);
604 : }
605 : }
606 : /* }}} */
607 :
608 : /* {{{ proto \Cairo\Status \Cairo\Region::xor(\Cairo\Region other_region)
609 : Computes the exclusive difference with other_region and stores the result.
610 : That is, region will be set to contain all areas that are either in region or in other_region, but not in both. */
611 4 : PHP_METHOD(Cairo_Region, xor)
612 : {
613 : zval *other_region;
614 : cairo_region_object *region_obj, *other_region_obj;
615 : zval status_case;
616 :
617 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
618 6 : Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
619 6 : ZEND_PARSE_PARAMETERS_END();
620 :
621 4 : region_obj = cairo_region_object_get(getThis());
622 2 : if (!region_obj) {
623 0 : RETURN_THROWS();
624 : }
625 :
626 2 : other_region_obj = Z_CAIRO_REGION_P(other_region);
627 :
628 2 : status_case = php_enum_from_cairo_c_enum(
629 : ce_cairo_status,
630 2 : cairo_region_xor(region_obj->region, other_region_obj->region)
631 : );
632 :
633 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
634 4 : RETURN_ZVAL(&status_case, 1, 1);
635 : }
636 : }
637 : /* }}} */
638 :
639 : /* {{{ proto \Cairo\Status \Cairo\Region::xorRectangle(Cairo\Rectangle $rect)
640 : Computes the exclusive difference of region with rectangle and stores the result.
641 : That is, region will be set to contain all areas that are either in region or in rectangle, but not in both. */
642 4 : PHP_METHOD(Cairo_Region, xorRectangle)
643 : {
644 : zval *rectangle_zval;
645 : cairo_rectangle_object *rectangle_object;
646 : cairo_region_object *region_object;
647 : zval status_case;
648 : cairo_rectangle_int_t int_rect;
649 :
650 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
651 6 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
652 6 : ZEND_PARSE_PARAMETERS_END();
653 :
654 4 : region_object = cairo_region_object_get(getThis());
655 2 : if (!region_object) {
656 0 : RETURN_THROWS();
657 : }
658 :
659 2 : rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
660 2 : if (!rectangle_object) {
661 0 : RETURN_NULL();
662 : }
663 :
664 2 : int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
665 :
666 2 : status_case = php_enum_from_cairo_c_enum(
667 : ce_cairo_status,
668 2 : cairo_region_xor_rectangle(region_object->region, &int_rect)
669 : );
670 :
671 2 : if (Z_TYPE(status_case) == IS_OBJECT) {
672 4 : RETURN_ZVAL(&status_case, 1, 1);
673 : }
674 : }
675 : /* }}} */
676 :
677 :
678 : /* ----------------------------------------------------------------
679 : \Cairo\Region Definition and registration
680 : ------------------------------------------------------------------*/
681 :
682 :
683 : /* {{{ PHP_MINIT_FUNCTION */
684 424 : PHP_MINIT_FUNCTION(cairo_region)
685 : {
686 424 : memcpy(
687 : &cairo_region_object_handlers,
688 : zend_get_std_object_handlers(),
689 : sizeof(zend_object_handlers)
690 : );
691 :
692 424 : cairo_region_object_handlers.offset = XtOffsetOf(cairo_region_object, std);
693 424 : cairo_region_object_handlers.free_obj = cairo_region_free_obj;
694 424 : cairo_region_object_handlers.clone_obj = cairo_region_clone_obj;
695 :
696 424 : ce_cairo_region = register_class_Cairo_Region();
697 424 : ce_cairo_region->create_object = cairo_region_create_object;
698 :
699 : /* Region\Overlap */
700 424 : ce_cairo_region_overlap = register_class_Cairo_Region_Overlap();
701 :
702 424 : return SUCCESS;
703 : }
|