[cairo-commit] 5 commits - configure.in src/cairo-analysis-surface.c src/cairo-gstate.c src/cairo-output-stream.c src/cairo-png.c src/cairo-ps-surface.c src/cairo-traps.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Jan 5 13:40:33 PST 2008


 configure.in                 |    2 +-
 src/cairo-analysis-surface.c |   18 ++++++++++++------
 src/cairo-gstate.c           |    6 +++---
 src/cairo-output-stream.c    |   12 ++++++++++--
 src/cairo-png.c              |   10 ++++++++--
 src/cairo-ps-surface.c       |   18 ++++++++++++++++--
 src/cairo-traps.c            |    6 +++++-
 7 files changed, 55 insertions(+), 17 deletions(-)

New commits:
commit f440d894e668994721248dc6c95a936a839870db
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 5 21:20:45 2008 +0000

    Check errno for appropriate error return.
    
    After using fopen() and friends check the global errno to determine the
    most  appropriate error return - especially important when running
    memfault, where correct reporting of NO_MEMORY errors is required.

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index b8fb706..6451b0f 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -38,8 +38,10 @@
 
 #include "cairo-output-stream-private.h"
 
+#include <stdio.h>
 #include <locale.h>
 #include <ctype.h>
+#include <errno.h>
 
 #ifdef _MSC_VER
 #define snprintf _snprintf
@@ -538,8 +540,14 @@ _cairo_output_stream_create_for_filename (const char *filename)
 
     file = fopen (filename, "wb");
     if (file == NULL) {
-	_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
-	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
+	switch (errno) {
+	case ENOMEM:
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+	default:
+	    _cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
+	    return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
+	}
     }
 
     stream = malloc (sizeof *stream);
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 67c87fd..b76b525 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -275,8 +275,14 @@ cairo_surface_write_to_png (cairo_surface_t	*surface,
     cairo_status_t status;
 
     fp = fopen (filename, "wb");
-    if (fp == NULL)
-	return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
+    if (fp == NULL) {
+	switch (errno) {
+	case ENOMEM:
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	default:
+	    return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
+	}
+    }
 
     status = write_png (surface, stdio_write_func, fp);
 
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 4f91738..b6c6c9b 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -47,9 +47,11 @@
 #include "cairo-meta-surface-private.h"
 #include "cairo-output-stream-private.h"
 
+#include <stdio.h>
 #include <ctype.h>
 #include <time.h>
 #include <zlib.h>
+#include <errno.h>
 
 #define DEBUG_PS 0
 
@@ -943,7 +945,14 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
 
     surface->tmpfile = tmpfile ();
     if (surface->tmpfile == NULL) {
-	status = _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
+	switch (errno) {
+	case ENOMEM:
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    break;
+	default:
+	    status = _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
+	    break;
+	}
 	goto CLEANUP_SURFACE;
     }
 
commit 68a441e582c6c887e65800302906ddd35cb0291e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 5 19:34:42 2008 +0000

    [cairo-analysis-surface] Return early if the traps is empty.
    
    If the mask is empty, there is nothing to do, so return an early SUCCESS.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index b4213b2..b6f09f8 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -410,7 +410,7 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 						    tolerance,
 						    &traps);
 
-	if (status) {
+	if (status || traps.num_traps == 0) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
@@ -433,9 +433,9 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 			      cairo_operator_t		 op,
 			      cairo_pattern_t		*source,
 			      cairo_path_fixed_t	*path,
-			      cairo_fill_rule_t	 	 fill_rule,
+			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
-			      cairo_antialias_t	 	 antialias)
+			      cairo_antialias_t		 antialias)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_status_t	     status, backend_status;
@@ -482,7 +482,7 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 						  tolerance,
 						  &traps);
 
