[cairo] Idle thoughts on error propagation

Chris Wilson chris at chris-wilson.co.uk
Thu May 1 14:46:39 PDT 2008

Whilst playing with CAIRO_DEBUG, I noticed firefox3 hit the following
error point:

    cairo_matrix_init_scale (&tmp, sx, sy);
    cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);

    /* paranoid check against gradual numerical instability */
    if (! _cairo_matrix_is_invertible (&gstate->ctm))
	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);

firefox3 does check the error status of their surfaces, but never checks
for an error on the context and thus misses this error.

Similarly in the test harnesses, we tend to have to write the seemingly
   surface = cairo_surface_create ();
   cr = cairo_create (surface);
   /* do stuff */
   status = cairo_status (cr);
   cairo_destroy (cr);
   if (status) {
       cairo_surface_destroy (surface);
       return ERROR;
   status = cairo_surface_status (surface);
   cairo_surface_destroy (surface);
   if (status)
       return ERROR;

since all surface errors are propagated to the context, but (like above)
context errors are not propagated to the surface. Ideally (like firefox)
we'd like to write:
   surface = cairo_surface_create ();
   cr = cairo_create (surface);
   /* do stuff */
   cairo_destroy (cr);
   status = cairo_surface_destroy (surface);
   if (status)
       return ERROR;

As this also correctly propagates the drawing error into any patterns
derived from the surface.

Basically, I'm thinking along the lines of:
diff --git a/src/cairo.c b/src/cairo.c
index e44fbef..8a60b5b 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -116,6 +116,9 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
      * error, which is the most significant. */
     _cairo_status_set_error (&cr->status, status);
+    if (cr->gstate != NULL && cr->gstate->original_target != NULL)
+       status = _cairo_surface_set_error (cr->gstate->original_target, status);
     status = _cairo_error (status);

Just an idle thought. :-)
Chris Wilson

More information about the cairo mailing list