[perl-Cairo] Wrap the recording surface API



commit 8b3bc6c20181923cbeea00888318c9b2aade7d08
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Sun May 1 17:20:48 2011 +0200

    Wrap the recording surface API
    
    Based on a patch by Ross Alexander.

 Cairo.xs          |   43 +++++++++++++++++++++++++++++++++++++++++++
 CairoSurface.xs   |   42 ++++++++++++++++++++++++++++++++++++++++++
 Makefile.PL       |    6 ++++++
 cairo-perl.h      |    3 +++
 inc/MakeHelper.pm |   13 +++++++++++--
 t/CairoSurface.t  |   24 +++++++++++++++++++++++-
 6 files changed, 128 insertions(+), 3 deletions(-)
---
diff --git a/Cairo.xs b/Cairo.xs
index 453f9cf..b8bb1a9 100644
--- a/Cairo.xs
+++ b/Cairo.xs
@@ -242,6 +242,38 @@ newSVCairoRectangle (cairo_rectangle_t *rectangle)
 	return newRV_noinc ((SV *) hv);
 }
 
+cairo_rectangle_t *
+SvCairoRectangle (SV *sv)
+{
+	HV *hv;
+	SV **value;
+	cairo_rectangle_t *rectangle;
+
+	if (!cairo_perl_sv_is_hash_ref (sv))
+		croak ("cairo_rectangle_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 = SvNV (*value);
+
+	value = hv_fetchs (hv, "y", 0);
+	if (value && SvOK (*value))
+		rectangle->y = SvNV (*value);
+
+	value = hv_fetchs (hv, "width", 0);
+	if (value && SvOK (*value))
+		rectangle->width = SvNV (*value);
+
+	value = hv_fetchs (hv, "height", 0);
+	if (value && SvOK (*value))
+		rectangle->height = SvNV (*value);
+
+	return rectangle;
+}
+
 #endif
 
 /* ------------------------------------------------------------------------- */
@@ -791,6 +823,17 @@ HAS_SVG_SURFACE ()
 	RETVAL
 
 bool
+HAS_RECORDING_SURFACE ()
+    CODE:
+#ifdef CAIRO_HAS_RECORDING_SURFACE
+	RETVAL = TRUE;
+#else
+	RETVAL = FALSE;
+#endif
+    OUTPUT:
+	RETVAL
+
+bool
 HAS_FT_FONT ()
     CODE:
 #ifdef CAIRO_HAS_FT_FONT
diff --git a/CairoSurface.xs b/CairoSurface.xs
index 2a51673..4fa7b2d 100644
--- a/CairoSurface.xs
+++ b/CairoSurface.xs
@@ -85,6 +85,12 @@ get_package (cairo_surface_t *surface)
 		package = "Cairo::SvgSurface";
 		break;
 
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
+	    case CAIRO_SURFACE_TYPE_RECORDING:
+		package = "Cairo::RecordingSurface";
+		break;
+#endif
+
 	    case CAIRO_SURFACE_TYPE_XLIB:
 	    case CAIRO_SURFACE_TYPE_XCB:
 	    case CAIRO_SURFACE_TYPE_GLITZ:
@@ -92,6 +98,20 @@ get_package (cairo_surface_t *surface)
 	    case CAIRO_SURFACE_TYPE_WIN32:
 	    case CAIRO_SURFACE_TYPE_BEOS:
 	    case CAIRO_SURFACE_TYPE_DIRECTFB:
+	    case CAIRO_SURFACE_TYPE_OS2:
+	    case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
+	    case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE:
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
+	    case CAIRO_SURFACE_TYPE_SCRIPT:
+	    case CAIRO_SURFACE_TYPE_QT:
+	    case CAIRO_SURFACE_TYPE_VG:
+	    case CAIRO_SURFACE_TYPE_GL:
+	    case CAIRO_SURFACE_TYPE_DRM:
+	    case CAIRO_SURFACE_TYPE_TEE:
+	    case CAIRO_SURFACE_TYPE_XML:
+	    case CAIRO_SURFACE_TYPE_SKIA:
+	    case CAIRO_SURFACE_TYPE_SUBSURFACE:
+#endif
 		package = "Cairo::Surface";
 		break;
 
@@ -647,6 +667,28 @@ cairo_svg_surface_version_to_string (...)
 
 # --------------------------------------------------------------------------- #
 
+# The recording surface doesn't need the special package treatment because it
+# didn't exist in cairo 1.0.
+
+#ifdef CAIRO_HAS_RECORDING_SURFACE
+
+MODULE = Cairo::Surface	PACKAGE = Cairo::RecordingSurface	PREFIX = cairo_recording_surface_
+
+BOOT:
+	cairo_perl_set_isa ("Cairo::RecordingSurface", "Cairo::Surface");
+
+# cairo_surface_t * cairo_recording_surface_create (cairo_content_t, const cairo_rectangle_t *extents);
+cairo_surface_t_noinc *
+cairo_recording_surface_create (class, cairo_content_t content, cairo_rectangle_t_ornull *extents)
+    C_ARGS:
+	content, extents
+
+void cairo_recording_surface_ink_extents (cairo_surface_t *surface, OUTLIST double x0, OUTLIST double y0, OUTLIST double width, OUTLIST double height);
+
+#endif
+
+# --------------------------------------------------------------------------- #
+
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 6, 0)
 
 MODULE = Cairo::Surface	PACKAGE = Cairo::Format	PREFIX = cairo_format_
