[perl-Cairo] Wrap the region API



commit 913d48d69495982c4edcf572afe579635b9258e0
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Sun May 1 20:00:50 2011 +0200

    Wrap the region API

 Cairo.xs        |   56 +++++++++++++++++++++++++++++++++++
 CairoRegion.xs  |   88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MANIFEST        |    2 +
 Makefile.PL     |   27 ++++++++++++++---
 cairo-perl.h    |    9 +++++
 t/CairoRegion.t |   46 ++++++++++++++++++++++++++++
 6 files changed, 223 insertions(+), 5 deletions(-)
---
diff --git a/Cairo.xs b/Cairo.xs
index 1dde8f6..3174f51 100644
--- a/Cairo.xs
+++ b/Cairo.xs
@@ -278,6 +278,62 @@ SvCairoRectangle (SV *sv)
 
 /* ------------------------------------------------------------------------- */
 
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
+
+SV *
+newSVCairoRectangleInt (cairo_rectangle_int_t *rectangle)
+{
+	HV *hv;
+
+	if (!rectangle)
+		return &PL_sv_undef;
+
+	hv = newHV ();
+
+	hv_store (hv, "x", 1, newSViv (rectangle->x), 0);
+	hv_store (hv, "y", 1, newSViv (rectangle->y), 0);
+	hv_store (hv, "width", 5, newSViv (rectangle->width), 0);
+	hv_store (hv, "height", 6, newSViv (rectangle->height), 0);
+
+	return newRV_noinc ((SV *) hv);
+}
+
+cairo_rectangle_int_t *
+SvCairoRectangleInt (SV *sv)
+{
+	HV *hv;
+	SV **value;
+	cairo_rectangle_int_t *rectangle;
+
+	if (!cairo_perl_sv_is_hash_ref (sv))
+		croak ("cairo_rectangle_int_t must be a hash reference");
+
+	hv = (HV *) SvRV (sv);
+	rectangle = cairo_perl_alloc_temp (sizeof (cairo_rectangle_t));
+
+	value = hv_fetchs (hv, "x", 0);
+	if (value && SvOK (*value))
+		rectangle->x = SvIV (*value);
+
+	value = hv_fetchs (hv, "y", 0);
+	if (value && SvOK (*value))
+		rectangle->y = SvIV (*value);
+
+	value = hv_fetchs (hv, "width", 0);
+	if (value && SvOK (*value))
+		rectangle->width = SvIV (*value);
+
+	value = hv_fetchs (hv, "height", 0);
+	if (value && SvOK (*value))
+		rectangle->height = SvIV (*value);
+
+	return rectangle;
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 8, 0)
 
 SV *