-	if (status) {
+	if (status || traps.num_traps == 0) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
commit 481fd3b4c8d3972ce21399f81b2021a57ed58f00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 5 19:33:21 2008 +0000

    [cairo-traps] Return zero extents if it contains no traps.
    
    Previously, _cairo_traps_extents () returned the extents
    p1={INT_MAX, INT_MAX} p2={INT_MIN, INT_MIN} for an empty traps leading
    to integer overflow when computing the width using p2-p1 and causing
    further overflows within libpixman. [For example this caused the
    allocation of massive regions with test/mask and the PS backend.]

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index ae870a2..5c626cd 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1133,9 +1133,7 @@ _cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t	  *gstate,
 {
     cairo_box_t extents;
 
-    _cairo_traps_extents (traps, &extents);
-
-    if (extents.p1.x >= extents.p2.x || extents.p1.y >= extents.p2.y) {
+    if (traps->num_traps == 0) {
         /* no traps, so we actually won't draw anything */
 	if (x1)
 	    *x1 = 0.0;
@@ -1146,6 +1144,8 @@ _cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t	  *gstate,
 	if (y2)
 	    *y2 = 0.0;
     } else {
+	_cairo_traps_extents (traps, &extents);
+
 	if (x1)
 	    *x1 = _cairo_fixed_to_double (extents.p1.x);
 	if (y1)
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index d5e7532..41e18e9 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -568,7 +568,11 @@ _cairo_traps_contain (cairo_traps_t *traps, double x, double y)
 void
 _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents)
 {
-    *extents = traps->extents;
+    if (traps->num_traps == 0) {
+	extents->p1.x = extents->p1.y = _cairo_fixed_from_int (0);
+	extents->p2.y = extents->p2.y = _cairo_fixed_from_int (0);
+    } else
+	*extents = traps->extents;
 }
 
 /**
commit be126b6842e979dbcb306b2f9f41a2114a149b9a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 5 19:22:57 2008 +0000

    [cairo-analysis-surface] Check for an empty transformed bbox.
    
    After transforming the bbox, check that it has not been projected into
    an empty box.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 1276a35..b4213b2 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -115,8 +115,14 @@ _cairo_analysis_surface_add_operation  (cairo_analysis_surface_t *surface,
 					      NULL);
 	rect->x = floor (x1);
 	rect->y = floor (x2);
-	rect->width = ceil (x2) - rect->x;
-	rect->height = ceil (y2) - rect->y;
+
+	x2 = ceil (x2) - rect->x;
+	y2 = ceil (y2) - rect->y;
+	if (x2 <= 0 || y2 <= 0)
+	    return CAIRO_STATUS_SUCCESS;
+
+	rect->width  = x2;
+	rect->height = y2;
     }
 
     bbox.p1.x = _cairo_fixed_from_int (rect->x);
commit d9461733af36f2960525a9b33accf500447f5c64
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 4 16:43:54 2008 +0000

    [cairo-ps-surface] Use ctime_r when available.
    
    Use the thread-safe (and non-allocating) ctime_r() instead of ctime()
    if supported by the platform.

diff --git a/configure.in b/configure.in
index a5ca71c..7de0f4d 100644
--- a/configure.in
+++ b/configure.in
@@ -87,7 +87,7 @@ AC_DEFUN([_CHECK_FUNCS_WITH_FLAGS],
 
 dnl ===========================================================================
 
-AC_CHECK_FUNCS(vasnprintf)
+AC_CHECK_FUNCS(vasnprintf ctime_r)
 	
 dnl ===========================================================================
 dnl
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c1a8cc3..4f91738 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -53,6 +53,10 @@
 
 #define DEBUG_PS 0
 
+#ifndef HAVE_CTIME_R
+#define ctime_r(T, BUF) ctime (T)
+#endif
+
 typedef enum _cairo_image_transparency {
     CAIRO_IMAGE_IS_OPAQUE,
     CAIRO_IMAGE_HAS_BILEVEL_ALPHA,
@@ -318,6 +322,7 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t	   *surface,
 static void
 _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
 {
+    char ctime_buf[26];
     time_t now;
     char **comments;
     int i, num_comments;
@@ -342,7 +347,7 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
 				 "%%%%BoundingBox: %d %d %d %d\n",
 				 eps_header,
 				 cairo_version_string (),
-				 ctime (&now),
+				 ctime_r (&now, ctime_buf),
 				 surface->num_pages,
 				 surface->bbox_x1,
 				 surface->bbox_y1,


More information about the cairo-commit mailing list