Subversion Repositories Scribus

Rev

Rev 14952 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
14952 fschmid 1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2005 Red Hat, Inc.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18122 mrdocs 16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14952 fschmid 17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is Red Hat, Inc.
32
 *
33
 * Contributor(s):
34
 *      Owen Taylor <otaylor@redhat.com>
35
 *      Vladimir Vukicevic <vladimir@pobox.com>
36
 *      Søren Sandmann <sandmann@daimi.au.dk>
37
 */
38
 
39
#include "cairoint.h"
40
 
41
#include "cairo-region-private.h"
42
 
43
/* XXX need to update pixman headers to be const as appropriate */
44
#define CONST_CAST (pixman_region32_t *)
45
 
46
static const cairo_region_t _cairo_region_nil = {
47
    CAIRO_REFERENCE_COUNT_INVALID,      /* ref_count */
48
    CAIRO_STATUS_NO_MEMORY,             /* status */
49
};
50
 
51
/**
52
 * _cairo_region_set_error:
53
 * @region: a region
54
 * @status: a status value indicating an error
55
 *
56
 * Atomically sets region->status to @status and calls _cairo_error;
57
 * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
58
 * status values.
59
 *
60
 * All assignments of an error status to region->status should happen
61
 * through _cairo_region_set_error(). Note that due to the nature of
62
 * the atomic operation, it is not safe to call this function on the
63
 * nil objects.
64
 *
65
 * The purpose of this function is to allow the user to set a
66
 * breakpoint in _cairo_error() to generate a stack trace for when the
67
 * user causes cairo to detect an error.
68
 *
69
 * Return value: the error status.
70
 **/
71
static cairo_status_t
72
_cairo_region_set_error (cairo_region_t *region,
73
                        cairo_status_t status)
74
{
75
    if (! _cairo_status_is_error (status))
76
        return status;
77
 
78
    /* Don't overwrite an existing error. This preserves the first
79
     * error, which is the most significant. */
80
    _cairo_status_set_error (&region->status, status);
81
 
82
    return _cairo_error (status);
83
}
84
 
85
void
86
_cairo_region_init (cairo_region_t *region)
87
{
88
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
89
 
90
    region->status = CAIRO_STATUS_SUCCESS;
91
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
92
    pixman_region32_init (&region->rgn);
93
}
94
 
95
void
96
_cairo_region_init_rectangle (cairo_region_t *region,
97
                              const cairo_rectangle_int_t *rectangle)
98
{
99
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
100
 
101
    region->status = CAIRO_STATUS_SUCCESS;
102
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
103
    pixman_region32_init_rect (&region->rgn,
104
                               rectangle->x, rectangle->y,
105
                               rectangle->width, rectangle->height);
106
}
107
 
108
void
109
_cairo_region_fini (cairo_region_t *region)
110
{
111
    assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
112
    pixman_region32_fini (&region->rgn);
113
    VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
114
}
115
 
116
/**
117
 * cairo_region_create:
118
 *
119
 * Allocates a new empty region object.
120
 *
121
 * Return value: A newly allocated #cairo_region_t. Free with
122
 *   cairo_region_destroy(). This function always returns a
123
 *   valid pointer; if memory cannot be allocated, then a special
124
 *   error object is returned where all operations on the object do nothing.
125
 *   You can check for this with cairo_region_status().
126
 *
127
 * Since: 1.10
128
 **/
129
cairo_region_t *
130
cairo_region_create (void)
131
{
132
    cairo_region_t *region;
133
 
134
    region = _cairo_malloc (sizeof (cairo_region_t));
135
    if (region == NULL)
136
        return (cairo_region_t *) &_cairo_region_nil;
137
 
138
    region->status = CAIRO_STATUS_SUCCESS;
139
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
140
 
141
    pixman_region32_init (&region->rgn);
142
 
143
    return region;
144
}
145
slim_hidden_def (cairo_region_create);
146
 
147
cairo_region_t *
148
cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
149
                                int count)