diff --git a/CairoRegion.xs b/CairoRegion.xs
new file mode 100644
index 0000000..b8afd96
--- /dev/null
+++ b/CairoRegion.xs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011 by the cairo perl team (see the file README)
+ *
+ * Licensed under the LGPL, see LICENSE file for more information.
+ *
+ */
+
+#include <cairo-perl.h>
+
+MODULE = Cairo::Region	PACKAGE = Cairo::Region PREFIX = cairo_region_
+
+void DESTROY (cairo_region_t * region);
+    CODE:
+	cairo_region_destroy (region);
+
+# cairo_region_t * cairo_region_create_rectangles (const cairo_rectangle_int_t *rects, int count);
+cairo_region_t_noinc *
+cairo_region_create (class, ...)
+    PREINIT:
+	cairo_rectangle_int_t *rects;
+	int i, count;
+    CODE:
+	if (items == 1) {
+		RETVAL = cairo_region_create ();
+	} else if (items == 2) {
+		RETVAL = cairo_region_create_rectangle (SvCairoRectangleInt (ST (1)));
+	} else {
+		count = items - 1;
+		Newz (0, rects, count, cairo_rectangle_int_t);
+		for (i = 1; i < items; i++) {
+			rects[i-1] = *SvCairoRectangleInt (ST (i));
+		}
+		RETVAL = cairo_region_create_rectangles (rects, count);
+	}
+    OUTPUT:
+	RETVAL
+
+cairo_status_t cairo_region_status (const cairo_region_t *region);
+
+# void cairo_region_get_extents (const cairo_region_t *region, cairo_rectangle_int_t *extents);
+cairo_rectangle_int_t *
+cairo_region_get_extents (const cairo_region_t *region)
+    PREINIT:
+	cairo_rectangle_int_t rect;
+    CODE:
+	cairo_region_get_extents (region, &rect);
+	RETVAL = &rect;
+    OUTPUT:
+	RETVAL
+
+int cairo_region_num_rectangles (const cairo_region_t *region);
+
+# void cairo_region_get_rectangle (const cairo_region_t *region, int nth, cairo_rectangle_int_t *rectangle);
+cairo_rectangle_int_t *
+cairo_region_get_rectangle (const cairo_region_t *region, int nth)
+    PREINIT:
+	cairo_rectangle_int_t rect;
+    CODE:
+	cairo_region_get_rectangle (region, nth, &rect);
+	RETVAL = &rect;
+    OUTPUT:
+	RETVAL
+
+cairo_bool_t cairo_region_is_empty (const cairo_region_t *region);
+
+cairo_bool_t cairo_region_contains_point (const cairo_region_t *region, int x, int y);
+
+cairo_region_overlap_t cairo_region_contains_rectangle (const cairo_region_t *region, const cairo_rectangle_int_t *rectangle);
+
+cairo_bool_t cairo_region_equal (const cairo_region_t *a, const cairo_region_t *b);
+
+void cairo_region_translate (cairo_region_t *region, int dx, int dy);
+
+cairo_status_t cairo_region_intersect (cairo_region_t *dst, const cairo_region_t *other);
+
+cairo_status_t cairo_region_intersect_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rectangle);
+
+cairo_status_t cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other);
+
+cairo_status_t cairo_region_subtract_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rectangle);
+
+cairo_status_t cairo_region_union (cairo_region_t *dst, const cairo_region_t *other);
+
+cairo_status_t cairo_region_union_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rectangle);
+
+cairo_status_t cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other);
+
+cairo_status_t cairo_region_xor_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rectangle);
diff --git a/MANIFEST b/MANIFEST
index dc8a6c0..fed11f7 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -7,6 +7,7 @@ CairoFt.xs
 CairoMatrix.xs
 CairoPath.xs
 CairoPattern.xs
+CairoRegion.xs
 CairoSurface.xs
 ChangeLog.pre-git
 doctypes
@@ -43,5 +44,6 @@ t/CairoFt.t
 t/CairoMatrix.t
 t/CairoPath.t
 t/CairoPattern.t
+t/CairoRegion.t
 t/CairoSurface.t
 TODO
diff --git a/Makefile.PL b/Makefile.PL
index b99e67c..1a7f2f8 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -65,14 +65,16 @@ my %objects = (
 	'cairo_t *'             => 'Cairo::Context',
 	'cairo_font_face_t *'   => 'Cairo::FontFace',
 	'cairo_pattern_t *'     => 'Cairo::Pattern',
+	'cairo_region_t *'      => 'Cairo::Region',
 	'cairo_scaled_font_t *' => 'Cairo::ScaledFont',
 	'cairo_surface_t *'     => 'Cairo::Surface',
 );
 
 my %structs = (
-	'cairo_font_options_t *' => 'Cairo::FontOptions',
-	'cairo_matrix_t *'       => 'Cairo::Matrix',
-	'cairo_rectangle_t *'    => 'Cairo::Rectangle',
+	'cairo_font_options_t *'  => 'Cairo::FontOptions',
+	'cairo_matrix_t *'        => 'Cairo::Matrix',
+	'cairo_rectangle_t *'     => 'Cairo::Rectangle',
+	'cairo_rectangle_int_t *' => 'Cairo::RectangleInt',
 );
 
 my %enums = (
@@ -347,16 +349,27 @@ if ($have_cairo_1_10) {
 		CAIRO_PDF_VERSION_1_4
 		CAIRO_PDF_VERSION_1_5
 	/];
+
+	$enums{cairo_region_overlap_t} = [qw/
+		CAIRO_REGION_OVERLAP_
+		CAIRO_REGION_OVERLAP_IN
+		CAIRO_REGION_OVERLAP_OUT
+		CAIRO_REGION_OVERLAP_PART
+	/];
 } else {
 	$enums{cairo_pdf_version_t} = [];
+	$enums{cairo_region_overlap_t} = [];
 }
 
 # --------------------------------------------------------------------------- #
 
