[cairo-commit] 4 commits - src/cairo-analysis-surface.c src/cairo-pdf-surface.c test/mask-transformed-similar-pdf-ref.png

Carl Worth cworth at kemper.freedesktop.org
Thu Sep 25 02:18:19 PDT 2008


 src/cairo-analysis-surface.c              |   76 ++++++++++++++++--------------
 src/cairo-pdf-surface.c                   |   34 +++++++++----
 test/mask-transformed-similar-pdf-ref.png |binary
 3 files changed, 67 insertions(+), 43 deletions(-)

New commits:
commit 503506bf0dbfbc0be92f1461afa8683227732809
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Sep 25 02:16:47 2008 -0700

    Add pdf-specific reference image for mask-transformed-similar
    
    Thanks to help from Chris, we fixed the bug that was making this
    test fail with the PDF backend. All that was left was differing
    treatment of the edges of the image---easy enough to address
    with a pdf-specific reference image.

diff --git a/test/mask-transformed-similar-pdf-ref.png b/test/mask-transformed-similar-pdf-ref.png
new file mode 100644
index 0000000..e8d3879
Binary files /dev/null and b/test/mask-transformed-similar-pdf-ref.png differ
commit 31ff6c863ff82bd7339a03297e4b5a9adea0b1c9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 25 09:47:58 2008 +0100

    [pdf] Explicitly order the sequence of checks when analyzing masks
    
    There is an implicit precedence when analyzing patterns for
    compatibilty, in order of descending precedence:
      fatal error
      unsupported
      needs image fallback
      needs meta-surface analysis
      success.
    
    So wehen we have two patterns, we need to check both analysis statuses
    simulataneously, in order to correctly report the combined status.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f6f8679..f96e1fc 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -4466,19 +4466,35 @@ _cairo_pdf_surface_mask	(void			*abstract_surface,
 {
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_pdf_smask_group_t *group;
-    cairo_status_t status, status2;
+    cairo_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
-	status = _cairo_pdf_surface_analyze_operation (surface, op, source);
-	if (status != CAIRO_STATUS_SUCCESS &&
-	    status != CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	    return status;
+	cairo_status_t source_status, mask_status;
 
-	status2 = _cairo_pdf_surface_analyze_operation (surface, op, mask);
-	if (status2 != CAIRO_STATUS_SUCCESS)
-	    return status2;
+	source_status =  _cairo_pdf_surface_analyze_operation (surface, op, source);
+	if (source_status != CAIRO_STATUS_SUCCESS &&
+	    source_status < CAIRO_INT_STATUS_UNSUPPORTED)
+	    return source_status;
 
-	return status;
+	mask_status = _cairo_pdf_surface_analyze_operation (surface, op, mask);
+	if (mask_status != CAIRO_STATUS_SUCCESS &&
+	    mask_status < CAIRO_INT_STATUS_UNSUPPORTED)
+	    return mask_status;
+
+	/* return the most important status from either the source or mask */
+	if (source_status == CAIRO_INT_STATUS_UNSUPPORTED ||
+	    mask_status == CAIRO_INT_STATUS_UNSUPPORTED)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	if (source_status == CAIRO_INT_STATUS_IMAGE_FALLBACK ||
+	    mask_status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
+	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+
+	if (source_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN ||
+	    mask_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	    return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
+
+	return CAIRO_STATUS_SUCCESS;
     } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
 	status = _cairo_pdf_surface_start_fallback (surface);
 	if (status)
commit 69635bc054a823afe1ca378fffac1b2daabdf594
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Sep 25 01:52:45 2008 -0700

    Fix the analysis of mask operations (fixing mask-transformed-similar test case)
    
    The primary bug here was some missing braces. The code was conditionally
    assigning to backend_status, but then unconditionally checking for the
    value assigned. The result was the leaking of an internal status value
    (CAIRO_INT_STATUS_ANALYZE_META_SURFACE) which finally resulted in
    an incomplete PDF file in the mask-transformed-similar test case.
    
    While fixing this, also avoid re-using the backend_status variable so
    much so that the code is more readable.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 0b5b48f..ed3c9ef 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -331,7 +331,7 @@ _cairo_analysis_surface_mask (void		*abstract_surface,
 			      cairo_pattern_t	*mask)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	      status, backend_status;
+    cairo_int_status_t	      status, backend_status;
     cairo_rectangle_int_t   extents;
 
     if (!surface->target->backend->mask)
@@ -341,22 +341,37 @@ _cairo_analysis_surface_mask (void		*abstract_surface,
                                                             source, mask);
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
+	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
+	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
+
 	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source;
-	    if (_cairo_surface_is_meta (surface_pattern->surface))
-		backend_status = _analyze_meta_surface_pattern (surface, source);
-	    if (backend_status != CAIRO_STATUS_SUCCESS &&
-		backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
-		return backend_status;
+	    if (_cairo_surface_is_meta (surface_pattern->surface)) {
+		backend_source_status =
+		    _analyze_meta_surface_pattern (surface, source);
+		if (backend_source_status != CAIRO_STATUS_SUCCESS &&
+		    backend_source_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
+		    return backend_source_status;
+	    }
 	}
 
 	if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
-	    if (_cairo_surface_is_meta (surface_pattern->surface))
-		backend_status = _analyze_meta_surface_pattern (surface, mask);
-	    if (backend_status != CAIRO_STATUS_SUCCESS &&
-		backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
-		return backend_status;
+	    if (_cairo_surface_is_meta (surface_pattern->surface)) {
+		backend_mask_status =
+		    _analyze_meta_surface_pattern (surface, mask);
+		if (backend_mask_status != CAIRO_STATUS_SUCCESS &&
+		    backend_mask_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
+		    return backend_status;
+	    }
+	}
+
+	backend_status = CAIRO_STATUS_SUCCESS;
+
+	if (backend_source_status == CAIRO_INT_STATUS_IMAGE_FALLBACK ||
+	    backend_mask_status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
+	{
+	    backend_status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
 	}
     }
 
commit 5599b08dfaf5897f58b3456732dc9c241502b4c4
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Sep 25 01:42:03 2008 -0700

    Drop _cairo_analysis_surface prefix from some static functions
    
    Since these functions are static we don't really need the full
    name. And these two functions were both so long that they were
    causing some serious line-wrap issues.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 0b74a5e..0b5b48f 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -63,8 +63,8 @@ typedef struct {
 } cairo_analysis_surface_t;
 
 static cairo_int_status_t
-_cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
-						      cairo_pattern_t	       *pattern)
+_analyze_meta_surface_pattern (cairo_analysis_surface_t	*surface,
+			       cairo_pattern_t		*pattern)
 {
     cairo_surface_t *analysis = &surface->base;
     cairo_surface_pattern_t *surface_pattern;
@@ -118,9 +118,9 @@ _cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *
 }
 
 static cairo_int_status_t
-_cairo_analysis_surface_add_operation  (cairo_analysis_surface_t *surface,
-					cairo_rectangle_int_t    *rect,
-					cairo_int_status_t        backend_status)
+_add_operation  (cairo_analysis_surface_t *surface,
+		 cairo_rectangle_int_t    *rect,
+		 cairo_int_status_t        backend_status)
 {
     cairo_int_status_t status;
     cairo_box_t bbox;
@@ -302,8 +302,7 @@ _cairo_analysis_surface_paint (void			*abstract_surface,
                                                              source);
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-									       source);
+	backend_status = _analyze_meta_surface_pattern (surface, source);
 
     status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -320,7 +319,7 @@ _cairo_analysis_surface_paint (void			*abstract_surface,
 
     _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -345,8 +344,7 @@ _cairo_analysis_surface_mask (void		*abstract_surface,
 	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source;
 	    if (_cairo_surface_is_meta (surface_pattern->surface))
-		backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-										       source);
+		backend_status = _analyze_meta_surface_pattern (surface, source);
 	    if (backend_status != CAIRO_STATUS_SUCCESS &&
 		backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
 		return backend_status;
@@ -355,8 +353,7 @@ _cairo_analysis_surface_mask (void		*abstract_surface,
 	if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
 	    if (_cairo_surface_is_meta (surface_pattern->surface))
-		backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-										       mask);
+		backend_status = _analyze_meta_surface_pattern (surface, mask);
 	    if (backend_status != CAIRO_STATUS_SUCCESS &&
 		backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
 		return backend_status;
@@ -384,7 +381,7 @@ _cairo_analysis_surface_mask (void		*abstract_surface,
 
     _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -414,8 +411,7 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 							      tolerance, antialias);
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-									       source);
+	backend_status = _analyze_meta_surface_pattern (surface, source);
 
     status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -455,7 +451,7 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
         _cairo_box_round_to_rectangle (&box, &extents);
     }
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -482,8 +478,7 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 						    tolerance, antialias);
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-									       source);
+	backend_status = _analyze_meta_surface_pattern (surface, source);
 
     status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -522,7 +517,7 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
         _cairo_box_round_to_rectangle (&box, &extents);
     }
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -559,8 +554,7 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-									       source);
+	backend_status = _analyze_meta_surface_pattern (surface, source);
 
     status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -588,7 +582,7 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 	_cairo_rectangle_intersect (&extents, &glyph_extents);
     }
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -641,8 +635,7 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
     }
 
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
-	backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
-									       source);
+	backend_status = _analyze_meta_surface_pattern (surface, source);
 
     status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -670,7 +663,7 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
 	_cairo_rectangle_intersect (&extents, &glyph_extents);
     }
 
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
 
     return status;
 }


More information about the cairo-commit mailing list