150
{
151
    pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
152
    pixman_box32_t *pboxes = stack_pboxes;
153
    cairo_region_t *region;
154
    int i;
155
 
156
    region = _cairo_malloc (sizeof (cairo_region_t));
157
    if (unlikely (region == NULL)) {
158
        _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
159
        return (cairo_region_t *) &_cairo_region_nil;
160
    }
161
 
162
    if (count > ARRAY_LENGTH (stack_pboxes)) {
163
        pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
164
        if (unlikely (pboxes == NULL)) {
165
            free (region);
166
            _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
167
            return (cairo_region_t *) &_cairo_region_nil;
168
        }
169
    }
170
 
171
    for (i = 0; i < count; i++) {
172
        pboxes[i].x1 = rects[i].x;
173
        pboxes[i].y1 = rects[i].y;
174
        pboxes[i].x2 = rects[i].x + rects[i].width;
175
        pboxes[i].y2 = rects[i].y + rects[i].height;
176
    }
177
 
178
    i = pixman_region32_init_rects (&region->rgn, pboxes, count);
179
 
180
    if (pboxes != stack_pboxes)
181
        free (pboxes);
182
 
183
    if (unlikely (i == 0)) {
184
        free (region);
185
        _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
186
        return (cairo_region_t *) &_cairo_region_nil;
187
    }
188
 
189
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
190
    region->status = CAIRO_STATUS_SUCCESS;
191
    return region;
192
}
193
slim_hidden_def (cairo_region_create_rectangles);
194
 
195
/**
196
 * cairo_region_create_rectangle:
197
 * @rectangle: a #cairo_rectangle_int_t
198
 *
199
 * Allocates a new region object containing @rectangle.
200
 *
201
 * Return value: A newly allocated #cairo_region_t. Free with
202
 *   cairo_region_destroy(). This function always returns a
203
 *   valid pointer; if memory cannot be allocated, then a special
204
 *   error object is returned where all operations on the object do nothing.
205
 *   You can check for this with cairo_region_status().
206
 *
207
 * Since: 1.10
208
 **/
209
cairo_region_t *
210
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
211
{
212
    cairo_region_t *region;
213
 
214
    region = _cairo_malloc (sizeof (cairo_region_t));
215
    if (unlikely (region == NULL))
216
        return (cairo_region_t *) &_cairo_region_nil;
217
 
218
    region->status = CAIRO_STATUS_SUCCESS;
219
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
220
 
221
    pixman_region32_init_rect (&region->rgn,
222
                               rectangle->x, rectangle->y,
223
                               rectangle->width, rectangle->height);
224
 
225
    return region;
226
}
227
slim_hidden_def (cairo_region_create_rectangle);
228
 
229
/**
230
 * cairo_region_copy:
231
 * @original: a #cairo_region_t
232
 *
233
 * Allocates a new region object copying the area from @original.
234
 *
235
 * Return value: A newly allocated #cairo_region_t. Free with
236
 *   cairo_region_destroy(). This function always returns a
237
 *   valid pointer; if memory cannot be allocated, then a special
238
 *   error object is returned where all operations on the object do nothing.
239
 *   You can check for this with cairo_region_status().
240
 *
241
 * Since: 1.10
242
 **/
243
cairo_region_t *
244
cairo_region_copy (const cairo_region_t *original)
245
{
246
    cairo_region_t *copy;
247
 
248
    if (original != NULL && original->status)
249
        return (cairo_region_t *) &_cairo_region_nil;
250
 
251
    copy = cairo_region_create ();
252
    if (unlikely (copy->status))
253
        return copy;
254
 
255
    if (original != NULL &&
256
        ! pixman_region32_copy (&copy->rgn, CONST_CAST &original->rgn))
257
    {
258
        cairo_region_destroy (copy);
259
        return (cairo_region_t *) &_cairo_region_nil;
260
    }
261
 
262
    return copy;
263
}
264
slim_hidden_def (cairo_region_copy);
265
 
266
/**
267
 * cairo_region_reference:
268
 * @region: a #cairo_region_t
269
 *
270
 * Increases the reference count on @region by one. This prevents
271
 * @region from being destroyed until a matching call to
272
 * cairo_region_destroy() is made.
273
 *
274
 * Return value: the referenced #cairo_region_t.
275
 *
276
 * Since: 1.10
277
 **/
278
cairo_region_t *
279
cairo_region_reference (cairo_region_t *region)
280
{
281
    if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&region->ref_count))
282
        return NULL;
283
 
284
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
285
 
286
    _cairo_reference_count_inc (&region->ref_count);
287
    return region;
288
}
289
slim_hidden_def (cairo_region_reference);
290
 
291
/**
292
 * cairo_region_destroy:
293
 * @region: a #cairo_region_t
294
 *
295
 * Destroys a #cairo_region_t object created with
296
 * cairo_region_create(), cairo_region_copy(), or
297
 * or cairo_region_create_rectangle().
298
 *
299
 * Since: 1.10
300
 **/