-my %object_guards = ();
+my %object_guards = (
+	cairo_region_t => '#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)',
+);
 
 my %struct_guards = (
-	cairo_rectangle_t => '#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 4, 0)',
+	cairo_rectangle_t     => '#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 4, 0)',
+	cairo_rectangle_int_t => '#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)',
 );
 
 my %enum_guards = (
@@ -379,6 +392,10 @@ my @xs_files = qw(
 	CairoSurface.xs
 );
 
+if ($have_cairo_1_10) {
+	push @xs_files, 'CairoRegion.xs';
+}
+
 my $have_cairo_ft = !system qw(pkg-config --exists --silence-errors cairo-ft);
 if ($have_cairo_ft) {
 	print "Compiling Cairo with FreeType support\n";
diff --git a/cairo-perl.h b/cairo-perl.h
index c327087..18b6074 100644
--- a/cairo-perl.h
+++ b/cairo-perl.h
@@ -76,6 +76,15 @@ cairo_rectangle_t * SvCairoRectangle (SV *sv);
 
 #endif
 
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
+
+#undef newSVCairoRectangleInt
+#undef SvCairoRectangleInt
+SV * newSVCairoRectangleInt (cairo_rectangle_int_t *rectangle);
+cairo_rectangle_int_t * SvCairoRectangleInt (SV *sv);
+
+#endif
+
 /*
  * special treatment for surfaces
  */
diff --git a/t/CairoRegion.t b/t/CairoRegion.t
new file mode 100644
index 0000000..1ea8770
--- /dev/null
+++ b/t/CairoRegion.t
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2011 by the cairo perl team (see the file README)
+#
+# Licensed under the LGPL, see LICENSE file for more information.
+#
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use Cairo;
+
+unless (Cairo::VERSION >= Cairo::VERSION_ENCODE (1, 10, 0)) {
+	plan skip_all => 'need cairo 1.10';
+}
+
+plan tests => 19;
+
+my $region = Cairo::Region->create;
+isa_ok ($region, 'Cairo::Region');
+
+$region = Cairo::Region->create ({x=>10, y=>10, width=>5, height=>5});
+isa_ok ($region, 'Cairo::Region');
+
+$region = Cairo::Region->create ({x=>10, y=>10, width=>5, height=>5},
+                                 {x=>0, y=>0, width=>5, height=>5});
+isa_ok ($region, 'Cairo::Region');
+
+is ($region->status, 'success');
+is_deeply ($region->get_extents, {x=>0, y=>0, width=>15, height=>15});
+is ($region->num_rectangles, 2);
+is_deeply ($region->get_rectangle (1), {x=>10, y=>10, width=>5, height=>5});
+ok (!$region->is_empty);
+ok ($region->contains_point (12, 13));
+is ($region->contains_rectangle ({x=>7, y=>7, width=>5, height=>5}), 'part');
+ok ($region->equal ($region));
+$region->translate (0, 0);
+
+my $other = {x=>0, y=>0, width=>15, height=>15};
+foreach my $method (qw/intersect subtract union xor/) {
+  is ($region->$method ($region), 'success', $method);
+  my $rect_method = $method . '_rectangle';
+  is ($region->$rect_method ($other), 'success', $rect_method);
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]