[cairo-commit] 4 commits - boilerplate/cairo-boilerplate.h boilerplate/cairo-boilerplate-pdf.c boilerplate/cairo-boilerplate-ps.c boilerplate/cairo-boilerplate-svg.c src/cairo-cff-subset.c src/cairo-image-surface.c src/cairoint.h src/cairo-recording-surface.c src/cairo-surface.c test/fallback-resolution.c test/fallback-resolution.ppi144x144.ps.ref.png test/fallback-resolution.ppi144x144.ref.png test/fallback-resolution.ppi144x72.ps.ref.png test/fallback-resolution.ppi144x72.ref.png test/fallback-resolution.ppi150x150.ref.png test/fallback-resolution.ppi150x72.ref.png test/fallback-resolution.ppi288x288.pdf.ref.png test/fallback-resolution.ppi288x288.ps.ref.png test/fallback-resolution.ppi288x288.svg.ref.png test/fallback-resolution.ppi288x72.ps.ref.png test/fallback-resolution.ppi288x72.ref.png test/fallback-resolution.ppi300x300.ref.png test/fallback-resolution.ppi300x72.ref.png test/fallback-resolution.ppi37.5x37.5.ref.png test/fallback-resolution.ppi37.5x72.ref.png test/fallback -resolution.ppi576x576.pdf.ref.png test/fallback-resolution.ppi576x576.ps.ref.png test/fallback-resolution.ppi576x576.svg.ref.png test/fallback-resolution.ppi576x72.ps.ref.png test/fallback-resolution.ppi576x72.ref.png test/fallback-resolution.ppi600x600.ref.png test/fallback-resolution.ppi600x72.ref.png test/fallback-resolution.ppi72x144.ps.ref.png test/fallback-resolution.ppi72x144.ref.png test/fallback-resolution.ppi72x150.ref.png test/fallback-resolution.ppi72x288.ps.ref.png test/fallback-resolution.ppi72x288.ref.png test/fallback-resolution.ppi72x300.ref.png test/fallback-resolution.ppi72x37.5.ref.png test/fallback-resolution.ppi72x576.ps.ref.png test/fallback-resolution.ppi72x576.ref.png test/fallback-resolution.ppi72x600.ref.png test/fallback-resolution.ppi72x72.ref.png test/fallback-resolution.ppi72x75.ref.png test/fallback-resolution.ppi75x72.ref.png test/fallback-resolution.ppi75x75.ref.png

Adrian Johnson ajohnson at kemper.freedesktop.org
Sat Nov 27 09:18:22 PST 2010


 boilerplate/cairo-boilerplate-pdf.c             |    6 ++
 boilerplate/cairo-boilerplate-ps.c              |    6 ++
 boilerplate/cairo-boilerplate-svg.c             |    6 ++
 boilerplate/cairo-boilerplate.h                 |    3 -
 dev/null                                        |binary
 src/cairo-cff-subset.c                          |   51 ++++++++++++++++-----
 src/cairo-image-surface.c                       |   57 +++++++++++++++++-------
 src/cairo-recording-surface.c                   |   32 ++++++++++---
 src/cairo-surface.c                             |   27 +++++++++++
 src/cairoint.h                                  |   12 +++++
 test/fallback-resolution.c                      |   30 ++++--------
 test/fallback-resolution.ppi144x144.ps.ref.png  |binary
 test/fallback-resolution.ppi144x144.ref.png     |binary
 test/fallback-resolution.ppi144x72.ps.ref.png   |binary
 test/fallback-resolution.ppi144x72.ref.png      |binary
 test/fallback-resolution.ppi288x288.pdf.ref.png |binary
 test/fallback-resolution.ppi288x288.ps.ref.png  |binary
 test/fallback-resolution.ppi288x288.svg.ref.png |binary
 test/fallback-resolution.ppi288x72.ps.ref.png   |binary
 test/fallback-resolution.ppi288x72.ref.png      |binary
 test/fallback-resolution.ppi576x576.pdf.ref.png |binary
 test/fallback-resolution.ppi576x576.ps.ref.png  |binary
 test/fallback-resolution.ppi576x576.svg.ref.png |binary
 test/fallback-resolution.ppi576x72.ps.ref.png   |binary
 test/fallback-resolution.ppi576x72.ref.png      |binary
 test/fallback-resolution.ppi72x144.ps.ref.png   |binary
 test/fallback-resolution.ppi72x144.ref.png      |binary
 test/fallback-resolution.ppi72x288.ps.ref.png   |binary
 test/fallback-resolution.ppi72x288.ref.png      |binary
 test/fallback-resolution.ppi72x576.ps.ref.png   |binary
 test/fallback-resolution.ppi72x576.ref.png      |binary
 test/fallback-resolution.ppi72x72.ref.png       |binary
 32 files changed, 171 insertions(+), 59 deletions(-)