301
void
302
cairo_region_destroy (cairo_region_t *region)
303
{
304
    if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&region->ref_count))
305
        return;
306
 
307
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
308
 
309
    if (! _cairo_reference_count_dec_and_test (&region->ref_count))
310
        return;
311
 
312
    _cairo_region_fini (region);
313
    free (region);
314
}
315
slim_hidden_def (cairo_region_destroy);
316
 
317
/**
318
 * cairo_region_num_rectangles:
319
 * @region: a #cairo_region_t
320
 *
321
 * Returns the number of rectangles contained in @region.
322
 *
323
 * Return value: The number of rectangles contained in @region.
324
 *
325
 * Since: 1.10
326
 **/
327
int
328
cairo_region_num_rectangles (const cairo_region_t *region)
329
{
330
    if (region->status)
331
        return 0;
332
 
333
    return pixman_region32_n_rects (CONST_CAST &region->rgn);
334
}
335
slim_hidden_def (cairo_region_num_rectangles);
336
 
337
/**
338
 * cairo_region_get_rectangle:
339
 * @region: a #cairo_region_t
340
 * @nth: a number indicating which rectangle should be returned
341
 * @rectangle: return location for a #cairo_rectangle_int_t
342
 *
343
 * Stores the @nth rectangle from the region in @rectangle.
344
 *
345
 * Since: 1.10
346
 **/
347
void
348
cairo_region_get_rectangle (const cairo_region_t *region,
349
                            int nth,
350
                            cairo_rectangle_int_t *rectangle)
351
{
352
    pixman_box32_t *pbox;
353
 
354
    if (region->status) {
355
        rectangle->x = rectangle->y = 0;
356
        rectangle->width = rectangle->height = 0;
357
        return;
358
    }
359
 
360
    pbox = pixman_region32_rectangles (CONST_CAST &region->rgn, NULL) + nth;
361
 
362
    rectangle->x = pbox->x1;
363
    rectangle->y = pbox->y1;
364
    rectangle->width = pbox->x2 - pbox->x1;
365
    rectangle->height = pbox->y2 - pbox->y1;
366
}
367
slim_hidden_def (cairo_region_get_rectangle);
368
 
369
/**
370
 * cairo_region_get_extents:
371
 * @region: a #cairo_region_t
372
 * @rectangle: rectangle into which to store the extents
373
 *
374
 * Gets the bounding rectangle of @region as a #cairo_rectangle_int_t
375
 *
376
 * Since: 1.10
377
 **/
378
void
379
cairo_region_get_extents (const cairo_region_t *region,
380
                          cairo_rectangle_int_t *extents)
381
{
382
    pixman_box32_t *pextents;
383
 
384
    if (region->status) {
385
        extents->x = extents->y = 0;
386
        extents->width = extents->height = 0;
387
        return;
388
    }
389
 
390
    pextents = pixman_region32_extents (CONST_CAST &region->rgn);
391
 
392
    extents->x = pextents->x1;
393
    extents->y = pextents->y1;
394
    extents->width = pextents->x2 - pextents->x1;
395
    extents->height = pextents->y2 - pextents->y1;
396
}
397
slim_hidden_def (cairo_region_get_extents);
398
 
399
/**
400
 * cairo_region_status:
401
 * @region: a #cairo_region_t
402
 *
403
 * Checks whether an error has previous occured for this
404
 * region object.
405
 *
406
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
407
 *
408
 * Since: 1.10
409
 **/
410
cairo_status_t
411
cairo_region_status (const cairo_region_t *region)
412
{
413
    return region->status;
414
}
415
slim_hidden_def (cairo_region_status);
416
 
417
/**
418
 * cairo_region_subtract:
419
 * @dst: a #cairo_region_t
420
 * @other: another #cairo_region_t
421
 *
422
 * Subtracts @other from @dst and places the result in @dst
423
 *
424
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
425
 *
426
 * Since: 1.10
427
 **/
428
cairo_status_t
429
cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other)
430
{
431
    if (dst->status)
432
        return dst->status;
433
 
434
    if (other->status)
435
        return _cairo_region_set_error (dst, other->status);
436
 
437
    if (! pixman_region32_subtract (&dst->rgn,
438
                                    &dst->rgn,
439
                                    CONST_CAST &other->rgn))
440
    {
441
        return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
442
    }
443
 
444
    return CAIRO_STATUS_SUCCESS;
445
}
446
slim_hidden_def (cairo_region_subtract);
447
 