diff --git a/Makefile.PL b/Makefile.PL
index 490edd9..9a45a87 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -72,6 +72,7 @@ my %objects = (
 my %structs = (
 	'cairo_font_options_t *' => 'Cairo::FontOptions',
 	'cairo_matrix_t *'       => 'Cairo::Matrix',
+	'cairo_rectangle_t *'    => 'Cairo::Rectangle',
 );
 
 my %enums = (
@@ -327,6 +328,10 @@ if ($have_cairo_1_8) {
 
 my %object_guards = ();
 
+my %struct_guards = (
+	cairo_rectangle_t => '#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 4, 0)',
+);
+
 my %enum_guards = (
 	cairo_ps_level_t    => '#ifdef CAIRO_HAS_PS_SURFACE',
 	cairo_svg_version_t => '#ifdef CAIRO_HAS_SVG_SURFACE',
@@ -363,6 +368,7 @@ MakeHelper::write_boot (
 
 my @typemaps = MakeHelper::do_typemaps (\%objects, \%structs, \%enums, \%flags,
                                         \%object_guards,
+                                        \%struct_guards,
                                         \%enum_guards,
                                         \%flag_guards);
 push @typemaps, 'cairo-perl.typemap';
diff --git a/cairo-perl.h b/cairo-perl.h
index ffa9567..c327087 100644
--- a/cairo-perl.h
+++ b/cairo-perl.h
@@ -69,7 +69,10 @@ cairo_path_t * SvCairoPath (SV *sv);
 
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 4, 0)
 
+#undef newSVCairoRectangle
+#undef SvCairoRectangle
 SV * newSVCairoRectangle (cairo_rectangle_t *rectangle);
+cairo_rectangle_t * SvCairoRectangle (SV *sv);
 
 #endif
 
diff --git a/inc/MakeHelper.pm b/inc/MakeHelper.pm
index 15fea0f..6b49b84 100644
--- a/inc/MakeHelper.pm
+++ b/inc/MakeHelper.pm
@@ -79,6 +79,7 @@ sub do_typemaps
 	my %enums = %{shift ()};
 	my %flags = %{shift ()};
 	my %object_guards = %{shift ()};
+	my %struct_guards = %{shift ()};
 	my %enum_guards = %{shift ()};
 	my %flag_guards = %{shift ()};
 
@@ -230,13 +231,21 @@ EOS
 		my $type = $1;
 		my $mangled = mangle ($type);
 
+		if (exists $struct_guards{$type}) {
+			print HEADER "$struct_guards{$type}\n";
+		}
+
 		print HEADER <<"EOS";
 typedef $type ${type}_ornull;
 #define Sv$mangled(sv)			(($type *) cairo_struct_from_sv (sv, "$structs{$_}"))
 #define Sv${mangled}_ornull(sv)		(((sv) && SvOK (sv)) ? Sv$mangled(sv) : NULL)
-#define newSV$mangled(struct)		(cairo_struct_to_sv (($type *) struct, "$structs{$_}"))
-#define newSV${mangled}_ornull(struct)	(((struct) == NULL) ? &PL_sv_undef : newSV$mangled(struct))
+#define newSV$mangled(struct_)		(cairo_struct_to_sv (($type *) struct_, "$structs{$_}"))
+#define newSV${mangled}_ornull(struct_)	(((struct_) == NULL) ? &PL_sv_undef : newSV$mangled(struct_))
 EOS
+
+		if (exists $struct_guards{$type}) {
+			print HEADER "#endif /* $struct_guards{$type} */\n";
+		}
 	}
 
 	# ------------------------------------------------------------------- #
diff --git a/t/CairoSurface.t b/t/CairoSurface.t
index 178a813..d088b36 100644
--- a/t/CairoSurface.t
+++ b/t/CairoSurface.t
@@ -12,7 +12,7 @@ use warnings;
 
 use Config; # for byteorder
 
-use Test::More tests => 72;
+use Test::More tests => 77;
 
 use constant IMG_WIDTH => 256;
 use constant IMG_HEIGHT => 256;
@@ -339,3 +339,25 @@ SKIP: {
 	like (Cairo::SvgSurface::version_to_string('1-1'), qr/1\.1/);
 	like (Cairo::SvgSurface->version_to_string('1-1'), qr/1\.1/);
 }
+
+SKIP: {
+	skip 'svg surface', 5
+		unless Cairo::HAS_RECORDING_SURFACE;
+
+	my $surf = Cairo::RecordingSurface->create (
+	             'color',
+	             {x=>10, y=>10, width=>5, height=>5});
+	isa_ok ($surf, 'Cairo::RecordingSurface');
+	isa_ok ($surf, 'Cairo::Surface');
+
+	# Test that the extents rectangle was marshalled correctly.
+	my $cr = Cairo::Context->create ($surf);
+	$cr->move_to (0, 0);
+	$cr->line_to (30, 30);
+	$cr->paint;
+	is_deeply ([$surf->ink_extents], [10, 10, 5, 5]);
+
+	$surf = Cairo::RecordingSurface->create ('color', undef);
+	isa_ok ($surf, 'Cairo::RecordingSurface');
+	isa_ok ($surf, 'Cairo::Surface');
+}



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