New commits:
commit 7feefc75f6dcb9381cd5bc1bdc3e2d722789b155
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Nov 28 03:46:10 2010 +1030

    CFF subset: fix subsetting of Euro glyph
    
    https://bugs.freedesktop.org/show_bug.cgi?id=31878

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 44d1f5e..26c39a4 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -131,6 +131,7 @@ typedef struct _cairo_cff_font {
     char                *subset_font_name;
     cairo_array_t        charstrings_subset_index;
     cairo_array_t        strings_subset_index;
+    int			 euro_sid;
     int                 *fdselect_subset;
     unsigned int         num_subset_fontdicts;
     int                 *fd_subset_map;
@@ -1247,6 +1248,33 @@ cairo_cff_font_subset_strings (cairo_cff_font_t *font)
     return status;
 }
 
+/* The Euro is the only the only character in the winansi encoding
+ * with a glyph name that is not a CFF standard string. As the strings
+ * are written before the charset, we need to check during the
+ * subsetting phase if the Euro glyph is required and add the
+ * glyphname to the list of strings to write out.
+ */
+static cairo_status_t
+cairo_cff_font_subset_charset_strings (cairo_cff_font_t *font)
+{
+    cairo_status_t status;
+    unsigned int i;
+    int ch;
+    const char *euro = "Euro";
+
+    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+	ch = font->scaled_font_subset->to_latin_char[i];
+	if (ch == 128) {
+	    font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
+	    status = cff_index_append_copy (&font->strings_subset_index,
+					    (unsigned char *)euro, strlen(euro));
+	    return status;
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static cairo_status_t
 cairo_cff_font_subset_font (cairo_cff_font_t  *font)
 {
@@ -1279,6 +1307,9 @@ cairo_cff_font_subset_font (cairo_cff_font_t  *font)
     if (unlikely (status))
         return status;
 
+    if (font->scaled_font_subset->is_latin)
+	status = cairo_cff_font_subset_charset_strings (font);
+
     return status;
 }
 
@@ -1500,12 +1531,10 @@ static const int winansi_to_cff_std_string[] = {
     147, 225, 222, 223, 224, 226, 162, 227,
 };
 
-static cairo_status_t
-cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch, int *sid_out)
+static int
+cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch)
 {
     int sid;
-    cairo_status_t status;
-    const char *euro = "Euro";
 
     if (ch == 39) {
 	sid = 104;
@@ -1517,11 +1546,8 @@ cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch, int *s
 	sid = ch - 31;
 
     } else if (ch == 128) {
-	sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
-	status = cff_index_append_copy (&font->strings_subset_index,
-					(unsigned char *)euro, strlen(euro));
-	if (unlikely (status))
-	    return status;
+	assert (font->euro_sid >= NUM_STD_STRINGS);
+	sid = font->euro_sid;
 
     } else if (ch >= 128 && ch <= 255) {
 	sid = winansi_to_cff_std_string[ch - 128];
@@ -1530,9 +1556,7 @@ cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch, int *s
 	sid = 0;
     }
 
-    *sid_out = sid;
-
-    return CAIRO_STATUS_SUCCESS;
+    return sid;
 }
 
 static cairo_status_t
@@ -1551,7 +1575,7 @@ cairo_cff_font_write_type1_charset (cairo_cff_font_t  *font)
 
     for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
 	ch = font->scaled_font_subset->to_latin_char[i];
-	status = cairo_cff_font_get_sid_for_winansi_char (font, ch, &sid);
+	sid = cairo_cff_font_get_sid_for_winansi_char (font, ch);
         if (unlikely (status))
 	    return status;
 
@@ -2021,6 +2045,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
     cff_index_init (&font->local_sub_index);
     cff_index_init (&font->charstrings_subset_index);
     cff_index_init (&font->strings_subset_index);
+    font->euro_sid = 0;
     font->fdselect = NULL;
     font->fd_dict = NULL;
     font->fd_private_dict = NULL;
commit f85af7fe8d92f5ac304d742fcbfdaac512bace33
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Nov 21 23:41:33 2010 +1030

    Change fallback resolution test to use resolutions in multiples of 72
    
    With integer aligned clipping the test output has no seams.

diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index c122dea..1d05973 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -328,27 +328,19 @@ preamble (cairo_test_context_t *ctx)
     struct {
 	double x, y;
     } ppi[] = {
-	{ 600, 600 },
-	{ 600, 72 },
+	{ 576, 576 },
+	{ 576, 72 },
 
-	{ 300, 300 },
-	{ 300, 72 },
+	{ 288, 288 },
+	{ 288, 72 },
 
-	{ 150, 150 },
-	{ 150, 72 },
+	{ 144, 144 },
+	{ 144, 72 },
 
-	{ 75, 75 },
-	{ 75, 72 },
-
-	{ 72, 600 },
-	{ 72, 300 },
-	{ 72, 150 },
-	{ 72, 75 },
+	{ 72, 576 },
+	{ 72, 288 },
+	{ 72, 144 },
 	{ 72, 72 },
-	{ 72, 37.5 },
-
-	{ 37.5, 72 },
-	{ 37.5, 37.5 },
     };
     unsigned int i;
     int n, num_ppi;