448
/**
449
 * cairo_region_subtract_rectangle:
450
 * @dst: a #cairo_region_t
451
 * @rectangle: a #cairo_rectangle_int_t
452
 *
453
 * Subtracts @rectangle from @dst and places the result in @dst
454
 *
455
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
456
 *
457
 * Since: 1.10
458
 **/
459
cairo_status_t
460
cairo_region_subtract_rectangle (cairo_region_t *dst,
461
                                 const cairo_rectangle_int_t *rectangle)
462
{
463
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
464
    pixman_region32_t region;
465
 
466
    if (dst->status)
467
        return dst->status;
468
 
469
    pixman_region32_init_rect (&region,
470
                               rectangle->x, rectangle->y,
471
                               rectangle->width, rectangle->height);
472
 
473
    if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &region))
474
        status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
475
 
476
    pixman_region32_fini (&region);
477
 
478
    return status;
479
}
480
slim_hidden_def (cairo_region_subtract_rectangle);
481
 
482
/**
483
 * cairo_region_intersect:
484
 * @dst: a #cairo_region_t
485
 * @other: another #cairo_region_t
486
 *
487
 * Computes the intersection of @dst with @other and places the result in @dst
488
 *
489
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
490
 *
491
 * Since: 1.10
492
 **/
493
cairo_status_t
494
cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other)
495
{
496
    if (dst->status)
497
        return dst->status;
498
 
499
    if (other->status)
500
        return _cairo_region_set_error (dst, other->status);
501
 
502
    if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn))
503
        return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
504
 
505
    return CAIRO_STATUS_SUCCESS;
506
}
507
slim_hidden_def (cairo_region_intersect);
508
 
509
/**
510
 * cairo_region_intersect_rectangle:
511
 * @dst: a #cairo_region_t
512
 * @rectangle: a #cairo_rectangle_int_t
513
 *
514
 * Computes the intersection of @dst with @rectangle and places the
515
 * result in @dst
516
 *
517
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
518
 *
519
 * Since: 1.10
520
 **/
521
cairo_status_t
522
cairo_region_intersect_rectangle (cairo_region_t *dst,
523
                                  const cairo_rectangle_int_t *rectangle)
524
{
525
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
526
    pixman_region32_t region;
527
 
528
    if (dst->status)
529
        return dst->status;
530
 
531
    pixman_region32_init_rect (&region,
532
                               rectangle->x, rectangle->y,
533
                               rectangle->width, rectangle->height);
534
 
535
    if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &region))
536
        status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
537
 
538
    pixman_region32_fini (&region);
539
 
540
    return status;
541
}
542
slim_hidden_def (cairo_region_intersect_rectangle);
543
 
544
/**
545
 * cairo_region_union:
546
 * @dst: a #cairo_region_t
547
 * @other: another #cairo_region_t
548
 *
549
 * Computes the union of @dst with @other and places the result in @dst
550
 *
551
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
552
 *
553
 * Since: 1.10
554
 **/
555
cairo_status_t
556
cairo_region_union (cairo_region_t *dst,
557
                    cairo_region_t *other)
558
{
559
    if (dst->status)
560
        return dst->status;
561
 
562
    if (other->status)
563
        return _cairo_region_set_error (dst, other->status);
564
 
565
    if (! pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn))
566
        return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
567
 
568
    return CAIRO_STATUS_SUCCESS;
569
}
570
slim_hidden_def (cairo_region_union);
571
 
572
/**
573
 * cairo_region_union_rectangle:
574
 * @dst: a #cairo_region_t
575
 * @rectangle: a #cairo_rectangle_int_t
576
 *
577
 * Computes the union of @dst with @rectangle and places the result in @dst.
578
 *
579
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
580
 *
581
 * Since: 1.10
582
 **/
583
cairo_status_t
584
cairo_region_union_rectangle (cairo_region_t *dst,
585
                              const cairo_rectangle_int_t *rectangle)
586
{
587
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
588
    pixman_region32_t region;
589
 
590
    if (dst->status)
591
        return dst->status;
592
 
593
    pixman_region32_init_rect (&region,
594
                               rectangle->x, rectangle->y,
595
                               rectangle->width, rectangle->height);
596
 
597
    if (! pixman_region32_union (&dst->rgn, &dst->rgn, &region))
598
        status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
599
 
600
    pixman_region32_fini (&region);
601
 
602
    return status;
603
}
604
slim_hidden_def (cairo_region_union_rectangle);
605
 
