[cairo-commit] 4 commits - src/cairo-clip.c src/cairo-quartz-surface.c src/cairo-xcb-private.h

Andrea Canciani ranma42 at kemper.freedesktop.org
Tue Jul 24 02:26:55 PDT 2012


 src/cairo-clip.c           |    2 
 src/cairo-quartz-surface.c |   94 ++++++++++++++++++++++++++++++++++-----------
 src/cairo-xcb-private.h    |    2 
 3 files changed, 77 insertions(+), 21 deletions(-)

New commits:
commit d00539ca13fbd36dea07b386211ad49ef744d5ee
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Tue Jul 24 10:21:08 2012 +0200

    quartz: Use the correct transform when replaying recording surfaces
    
    Recording surfaces should be replayed with the transform matrix used
    in the pattern, otherwise the image surface will be transformed,
    introducing artifacts.
    
    Fixes record{1414x,2x}-paint-alpha-{,solid-clip,clip},
    record2x-{self-intersecting,text-transform} and record90-paint-alpha.

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 6bb0e2b..1e2bbec 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -786,6 +786,7 @@ static cairo_status_t
 _cairo_surface_to_cgimage (cairo_surface_t       *source,
 			   cairo_rectangle_int_t *extents,
 			   cairo_format_t         format,
+			   cairo_matrix_t        *matrix,
 			   const cairo_clip_t    *clip,
 			   CGImageRef            *image_out)
 {
@@ -830,7 +831,7 @@ _cairo_surface_to_cgimage (cairo_surface_t       *source,
 	}
 
 	status = _cairo_recording_surface_replay_with_clip (source,
-							    NULL,
+							    matrix,
 							    &image_surface->base,
 							    NULL);
 	if (unlikely (status)) {
@@ -841,6 +842,8 @@ _cairo_surface_to_cgimage (cairo_surface_t       *source,
 
 	source_img->image_out = image_surface;
 	source_img->image_extra = NULL;
+
+	cairo_matrix_init_identity (matrix);
     }
     else {
 	status = _cairo_surface_acquire_source_image (source_img->surface,
@@ -963,8 +966,9 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
     else
 	_cairo_surface_get_extents (&dest->base, &extents);
 
+    m = spattern->base.matrix;
     status = _cairo_surface_to_cgimage (pat_surf, &extents, format,
-					clip, &image);
+					&m, clip, &image);
     if (unlikely (status))
 	return status;
 
@@ -999,7 +1003,6 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
     rw = pbounds.size.width;
     rh = pbounds.size.height;
 
-    m = spattern->base.matrix;
     cairo_matrix_invert (&m);
     _cairo_quartz_cairo_matrix_to_quartz (&m, &stransform);
 
@@ -1247,7 +1250,7 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
 
 	_cairo_surface_get_extents (composite->surface, &extents);
 	status = _cairo_surface_to_cgimage (pat_surf, &extents, format,
-					    clip, &img);
+					    &m, clip, &img);
 	if (unlikely (status))
 	    return status;
 
@@ -1650,10 +1653,11 @@ _cairo_quartz_cg_mask_with_surface (cairo_composite_rectangles_t *extents,
     cairo_quartz_drawing_state_t state;
     cairo_format_t format = _cairo_format_from_content (extents->surface->content);
     cairo_rectangle_int_t dest_extents;
+    cairo_matrix_t m = *mask_mat;
 
     _cairo_surface_get_extents (extents->surface, &dest_extents);
     status = _cairo_surface_to_cgimage (mask_surf, &dest_extents, format,
-					extents->clip, &img);
+					&m, extents->clip, &img);
     if (unlikely (status))
 	return status;
 
@@ -1662,7 +1666,7 @@ _cairo_quartz_cg_mask_with_surface (cairo_composite_rectangles_t *extents,
 	goto BAIL;
 
     rect = CGRectMake (0.0, 0.0, CGImageGetWidth (img), CGImageGetHeight (img));
-    _cairo_quartz_cairo_matrix_to_quartz (mask_mat, &mask_matrix);
+    _cairo_quartz_cairo_matrix_to_quartz (&m, &mask_matrix);
 
     /* ClipToMask is essentially drawing an image, so we need to flip the CTM
      * to get the image to appear oriented the right way */
commit 44a07a66135c4f534c909bd84f24cf7c0275a914
Author: Henry (Yu) Song - SISA <hsong at sisa.samsung.com>
Date:   Mon Jul 23 16:28:28 2012 +0000

    quartz: Never acquire recording surfaces
    
    We need to replay if the source/mask surface is a recording surface
    otherwise, a crash happens if it is unbounded.
    
    Fixes crashes in recordxx-xxx tests

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 7c8c453..6bb0e2b 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -47,6 +47,7 @@
 #include "cairo-pattern-private.h"
 #include "cairo-surface-backend-private.h"
 #include "cairo-surface-clipper-private.h"
+#include "cairo-recording-surface-private.h"
 
 #include <dlfcn.h>
 
@@ -782,11 +783,15 @@ DataProviderReleaseCallback (void *info, const void *data, size_t size)
 }
 
 static cairo_status_t
-_cairo_surface_to_cgimage (cairo_surface_t *source,
-			   CGImageRef *image_out)
+_cairo_surface_to_cgimage (cairo_surface_t       *source,
+			   cairo_rectangle_int_t *extents,
+			   cairo_format_t         format,
+			   const cairo_clip_t    *clip,
+			   CGImageRef            *image_out)
 {
     cairo_status_t status;
     quartz_source_image_t *source_img;
+    cairo_image_surface_t *image_surface;
 
     if (source->backend && source->backend->type == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
 	cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source;
@@ -814,10 +819,37 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
 
     source_img->surface = source;
 
-    status = _cairo_surface_acquire_source_image (source_img->surface, &source_img->image_out, &source_img->image_extra);
-    if (unlikely (status)) {
-	free (source_img);
-	return status;
+    if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
+	image_surface = (cairo_image_surface_t *)
+	    cairo_image_surface_create (format, extents->width, extents->height);
+	if (unlikely (image_surface->base.status)) {
+	    status = image_surface->base.status;
+	    cairo_surface_destroy (&image_surface->base);
+	    free (source_img);
+	    return status;
+	}
+
+	status = _cairo_recording_surface_replay_with_clip (source,
+							    NULL,
+							    &image_surface->base,
+							    NULL);
+	if (unlikely (status)) {
+	    cairo_surface_destroy (&image_surface->base);
+	    free (source_img);
+	    return status;
+	}
+
+	source_img->image_out = image_surface;
+	source_img->image_extra = NULL;
+    }
+    else {
+	status = _cairo_surface_acquire_source_image (source_img->surface,
+						      &source_img->image_out,
+						      &source_img->image_extra);
+	if (unlikely (status)) {
+	    free (source_img);
+	    return status;
+	}
     }
 
     if (source_img->image_out->width == 0 || source_img->image_out->height == 0) {
@@ -897,11 +929,13 @@ SurfacePatternReleaseInfoFunc (void *ainfo)
 static cairo_int_status_t
 _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t *dest,
 							 const cairo_pattern_t *apattern,
+							 const cairo_clip_t *clip,
 							 CGPatternRef *cgpat)
 {
     cairo_surface_pattern_t *spattern;
     cairo_surface_t *pat_surf;
     cairo_rectangle_int_t extents;
+    cairo_format_t format = _cairo_format_from_content (dest->base.content);
 
     CGImageRef image;
     CGRect pbounds;
@@ -922,10 +956,15 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
     spattern = (cairo_surface_pattern_t *) apattern;
     pat_surf = spattern->surface;
 
-    is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
-    assert (is_bounded);
+    if (pat_surf->type != CAIRO_SURFACE_TYPE_RECORDING) {
+	is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
+	assert (is_bounded);
+    }
+    else
+	_cairo_surface_get_extents (&dest->base, &extents);
 
-    status = _cairo_surface_to_cgimage (pat_surf, &image);
+    status = _cairo_surface_to_cgimage (pat_surf, &extents, format,
+					clip, &image);
     if (unlikely (status))
 	return status;
 
@@ -1084,14 +1123,15 @@ _cairo_quartz_setup_gradient_source (cairo_quartz_drawing_state_t *state,
 
 static cairo_int_status_t
 _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
-			   cairo_composite_rectangles_t *extents)
+			   cairo_composite_rectangles_t *composite)
 {
-    cairo_quartz_surface_t       *surface = (cairo_quartz_surface_t *) extents->surface;
-    cairo_operator_t              op = extents->op;
-    const cairo_pattern_t        *source = &extents->source_pattern.base;
-    const cairo_clip_t           *clip = extents->clip;
+    cairo_quartz_surface_t       *surface = (cairo_quartz_surface_t *) composite->surface;
+    cairo_operator_t              op = composite->op;
+    const cairo_pattern_t        *source = &composite->source_pattern.base;
+    const cairo_clip_t           *clip = composite->clip;
     cairo_bool_t needs_temp;
     cairo_status_t status;
+    cairo_format_t format = _cairo_format_from_content (composite->surface->content);
 
     state->layer = NULL;
     state->image = NULL;
@@ -1205,7 +1245,9 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
 	cairo_fixed_t fw, fh;
 	cairo_bool_t is_bounded;
 
-	status = _cairo_surface_to_cgimage (pat_surf, &img);
+	_cairo_surface_get_extents (composite->surface, &extents);
+	status = _cairo_surface_to_cgimage (pat_surf, &extents, format,
+					    clip, &img);
 	if (unlikely (status))
 	    return status;
 
@@ -1220,8 +1262,10 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
 
 	_cairo_quartz_cairo_matrix_to_quartz (&m, &state->transform);
 
-	is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
-	assert (is_bounded);
+	if (pat_surf->type != CAIRO_SURFACE_TYPE_RECORDING) {
+	    is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
+	    assert (is_bounded);
+	}
 
 	srcRect = CGRectMake (0, 0, extents.width, extents.height);
 
@@ -1291,7 +1335,7 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
 	CGPatternRef pattern = NULL;
 	cairo_int_status_t status;
 
-	status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, &pattern);
+	status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, clip, &pattern);
 	if (unlikely (status))
 	    return status;
 
@@ -1604,8 +1648,12 @@ _cairo_quartz_cg_mask_with_surface (cairo_composite_rectangles_t *extents,
     cairo_status_t status;
     CGAffineTransform mask_matrix;
     cairo_quartz_drawing_state_t state;
+    cairo_format_t format = _cairo_format_from_content (extents->surface->content);
+    cairo_rectangle_int_t dest_extents;
 
-    status = _cairo_surface_to_cgimage (mask_surf, &img);
+    _cairo_surface_get_extents (extents->surface, &dest_extents);
+    status = _cairo_surface_to_cgimage (mask_surf, &dest_extents, format,
+					extents->clip, &img);
     if (unlikely (status))
 	return status;
 
commit 459c060b6fcc0a3b7e6f0e544fe83f954a5ca716
Author: Henry (Yu) Song - SISA <hsong at sisa.samsung.com>
Date:   Tue Jul 24 02:05:15 2012 +0000

    clip: Transform clip path in _cairo_clip_intersect_clip_path_transformed()
    
    _cairo_clip_intersect_clip_path_transformed() completely ignored the
    transformation matrix instead of transforming all the clip paths with
    it.
    
    This caused bugs when replaying recording surfaces.
    
    Fixes record{2x,1414x,90}-paint-alpha-clip-mask.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index bd70c06..0df9b06 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -536,6 +536,8 @@ _cairo_clip_intersect_clip_path_transformed (cairo_clip_t *clip,
     if (_cairo_path_fixed_init_copy (&path, &clip_path->path))
 	return _cairo_clip_set_all_clipped (clip);
 
+    _cairo_path_fixed_transform (&path, m);
+
     clip =  _cairo_clip_intersect_path (clip,
 				       &path,
 				       clip_path->fill_rule,
commit 5f1dd8b3684db5aed42f355fa41310639e7d395d
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Tue Jul 24 09:56:52 2012 +0200

    xcb: Fix make check
    
    The xcb private header uses the ASSERT_NOT_REACHED macro.
    This macro is defined in cairoint.h, which needs to be included.
    
    Fixes:
    
      CHECK cairo-xcb-private.h
    In file included from headers-standalone-tmp.c:1:
    ./cairo-xcb-private.h: In function ‘_cairo_xcb_connection_shm_put_image’:
    ./cairo-xcb-private.h:636: error: ‘ASSERT_NOT_REACHED’ undeclared (first use in this function)
    ./cairo-xcb-private.h:636: error: (Each undeclared identifier is reported only once
    ./cairo-xcb-private.h:636: error: for each function it appears in.)

diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 1df5a11..7c9af8f 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -39,6 +39,8 @@
 
 #include "cairo-xcb.h"
 
+#include "cairoint.h"
+
 #include "cairo-cache-private.h"
 #include "cairo-compiler-private.h"
 #include "cairo-device-private.h"


More information about the cairo-commit mailing list