diff --git a/test/fallback-resolution.ppi144x144.ps.ref.png b/test/fallback-resolution.ppi144x144.ps.ref.png
new file mode 100644
index 0000000..0922f03
Binary files /dev/null and b/test/fallback-resolution.ppi144x144.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi144x144.ref.png b/test/fallback-resolution.ppi144x144.ref.png
new file mode 100644
index 0000000..cbe93ca
Binary files /dev/null and b/test/fallback-resolution.ppi144x144.ref.png differ
diff --git a/test/fallback-resolution.ppi144x72.ps.ref.png b/test/fallback-resolution.ppi144x72.ps.ref.png
new file mode 100644
index 0000000..2f8d82d
Binary files /dev/null and b/test/fallback-resolution.ppi144x72.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi144x72.ref.png b/test/fallback-resolution.ppi144x72.ref.png
new file mode 100644
index 0000000..4c16ca1
Binary files /dev/null and b/test/fallback-resolution.ppi144x72.ref.png differ
diff --git a/test/fallback-resolution.ppi150x150.ref.png b/test/fallback-resolution.ppi150x150.ref.png
deleted file mode 100644
index 40e68a9..0000000
Binary files a/test/fallback-resolution.ppi150x150.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi150x72.ref.png b/test/fallback-resolution.ppi150x72.ref.png
deleted file mode 100644
index 47e0c58..0000000
Binary files a/test/fallback-resolution.ppi150x72.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi288x288.pdf.ref.png b/test/fallback-resolution.ppi288x288.pdf.ref.png
new file mode 100644
index 0000000..181e110
Binary files /dev/null and b/test/fallback-resolution.ppi288x288.pdf.ref.png differ
diff --git a/test/fallback-resolution.ppi288x288.ps.ref.png b/test/fallback-resolution.ppi288x288.ps.ref.png
new file mode 100644
index 0000000..99bccef
Binary files /dev/null and b/test/fallback-resolution.ppi288x288.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi288x288.svg.ref.png b/test/fallback-resolution.ppi288x288.svg.ref.png
new file mode 100644
index 0000000..e71ff81
Binary files /dev/null and b/test/fallback-resolution.ppi288x288.svg.ref.png differ
diff --git a/test/fallback-resolution.ppi288x72.ps.ref.png b/test/fallback-resolution.ppi288x72.ps.ref.png
new file mode 100644
index 0000000..89b9c51
Binary files /dev/null and b/test/fallback-resolution.ppi288x72.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi288x72.ref.png b/test/fallback-resolution.ppi288x72.ref.png
new file mode 100644
index 0000000..b213587
Binary files /dev/null and b/test/fallback-resolution.ppi288x72.ref.png differ
diff --git a/test/fallback-resolution.ppi300x300.ref.png b/test/fallback-resolution.ppi300x300.ref.png
deleted file mode 100644
index 61af74c..0000000
Binary files a/test/fallback-resolution.ppi300x300.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi300x72.ref.png b/test/fallback-resolution.ppi300x72.ref.png
deleted file mode 100644
index d790a38..0000000
Binary files a/test/fallback-resolution.ppi300x72.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi37.5x37.5.ref.png b/test/fallback-resolution.ppi37.5x37.5.ref.png
deleted file mode 100644
index 172fbcd..0000000
Binary files a/test/fallback-resolution.ppi37.5x37.5.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi37.5x72.ref.png b/test/fallback-resolution.ppi37.5x72.ref.png
deleted file mode 100644
index cac416a..0000000
Binary files a/test/fallback-resolution.ppi37.5x72.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi576x576.pdf.ref.png b/test/fallback-resolution.ppi576x576.pdf.ref.png
new file mode 100644
index 0000000..5b37619
Binary files /dev/null and b/test/fallback-resolution.ppi576x576.pdf.ref.png differ
diff --git a/test/fallback-resolution.ppi576x576.ps.ref.png b/test/fallback-resolution.ppi576x576.ps.ref.png
new file mode 100644
index 0000000..9dc4735
Binary files /dev/null and b/test/fallback-resolution.ppi576x576.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi576x576.svg.ref.png b/test/fallback-resolution.ppi576x576.svg.ref.png
new file mode 100644
index 0000000..b5a97e3
Binary files /dev/null and b/test/fallback-resolution.ppi576x576.svg.ref.png differ
diff --git a/test/fallback-resolution.ppi576x72.ps.ref.png b/test/fallback-resolution.ppi576x72.ps.ref.png
new file mode 100644
index 0000000..9ac6be4
Binary files /dev/null and b/test/fallback-resolution.ppi576x72.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi576x72.ref.png b/test/fallback-resolution.ppi576x72.ref.png
new file mode 100644
index 0000000..b63e66e
Binary files /dev/null and b/test/fallback-resolution.ppi576x72.ref.png differ
diff --git a/test/fallback-resolution.ppi600x600.ref.png b/test/fallback-resolution.ppi600x600.ref.png
deleted file mode 100644
index 34a2e56..0000000
Binary files a/test/fallback-resolution.ppi600x600.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi600x72.ref.png b/test/fallback-resolution.ppi600x72.ref.png
deleted file mode 100644
index ed45777..0000000
Binary files a/test/fallback-resolution.ppi600x72.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi72x144.ps.ref.png b/test/fallback-resolution.ppi72x144.ps.ref.png
new file mode 100644
index 0000000..50b5a99
Binary files /dev/null and b/test/fallback-resolution.ppi72x144.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi72x144.ref.png b/test/fallback-resolution.ppi72x144.ref.png
new file mode 100644
index 0000000..9d232c0
Binary files /dev/null and b/test/fallback-resolution.ppi72x144.ref.png differ
diff --git a/test/fallback-resolution.ppi72x150.ref.png b/test/fallback-resolution.ppi72x150.ref.png
deleted file mode 100644
index db61cba..0000000
Binary files a/test/fallback-resolution.ppi72x150.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi72x288.ps.ref.png b/test/fallback-resolution.ppi72x288.ps.ref.png
new file mode 100644
index 0000000..b4ff82d
Binary files /dev/null and b/test/fallback-resolution.ppi72x288.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi72x288.ref.png b/test/fallback-resolution.ppi72x288.ref.png
new file mode 100644
index 0000000..fdbc382
Binary files /dev/null and b/test/fallback-resolution.ppi72x288.ref.png differ
diff --git a/test/fallback-resolution.ppi72x300.ref.png b/test/fallback-resolution.ppi72x300.ref.png
deleted file mode 100644
index 76b5b0c..0000000
Binary files a/test/fallback-resolution.ppi72x300.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi72x37.5.ref.png b/test/fallback-resolution.ppi72x37.5.ref.png
deleted file mode 100644
index a459d52..0000000
Binary files a/test/fallback-resolution.ppi72x37.5.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi72x576.ps.ref.png b/test/fallback-resolution.ppi72x576.ps.ref.png
new file mode 100644
index 0000000..6a3ddcb
Binary files /dev/null and b/test/fallback-resolution.ppi72x576.ps.ref.png differ
diff --git a/test/fallback-resolution.ppi72x576.ref.png b/test/fallback-resolution.ppi72x576.ref.png
new file mode 100644
index 0000000..c943f08
Binary files /dev/null and b/test/fallback-resolution.ppi72x576.ref.png differ
diff --git a/test/fallback-resolution.ppi72x600.ref.png b/test/fallback-resolution.ppi72x600.ref.png
deleted file mode 100644
index 38235a3..0000000
Binary files a/test/fallback-resolution.ppi72x600.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi72x72.ref.png b/test/fallback-resolution.ppi72x72.ref.png
index b76fd94..5d1df2c 100644
Binary files a/test/fallback-resolution.ppi72x72.ref.png and b/test/fallback-resolution.ppi72x72.ref.png differ
diff --git a/test/fallback-resolution.ppi72x75.ref.png b/test/fallback-resolution.ppi72x75.ref.png
deleted file mode 100644
index 3c22cca..0000000
Binary files a/test/fallback-resolution.ppi72x75.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi75x72.ref.png b/test/fallback-resolution.ppi75x72.ref.png
deleted file mode 100644
index 161edb0..0000000
Binary files a/test/fallback-resolution.ppi75x72.ref.png and /dev/null differ
diff --git a/test/fallback-resolution.ppi75x75.ref.png b/test/fallback-resolution.ppi75x75.ref.png
deleted file mode 100644
index 3769d09..0000000
Binary files a/test/fallback-resolution.ppi75x75.ref.png and /dev/null differ
commit 126108a6ac5aa5e615071e0cbd1901e5a5de3ca6
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed Nov 24 21:43:07 2010 +1030

    Boilerplate: Set fallback resolution using force_fallbacks function
    
    cairo_set_fallback_resolution() does not work when testing rgb24 surfaces

diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
index 6f4afe9..ea66c23 100644
--- a/boilerplate/cairo-boilerplate-pdf.c
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -219,7 +219,8 @@ _cairo_boilerplate_pdf_cleanup (void *closure)
 
 static void
 _cairo_boilerplate_pdf_force_fallbacks (cairo_surface_t *abstract_surface,
-					unsigned int	 flags)
+				       double		 x_pixels_per_inch,
+				       double		 y_pixels_per_inch)
 {
     pdf_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
 							     &pdf_closure_key);
@@ -233,6 +234,9 @@ _cairo_boilerplate_pdf_force_fallbacks (cairo_surface_t *abstract_surface,
     paginated = (cairo_paginated_surface_t*) abstract_surface;
     surface = (cairo_pdf_surface_t*) paginated->target;
     surface->force_fallbacks = TRUE;
+    cairo_surface_set_fallback_resolution (&paginated->base,
+					   x_pixels_per_inch,
+					   y_pixels_per_inch);
 }
 #endif
 
diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c
index 09dce6e..e4a3f71 100644
--- a/boilerplate/cairo-boilerplate-ps.c
+++ b/boilerplate/cairo-boilerplate-ps.c
@@ -281,7 +281,8 @@ _cairo_boilerplate_ps_cleanup (void *closure)
 
 static void
 _cairo_boilerplate_ps_force_fallbacks (cairo_surface_t *abstract_surface,
-				       unsigned int	flags)
+				       double		 x_pixels_per_inch,
+				       double		 y_pixels_per_inch)
 {
     ps_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
 							    &ps_closure_key);