606
/**
607
 * cairo_region_is_empty:
608
 * @region: a #cairo_region_t
609
 *
610
 * Checks whether @region is empty.
611
 *
612
 * Return value: %TRUE if @region is empty, %FALSE if it isn't.
613
 *
614
 * Since: 1.10
615
 **/
616
cairo_bool_t
617
cairo_region_is_empty (const cairo_region_t *region)
618
{
619
    if (region->status)
620
        return TRUE;
621
 
622
    return ! pixman_region32_not_empty (CONST_CAST &region->rgn);
623
}
624
slim_hidden_def (cairo_region_is_empty);
625
 
626
/**
627
 * cairo_region_translate:
628
 * @region: a #cairo_region_t
629
 * @dx: Amount to translate in the x direction
630
 * @dy: Amount to translate in the y direction
631
 *
632
 * Translates @region by (@dx, @dy).
633
 *
634
 * Since: 1.10
635
 **/
636
void
637
cairo_region_translate (cairo_region_t *region,
638
                        int dx, int dy)
639
{
640
    if (region->status)
641
        return;
642
 
643
    pixman_region32_translate (&region->rgn, dx, dy);
644
}
645
slim_hidden_def (cairo_region_translate);
646
 
647
/**
648
 * cairo_region_contains_rectangle:
649
 * @region: a #cairo_region_t
650
 * @rectangle: a #cairo_rectangle_int_t
651
 *
652
 * Checks whether @rectangle is inside, outside or partially contained
653
 * in @region
654
 *
655
 * Return value:
656
 *   %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region,
657
 *   %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or
658
 *   %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region.
659
 *
660
 * Since: 1.10
661
 **/
662
cairo_region_overlap_t
663
cairo_region_contains_rectangle (const cairo_region_t *region,
664
                                 const cairo_rectangle_int_t *rectangle)
665
{
666
    pixman_box32_t pbox;
667
    pixman_region_overlap_t poverlap;
668
 
669
    if (region->status)
670
        return CAIRO_REGION_OVERLAP_OUT;
671
 
672
    pbox.x1 = rectangle->x;
673
    pbox.y1 = rectangle->y;
674
    pbox.x2 = rectangle->x + rectangle->width;
675
    pbox.y2 = rectangle->y + rectangle->height;
676
 
677
    poverlap = pixman_region32_contains_rectangle (CONST_CAST &region->rgn,
678
                                                   &pbox);
679
    switch (poverlap) {
680
    default:
681
    case PIXMAN_REGION_OUT:  return CAIRO_REGION_OVERLAP_OUT;
682
    case PIXMAN_REGION_IN:   return CAIRO_REGION_OVERLAP_IN;
683
    case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART;
684
    }
685
}
686
slim_hidden_def (cairo_region_contains_rectangle);
687
 
688
/**
689
 * cairo_region_contains_point:
690
 * @region: a #cairo_region_t
691
 * @x: the x coordinate of a point
692
 * @y: the y coordinate of a point
693
 *
694
 * Checks whether (@x, @y) is contained in @region.
695
 *
696
 * Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not.
697
 *
698
 * Since: 1.10
699
 **/
700
cairo_bool_t
701
cairo_region_contains_point (const cairo_region_t *region,
702
                             int x, int y)
703
{
704
    pixman_box32_t box;
705
 
706
    if (region->status)
707
        return FALSE;
708
 
709
    return pixman_region32_contains_point (CONST_CAST &region->rgn, x, y, &box);
710
}
711
slim_hidden_def (cairo_region_contains_point);
712
 
713
/**
714
 * cairo_region_equal:
715
 * @region_a: a #cairo_region_t
716
 * @region_b: a #cairo_region_t
717
 *
718
 * Compares whether region_a is equivalent to region_b.
719
 *
720
 * Return value: %TRUE if both regions contained the same coverage,
721
 * %FALSE if it is not.
722
 *
723
 * Since: 1.10
724
 **/
725
cairo_bool_t
726
cairo_region_equal (const cairo_region_t *a,
727
                    const cairo_region_t *b)
728
{
729
    /* error objects are never equal */
730
    if ((a != NULL && a->status) || (b != NULL && b->status))
731
        return FALSE;
732
 
733
    if (a == b)
734
        return TRUE;
735
 
736
    if (a == NULL || b == NULL)
737
        return FALSE;
738
 
739
    return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn);
740
}
741
slim_hidden_def (cairo_region_equal);