[perl-Cairo] Auto-upgrade strings to utf8



commit 20f7d8c347bdcf44347b352824fa3567b0c6ee59
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Sun Dec 11 21:01:41 2011 +0100

    Auto-upgrade strings to utf8
    
    Whenever cairo expects utf8-encoded strings, automatically "upgrade" the
    user-supplied string to utf8.  This makes it unnecessary (but harmless)
    for users to call utf8::upgrade() on their strings.
    
    Note, however, that calling utf8::encode() will now yield doubly-encoded
    and thus broken strings.  Also, having utf8-encoded literals in your
    code without an accompanying "use utf8" line will also lead to double
    encoding.
    
    https://rt.cpan.org/Ticket/Display.html?id=73177

 Cairo.xs             |   11 ++++++-----
 CairoFont.xs         |    7 ++++---
 NEWS                 |    5 +++++
 cairo-perl.h         |    5 +++++
 cairo-perl.typemap   |   18 +++++++++++++++---
 examples/png/text.pl |    5 +++--
 6 files changed, 38 insertions(+), 13 deletions(-)
---
diff --git a/Cairo.xs b/Cairo.xs
index 45dde27..8c1e3ad 100644
--- a/Cairo.xs
+++ b/Cairo.xs
@@ -656,7 +656,7 @@ cairo_bool_t cairo_in_clip (cairo_t *cr, double x, double y);
 
 void cairo_reset_clip (cairo_t *cr);
 
-void cairo_select_font_face (cairo_t *cr, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight);
+void cairo_select_font_face (cairo_t *cr, const char_utf8 *family, cairo_font_slant_t slant, cairo_font_weight_t weight);
 
 void cairo_set_font_size (cairo_t *cr, double size);
 
@@ -694,7 +694,7 @@ cairo_scaled_font_t * cairo_get_scaled_font (cairo_t *cr);
 
 #endif
 
-void cairo_show_text (cairo_t * cr, const char * utf8);
+void cairo_show_text (cairo_t * cr, const char_utf8 * utf8);
 
 ##void cairo_show_glyphs (cairo_t * cr, cairo_glyph_t * glyphs, int num_glyphs);
 void cairo_show_glyphs (cairo_t * cr, ...)
@@ -727,6 +727,7 @@ cairo_show_text_glyphs (cairo_t *cr, SV *utf8_sv, SV *glyphs_sv, SV *clusters_sv
 	if (!cairo_perl_sv_is_array_ref (clusters_sv))
 		croak ("text clusters must be an array ref");
 
+	sv_utf8_upgrade (utf8_sv);
 	utf8 = SvPV (utf8_sv, utf8_len);
 
 	glyphs_av = (AV *) SvRV (glyphs_sv);
@@ -771,8 +772,8 @@ cairo_font_extents_t * cairo_font_extents (cairo_t *cr)
 
 void cairo_set_font_face (cairo_t *cr, cairo_font_face_t *font_face);
 
-##void cairo_text_extents (cairo_t * cr, const unsigned char * utf8, cairo_text_extents_t * extents);
-cairo_text_extents_t * cairo_text_extents (cairo_t * cr, const char * utf8)
+##void cairo_text_extents (cairo_t * cr, const char * utf8, cairo_text_extents_t * extents);
+cairo_text_extents_t * cairo_text_extents (cairo_t * cr, const char_utf8 * utf8)
     PREINIT:
 	cairo_text_extents_t extents;
     CODE:
@@ -798,7 +799,7 @@ cairo_text_extents_t * cairo_glyph_extents (cairo_t * cr, ...)
     OUTPUT:
 	RETVAL
 
-void cairo_text_path  (cairo_t * cr, const char * utf8);
+void cairo_text_path  (cairo_t * cr, const char_utf8 * utf8);
 
 ##void cairo_glyph_path (cairo_t * cr, cairo_glyph_t * glyphs, int num_glyphs);
 void cairo_glyph_path (cairo_t * cr, ...)
diff --git a/CairoFont.xs b/CairoFont.xs
index c1af1d8..4a623c9 100644
--- a/CairoFont.xs
+++ b/CairoFont.xs
@@ -85,7 +85,7 @@ BOOT:
 
 # cairo_font_face_t * cairo_toy_font_face_create (const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight)
 cairo_font_face_t_noinc *
-cairo_toy_font_face_create (class, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight)
+cairo_toy_font_face_create (class, const char_utf8 *family, cairo_font_slant_t slant, cairo_font_weight_t weight)
     C_ARGS:
 	family, slant, weight
     POSTCALL:
@@ -93,7 +93,7 @@ cairo_toy_font_face_create (class, const char *family, cairo_font_slant_t slant,
 	cairo_perl_package_table_insert (RETVAL, "Cairo::ToyFontFace");
 #endif
 
-const char * cairo_toy_font_face_get_family (cairo_font_face_t *font_face);
+const char_utf8 * cairo_toy_font_face_get_family (cairo_font_face_t *font_face);
 
 cairo_font_slant_t  cairo_toy_font_face_get_slant (cairo_font_face_t *font_face);
 
@@ -135,7 +135,7 @@ cairo_font_extents_t * cairo_scaled_font_extents (cairo_scaled_font_t *scaled_fo
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 0)
 
 ##void cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, const char *utf8, cairo_text_extents_t *extents);
-cairo_text_extents_t * cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, const char *utf8)
+cairo_text_extents_t * cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, const char_utf8 *utf8)
     PREINIT:
 	cairo_text_extents_t extents;
     CODE:
@@ -178,6 +178,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, double x, do
 	cairo_text_cluster_flags_t cluster_flags;
 	cairo_status_t status;
     PPCODE:
+	sv_utf8_upgrade (utf8_sv);
 	utf8 = SvPV (utf8_sv, utf8_len);
 	status = cairo_scaled_font_text_to_glyphs (
 	           scaled_font,
diff --git a/NEWS b/NEWS
index 1bdffa0..b2da923 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 Overview of changes in Cairo <next>
 ==================================
 
+* Auto-upgrade strings to utf8.  Note that this means that calling
+  utf8::encode() on strings before passing them into Cairo will now
+  yield doubly-encoded and thus broken strings.  Also, having
+  utf8-encoded literals in your code without an accompanying "use utf8"
+  line will also lead to double encoding.
 * Fix compiling and testing against older versions of cairo.
 * Make the test suite more robust.
 
diff --git a/cairo-perl.h b/cairo-perl.h
index 18b6074..c6c000e 100644
--- a/cairo-perl.h
+++ b/cairo-perl.h
@@ -112,4 +112,9 @@ SV * cairo_font_face_to_sv (cairo_font_face_t *surface);
 #define newSVCairoFontFace(object)		(cairo_font_face_to_sv (cairo_font_face_reference (object)))
 #define newSVCairoFontFace_noinc(object)	(cairo_font_face_to_sv (object))
 
+/*
+ * Type aliases for the typemap
+ */
+typedef char char_utf8;
+
 #endif /* _CAIRO_PERL_H_ */
diff --git a/cairo-perl.typemap b/cairo-perl.typemap
index 62bb02c..4254fd4 100644
--- a/cairo-perl.typemap
+++ b/cairo-perl.typemap
@@ -1,10 +1,8 @@
 #
-# Copyright (c) 2004-2005 by the cairo perl team (see the file README)
+# Copyright (c) 2004-2011 by the cairo perl team (see the file README)
 #
 # Licensed under the LGPL, see LICENSE file for more information.
 #
-# $Id$
-#
 
 TYPEMAP
 
@@ -12,6 +10,9 @@ TYPEMAP
 # don't know const char *.
 const char * 	   	T_PV
 
+char_utf8 *             T_PV_UTF8
+const char_utf8 *       T_PV_UTF8
+
 cairo_bool_t		T_UV
 
 cairo_font_extents_t *	T_CAIRO_FONT_EXTENTS
@@ -22,9 +23,14 @@ cairo_path_t *		T_CAIRO_PATH
 
 FT_Face			T_FT_FACE
 
+# -----------------------------------------------------------------------------
 
 INPUT
 
+T_PV_UTF8
+	sv_utf8_upgrade ($arg);
+	$var = ($type) SvPV_nolen ($arg);
+
 T_CAIRO_GLYPH
 	$var = SvCairoGlyph ($arg);
 
@@ -34,8 +40,14 @@ T_CAIRO_TEXT_CLUSTER
 T_CAIRO_PATH
 	$var = SvCairoPath ($arg);
 
+# -----------------------------------------------------------------------------
+
 OUTPUT
 
+T_PV_UTF8
+	sv_setpv ((SV*)$arg, $var);
+	SvUTF8_on ($arg);
+
 T_CAIRO_FONT_EXTENTS
 	$arg = newSVCairoFontExtents ($var);
 
diff --git a/examples/png/text.pl b/examples/png/text.pl
index d128705..58165d9 100644
--- a/examples/png/text.pl
+++ b/examples/png/text.pl
@@ -2,13 +2,14 @@
 
 use strict;
 use warnings;
+use utf8;
 use Cairo;
 
 use constant
 {
 	WIDTH => 450,
 	HEIGHT => 600,
-	TEXT => 'hello, world',
+	TEXT => 'hÃllÃ, wÃrld',
 	NUM_GLYPHS => 10,
 	M_PI => 4 * atan2(1, 1),
 };
@@ -19,7 +20,7 @@ sub box_text
 
 	$cr->save;
 
-	my $extents = $cr->text_extents (TEXT);
+	my $extents = $cr->text_extents ($utf8);
 	my $line_width = $cr->get_line_width;
 	$cr->rectangle ($x + $extents->{x_bearing} - $line_width,
 	                $y + $extents->{y_bearing} - $line_width,



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