@@ -295,6 +296,9 @@ _cairo_boilerplate_ps_force_fallbacks (cairo_surface_t *abstract_surface,
     paginated = (cairo_paginated_surface_t*) abstract_surface;
     surface = (cairo_ps_surface_t*) paginated->target;
     surface->force_fallbacks = TRUE;
+    cairo_surface_set_fallback_resolution (&paginated->base,
+					   x_pixels_per_inch,
+					   y_pixels_per_inch);
 }
 
 static const cairo_boilerplate_target_t targets[] = {
diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c
index a0bbba6..7e7f1e7 100644
--- a/boilerplate/cairo-boilerplate-svg.c
+++ b/boilerplate/cairo-boilerplate-svg.c
@@ -253,7 +253,8 @@ _cairo_boilerplate_svg_cleanup (void *closure)
 
 static void
 _cairo_boilerplate_svg_force_fallbacks (cairo_surface_t *abstract_surface,
-					unsigned int	 flags)
+				       double		 x_pixels_per_inch,
+				       double		 y_pixels_per_inch)
 {
     svg_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
 							     &svg_closure_key);
@@ -267,6 +268,9 @@ _cairo_boilerplate_svg_force_fallbacks (cairo_surface_t *abstract_surface,
     paginated = (cairo_paginated_surface_t*) abstract_surface;
     surface = (cairo_svg_surface_t*) paginated->target;
     surface->force_fallbacks = TRUE;
+    cairo_surface_set_fallback_resolution (&paginated->base,
+					   x_pixels_per_inch,
+					   y_pixels_per_inch);
 }
 
 static const cairo_boilerplate_target_t targets[] = {
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index dae17ea..c0a0452 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -128,7 +128,8 @@ typedef cairo_surface_t *
 
 typedef void
 (*cairo_boilerplate_force_fallbacks_t) (cairo_surface_t *surface,
-					unsigned int flags);
+				       double		 x_pixels_per_inch,
+				       double		 y_pixels_per_inch);
 
 typedef cairo_status_t
 (*cairo_boilerplate_finish_surface_t) (cairo_surface_t *surface);
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index 8ae952a..c122dea 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -444,15 +444,13 @@ preamble (cairo_test_context_t *ctx)
 	    fflush (stdout);
 
 	    if (target->force_fallbacks != NULL)
-		target->force_fallbacks (surface, ~0U);
+		target->force_fallbacks (surface, ppi[n].x, ppi[n].y);
 	    cr = cairo_create (surface);
 #if SET_TOLERANCE
 	    cairo_set_tolerance (cr, 3.0);
 #endif
 
 	    cairo_surface_set_device_offset (surface, 25, 25);
-	    cairo_surface_set_fallback_resolution (surface,
-						   ppi[n].x, ppi[n].y);
 
 	    cairo_save (cr); {
 		cairo_set_source_rgb (cr, 1, 1, 1);
commit 59661f8af428b88125db033867d662e9393d0a41
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Nov 21 23:25:21 2010 +1030

    Fix fallback-resolution test
    
    The recording surface source image painted onto fallback images always
    had the resolution 72ppi instead of the fallback resolution of the
    target surface. Fix this by passing adding a new
    acquire_source_image_transformed backend function for the recording
    surface to use and passing the target device transform through to the
    recording surface when the image is acquired.
    
    Based on Carl Worth's experimental acquired_source_image_transformed
    branch.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=24692

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 09248f8..9c35d7d 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1368,6 +1368,7 @@ static pixman_image_t *
 _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
 			   cairo_bool_t is_mask,
 			   const cairo_rectangle_int_t *extents,
+			   cairo_matrix_t *dst_device_transform,
 			   int *ix, int *iy)
 {
     pixman_image_t *pixman_image;
@@ -1375,6 +1376,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
     cairo_extend_t extend;
     cairo_filter_t filter;
     double tx, ty;
+    cairo_bool_t undo_src_transform = FALSE;
 
     tx = pattern->base.matrix.x0;
     ty = pattern->base.matrix.y0;
@@ -1490,7 +1492,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
 	void *extra;
 	cairo_status_t status;
 
-	status = _cairo_surface_acquire_source_image (pattern->surface, &image, &extra);
+	status = _cairo_surface_acquire_source_image_transformed (pattern->surface, dst_device_transform, &image, &extra);
 	if (unlikely (status))
 	    return NULL;
 
@@ -1536,6 +1538,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
 	cleanup->image_extra = extra;
 	pixman_image_set_destroy_function (pixman_image,
 					   _acquire_source_cleanup, cleanup);
+	undo_src_transform = TRUE;
     }
 
     if (! _cairo_matrix_is_translation (&pattern->base.matrix) ||
@@ -1545,6 +1548,15 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
 	cairo_matrix_t m;
 
 	m = pattern->base.matrix;
+	if (undo_src_transform) {
+	    cairo_matrix_t sm;
+
+	    cairo_matrix_init_scale (&sm,
+				     dst_device_transform->xx,
+				     dst_device_transform->yy);
+	    cairo_matrix_multiply (&m, &m, &sm);
+	}
+
 	if (m.x0 != 0. || m.y0 != 0.) {
 	    cairo_matrix_t inv;
 	    cairo_status_t status;
@@ -1649,6 +1661,7 @@ static pixman_image_t *
 _pixman_image_for_pattern (const cairo_pattern_t *pattern,
 			   cairo_bool_t is_mask,
 			   const cairo_rectangle_int_t *extents,
+			   cairo_matrix_t *dst_device_transform,
 			   int *tx, int *ty)
 {
     *tx = *ty = 0;
@@ -1669,7 +1682,7 @@ _pixman_image_for_pattern (const cairo_pattern_t *pattern,
 
     case CAIRO_PATTERN_TYPE_SURFACE:
 	return _pixman_image_for_surface ((const cairo_surface_pattern_t *) pattern,
-					  is_mask, extents, tx, ty);
+					  is_mask, extents, dst_device_transform, tx, ty);
     }
 }
 
@@ -1907,6 +1920,7 @@ typedef cairo_status_t
 		      const cairo_pattern_t		*src,
 		      int				 dst_x,
 		      int				 dst_y,
+		      cairo_matrix_t 			*dst_device_transform,
 		      const cairo_rectangle_int_t	*extents,
 		      cairo_region_t			*clip_region);
 
@@ -1958,6 +1972,7 @@ _create_composite_mask_pattern (cairo_clip_t                  *clip,
 			mask, PIXMAN_a8,
 			CAIRO_OPERATOR_ADD, NULL,
 			extents->x, extents->y,
+			&dst->base.device_transform,
 			extents, NULL);
     if (unlikely (status)) {
 	pixman_image_unref (mask);
@@ -2034,7 +2049,7 @@ _clip_and_composite_with_mask (cairo_clip_t                  *clip,
 	pixman_image_t *src;
 	int src_x, src_y;
 
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
 	if (unlikely (src == NULL)) {
 	    pixman_image_unref (mask);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2082,6 +2097,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 			       tmp, dst->pixman_format,
 			       CAIRO_OPERATOR_ADD, NULL,
 			       extents->x, extents->y,
+			       &dst->base.device_transform,
 			       extents, NULL);
     } else {
 	/* Initialize the temporary surface from the destination surface */
@@ -2098,6 +2114,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 			       tmp, dst->pixman_format,
 			       op, src,
 			       extents->x, extents->y,
+			       &dst->base.device_transform,
 			       extents, NULL);
     }
     if (unlikely (status))
@@ -2181,6 +2198,7 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
 			    dst->pixman_image, dst->pixman_format,
 			    CAIRO_OPERATOR_SOURCE, NULL,
 			    extents->x, extents->y,
+			    &dst->base.device_transform,
 			    extents, NULL);
 	if (unlikely (status))
 	    return status;
@@ -2196,7 +2214,7 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
     if (unlikely (mask == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
     if (unlikely (src == NULL)) {
 	pixman_image_unref (mask);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2317,6 +2335,7 @@ _clip_and_composite (cairo_image_surface_t	*dst,
 				dst->pixman_image, dst->pixman_format,
 				op, src,
 				0, 0,
+				&dst->base.device_transform,
 				&extents->bounded,
 				clip_region);
 	}
@@ -2434,6 +2453,7 @@ _composite_traps (void                          *closure,
 		  const cairo_pattern_t         *pattern,
 		  int                            dst_x,
 		  int                            dst_y,
+		  cairo_matrix_t 		*dst_device_transform,
 		  const cairo_rectangle_int_t   *extents,
 		  cairo_region_t		*clip_region)
 {
@@ -2459,7 +2479,7 @@ _composite_traps (void                          *closure,
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2860,7 +2880,7 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
     if (unlikely (status))
 	goto CLEANUP;
 
-    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
     if (unlikely (src == NULL)) {
 	status =  _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
@@ -2977,7 +2997,7 @@ _composite_boxes (cairo_image_surface_t *dst,
 	}
 
 	if (pattern != NULL) {
-	    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &src_x, &src_y);
+	    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
 	    if (unlikely (src == NULL))
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	} else {
@@ -3314,6 +3334,7 @@ _composite_mask (void				*closure,
 		 const cairo_pattern_t		*src_pattern,
 		 int				 dst_x,
 		 int				 dst_y,
+		 cairo_matrix_t 		*dst_device_transform,
 		 const cairo_rectangle_int_t	*extents,
 		 cairo_region_t			*clip_region)
 {
@@ -3323,11 +3344,11 @@ _composite_mask (void				*closure,
     int mask_x = 0, mask_y = 0;
 
     if (src_pattern != NULL) {
-	src = _pixman_image_for_pattern (src_pattern, FALSE, extents, &src_x, &src_y);
+	src = _pixman_image_for_pattern (src_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
 	if (unlikely (src == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-	mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, &mask_x, &mask_y);
+	mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, dst_device_transform, &mask_x, &mask_y);
 	if (unlikely (mask == NULL)) {
 	    pixman_image_unref (src);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3336,7 +3357,7 @@ _composite_mask (void				*closure,
 	if (mask_pattern->has_component_alpha)
 	    pixman_image_set_component_alpha (mask, TRUE);
     } else {
-	src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, &src_x, &src_y);
+	src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
 	if (unlikely (src == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -3412,6 +3433,7 @@ _composite_spans (void                          *closure,
 		  const cairo_pattern_t         *pattern,
 		  int                            dst_x,
 		  int                            dst_y,
+		  cairo_matrix_t 		*dst_device_transform,
 		  const cairo_rectangle_int_t   *extents,
 		  cairo_region_t		*clip_region)
 {
@@ -3495,7 +3517,7 @@ _composite_spans (void                          *closure,
 	pixman_image_t *src;
 	int src_x, src_y;
 
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
 	if (unlikely (src == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto CLEANUP_RENDERER;
@@ -3786,6 +3808,7 @@ _composite_glyphs_via_mask (void			*closure,
 			    const cairo_pattern_t	*pattern,
 			    int				 dst_x,
 			    int				 dst_y,
+			    cairo_matrix_t 		*dst_device_transform,
 			    const cairo_rectangle_int_t	*extents,
 			    cairo_region_t		*clip_region)
 {
@@ -3801,7 +3824,7 @@ _composite_glyphs_via_mask (void			*closure,
     int src_x, src_y;
     int i;
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -3922,6 +3945,7 @@ _composite_glyphs (void				*closure,
 		   const cairo_pattern_t	*pattern,
 		   int				 dst_x,
 		   int				 dst_y,
+		   cairo_matrix_t 		*dst_device_transform,
 		   const cairo_rectangle_int_t	*extents,
 		   cairo_region_t		*clip_region)
 {
@@ -3934,7 +3958,7 @@ _composite_glyphs (void				*closure,
     int i;
 
     if (pattern != NULL) {
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
 	src_x -= dst_x;
 	src_y -= dst_y;
     } else {
@@ -4201,7 +4225,7 @@ _cairo_image_surface_composite (cairo_operator_t	 op,
 
     extents.is_bounded = _cairo_operator_bounded_by_either (op);
 
-    src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &src_offset_x, &src_offset_y);
+    src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &dst->base.device_transform, &src_offset_x, &src_offset_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -4210,7 +4234,7 @@ _cairo_image_surface_composite (cairo_operator_t	 op,
 	pixman_image_t *mask;
 	int mask_offset_x, mask_offset_y;
 
-	mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &mask_offset_x, &mask_offset_y);
+	mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &dst->base.device_transform, &mask_offset_x, &mask_offset_y);
 	if (unlikely (mask == NULL)) {
 	    pixman_image_unref (src);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4375,6 +4399,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t	op,
 			       op,
 			       &source_pattern.base,
 			       0, 0,
+			       &dst->base.device_transform,
 			       &extents.bounded,
 			       clip_region);
 
@@ -4479,7 +4504,7 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
 	    return status;
     }
 
-    src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &src_x, &src_y);
+    src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &renderer->dst->base.device_transform, &src_x, &src_y);
     if (src == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 0ac938b..3e4dd0c 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -249,13 +249,16 @@ _cairo_recording_surface_finish (void *abstract_surface)
 }
 
 static cairo_status_t
-_cairo_recording_surface_acquire_source_image (void			 *abstract_surface,
-					       cairo_image_surface_t	**image_out,
-					       void			**image_extra)
+_cairo_recording_surface_acquire_source_image_transformed (void			   *abstract_surface,
+							   cairo_matrix_t	   *device_transform,
+							   cairo_image_surface_t  **image_out,
+							   void			  **image_extra)
 {
     cairo_status_t status;
     cairo_recording_surface_t *surface = abstract_surface;
     cairo_surface_t *image;
+    double width;
+    double height;
 
     image = _cairo_surface_has_snapshot (&surface->base,
 					 &_cairo_image_surface_backend);
@@ -265,9 +268,10 @@ _cairo_recording_surface_acquire_source_image (void			 *abstract_surface,
 	return CAIRO_STATUS_SUCCESS;
     }
 
+    width = surface->extents.width * device_transform->xx;
+    height = surface->extents.height * device_transform->yy;
     image = _cairo_image_surface_create_with_content (surface->content,
-						      surface->extents.width,
-						      surface->extents.height);
+						      width, height);
     if (unlikely (image->status))
 	return image->status;
 
@@ -275,6 +279,8 @@ _cairo_recording_surface_acquire_source_image (void			 *abstract_surface,
 				     -surface->extents.x,
 				     -surface->extents.y);
 
+    _cairo_surface_set_device_scale (image,
+				     device_transform->xx, device_transform->yy);
     status = _cairo_recording_surface_replay (&surface->base, image);
     if (unlikely (status)) {
 	cairo_surface_destroy (image);
@@ -288,6 +294,19 @@ _cairo_recording_surface_acquire_source_image (void			 *abstract_surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_status_t
+_cairo_recording_surface_acquire_source_image (void			 *abstract_surface,
+					       cairo_image_surface_t	**image_out,
+					       void			**image_extra)
+{
+    cairo_matrix_t identity;
+
+    cairo_matrix_init_identity (&identity);
+
+    return _cairo_recording_surface_acquire_source_image_transformed (
+	abstract_surface, &identity, image_out, image_extra);
+}
+
 static void
 _cairo_recording_surface_release_source_image (void			*abstract_surface,
 					       cairo_image_surface_t	*image,
@@ -729,7 +748,8 @@ static const cairo_surface_backend_t cairo_recording_surface_backend = {
     NULL, /* can_repaint_solid_pattern_surface */
 
     _cairo_recording_surface_has_show_text_glyphs,
-    _cairo_recording_surface_show_text_glyphs
+    _cairo_recording_surface_show_text_glyphs,
+    _cairo_recording_surface_acquire_source_image_transformed
 };
 
 cairo_int_status_t
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 76f6447..ea9b0fe 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1458,6 +1458,33 @@ _cairo_surface_acquire_source_image (cairo_surface_t         *surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
+cairo_status_t
+_cairo_surface_acquire_source_image_transformed (cairo_surface_t	 *surface,
+						 cairo_matrix_t		 *device_transform,
+						 cairo_image_surface_t  **image_out,
+						 void                   **image_extra)
+{
+    cairo_status_t status;
+
+    if (surface->status)
+	return surface->status;
+
+    assert (!surface->finished);
+
+    if (surface->backend->acquire_source_image_transformed == NULL)
+	return _cairo_surface_acquire_source_image (surface,
+						    image_out, image_extra);
+
+    status = surface->backend->acquire_source_image_transformed (surface, device_transform,
+								 image_out, image_extra);
+    if (unlikely (status))
+	return _cairo_surface_set_error (surface, status);
+
+    _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 /**
  * _cairo_surface_release_source_image:
  * @surface: a #cairo_surface_t
diff --git a/src/cairoint.h b/src/cairoint.h
index cf0d459..f2c2e0f 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -856,6 +856,12 @@ struct _cairo_surface_backend {
 				 cairo_text_cluster_flags_t  cluster_flags,
 				 cairo_scaled_font_t	    *scaled_font,
 				 cairo_clip_t               *clip);
+
+    cairo_warn cairo_status_t
+    (*acquire_source_image_transformed)	(void                    *abstract_surface,
+					 cairo_matrix_t		 *device_transform,
+					 cairo_image_surface_t  **image_out,
+					 void                   **image_extra);
 };
 
 #include "cairo-surface-private.h"
@@ -1760,6 +1766,12 @@ _cairo_surface_acquire_source_image (cairo_surface_t         *surface,
 				     cairo_image_surface_t  **image_out,
 				     void                   **image_extra);
 
+cairo_private cairo_status_t
+_cairo_surface_acquire_source_image_transformed (cairo_surface_t         *surface,
+						 cairo_matrix_t		 *device_trasnform,
+						 cairo_image_surface_t  **image_out,
+						 void                   **image_extra);
+
 cairo_private void
 _cairo_surface_release_source_image (cairo_surface_t        *surface,
 				     cairo_image_surface_t  *image,


More information about the cairo-commit mailing list