[cairo] [PATCH 09/39] [OpenVG] Made the source paint object live in the surface

tardyp at gmail.com tardyp at gmail.com
Fri Jul 10 10:02:11 PDT 2009


From: Øyvind Kolås <pippin at gimp.org>

(source image will live there as well later). Made the source preparation
functions take the surface instead of a paint object as a parameter.
---
 src/cairo-openvg-surface.c |  155 ++++++++++++++++++++++++++------------------
 1 files changed, 91 insertions(+), 64 deletions(-)

diff --git a/src/cairo-openvg-surface.c b/src/cairo-openvg-surface.c
index 1068028..54ad794 100644
--- a/src/cairo-openvg-surface.c
+++ b/src/cairo-openvg-surface.c
@@ -44,14 +44,14 @@ typedef struct cairo_openvg_surface {
     int             width;
     int             height;
 
-    VGImage         source_image;
+    VGPaint         source_paint;
 } cairo_openvg_surface_t;
 
 static cairo_surface_t *
 _cairo_openvg_surface_create_similar (void *asurface,
-                                   cairo_content_t content,
-                                   int width,
-                                   int height)
+                                      cairo_content_t content,
+                                      int width,
+                                      int height)
 {
     return cairo_openvg_surface_create(width, height);
 }
@@ -307,8 +307,8 @@ _cairo_openvg_cairo_matrix_to_openvg (const cairo_matrix_t *src,
     dst[8] = /* w2  */ 0;
 }
 
-static void
-_cairo_openvg_setup_gradient_stops (VGPaint paint,
+static cairo_status_t
+_cairo_openvg_setup_gradient_stops (cairo_openvg_surface_t   *vgsurface,
                                     cairo_gradient_pattern_t *pattern)
 {
   VGint numstops = pattern->n_stops;
@@ -318,7 +318,7 @@ _cairo_openvg_setup_gradient_stops (VGPaint paint,
   stops = malloc (sizeof (VGfloat) * numstops * 5); 
   if (stops == NULL)
     {
-      return; /* FIXME: report error state */
+      return CAIRO_STATUS_NO_MEMORY;
     }
 
   for (i=0; i< numstops; i++)
@@ -329,28 +329,29 @@ _cairo_openvg_setup_gradient_stops (VGPaint paint,
       stops[i*5 + 3] = pattern->stops[i].color.blue;
       stops[i*5 + 4] = pattern->stops[i].color.alpha;
     }
-  vgSetParameterfv (paint, VG_PAINT_COLOR_RAMP_STOPS, numstops * 5, stops);
+  vgSetParameterfv (vgsurface->source_paint,
+                    VG_PAINT_COLOR_RAMP_STOPS, numstops * 5, stops);
   free (stops);
+  return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-_cairo_openvg_setup_linear_source (VGPaint paint,
+static cairo_status_t
+_cairo_openvg_setup_linear_source (cairo_openvg_surface_t *vgsurface,
                                    cairo_linear_pattern_t *lpat)
 {
+  cairo_status_t status;
   cairo_pattern_t *abspat = (cairo_pattern_t *) lpat;
   cairo_matrix_t   mat;
   VGfloat linear[4];
   double x0, y0;
   double x1, y1;
 
-
   cairo_pattern_get_matrix (abspat, &mat);
 
-  if (cairo_matrix_invert (&mat) == CAIRO_STATUS_INVALID_MATRIX)
-    {
-      /* FIXME: pass on error */
-      return;
-    }
+  status = cairo_matrix_invert (&mat);
+  if (status)
+   return status;
+
   x0 = _cairo_fixed_to_double (lpat->p1.x);
   y0 = _cairo_fixed_to_double (lpat->p1.y);
   x1 = _cairo_fixed_to_double (lpat->p2.x);
@@ -364,17 +365,19 @@ _cairo_openvg_setup_linear_source (VGPaint paint,
   linear[2] = x1;
   linear[3] = y1;
 
-  vgSetParameteri (paint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
-  vgSetParameteri (paint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
-  vgSetParameterfv (paint, VG_PAINT_LINEAR_GRADIENT, 4, linear);
+  vgSetParameteri (vgsurface->source_paint,
+                   VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
+  vgSetParameteri (vgsurface->source_paint,
+                   VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
+  vgSetParameterfv (vgsurface->source_paint, VG_PAINT_LINEAR_GRADIENT, 4, linear);
 
-  _cairo_openvg_setup_gradient_stops (paint,
-                                      (cairo_gradient_pattern_t *) &lpat->base);
+  return _cairo_openvg_setup_gradient_stops (vgsurface,
+                               (cairo_gradient_pattern_t *) &lpat->base);
 
 }
 
-static void
-_cairo_openvg_setup_radial_source (VGPaint paint,
+static cairo_status_t
+_cairo_openvg_setup_radial_source (cairo_openvg_surface_t *vgsurface,
                                    cairo_radial_pattern_t *rpat)
 {
   cairo_pattern_t *abspat = (cairo_pattern_t *) rpat;
@@ -388,8 +391,7 @@ _cairo_openvg_setup_radial_source (VGPaint paint,
 
   if (cairo_matrix_invert (&mat) == CAIRO_STATUS_INVALID_MATRIX)
     {
-      /* FIXME: pass on error */
-      return;
+      return CAIRO_STATUS_INVALID_MATRIX;
     }
   cx = _cairo_fixed_to_double (rpat->c1.x);
   cy = _cairo_fixed_to_double (rpat->c1.y);
@@ -407,69 +409,86 @@ _cairo_openvg_setup_radial_source (VGPaint paint,
   radial[3] = fy;
   radial[4] = _cairo_fixed_to_double (rpat->r2);
 
-  vgSetParameteri (paint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
-  vgSetParameteri (paint, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
-  vgSetParameterfv (paint, VG_PAINT_RADIAL_GRADIENT, 5, radial);
+  vgSetParameteri (vgsurface->source_paint,
+                   VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
+  vgSetParameteri (vgsurface->source_paint,
+                   VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
+  vgSetParameterfv (vgsurface->source_paint,
+                    VG_PAINT_RADIAL_GRADIENT, 5, radial);
 
-  _cairo_openvg_setup_gradient_stops (paint,
-                                      (cairo_gradient_pattern_t *) rpat);
+  return _cairo_openvg_setup_gradient_stops (vgsurface,
+                                            (cairo_gradient_pattern_t *) rpat);
 }
 
-static void
-_cairo_openvg_setup_solid_source (VGPaint paint,
-                                  cairo_solid_pattern_t *spat)
+static cairo_status_t
+_cairo_openvg_setup_solid_source (cairo_openvg_surface_t *vgsurface,
+                                  cairo_solid_pattern_t  *spat)
 {
   VGfloat color[] = {spat->color.red,
                      spat->color.green,
                      spat->color.blue,
                      spat->color.alpha};
-  vgSetParameterfv (paint, VG_PAINT_COLOR, 4, color);
+  vgSetParameterfv (vgsurface->source_paint, VG_PAINT_COLOR, 4, color);
+  return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-_cairo_openvg_setup_surface_source (VGPaint paint,
+static cairo_status_t
+_cairo_openvg_setup_surface_source (cairo_openvg_surface_t  *vgsurface,
                                     cairo_surface_pattern_t *spat)
 {
   VGfloat color[] = {0.7, 0.5, 0.3, 0.5};
-  vgSetParameterfv (paint, VG_PAINT_COLOR, 4, color);
+  vgSetParameterfv (vgsurface->source_paint, VG_PAINT_COLOR, 4, color);
   printf ("not handling source of type surface\n");
+  return CAIRO_STATUS_SUCCESS;
+  return CAIRO_INT_STATUS_UNSUPPORTED;
 }
 
-
-
-
-static void setup_source (VGPaint paint,
-                          cairo_pattern_t *source)
+static cairo_status_t
+setup_source (cairo_openvg_surface_t *vgsurface,
+              cairo_pattern_t        *source)
 {
+  /* this will bomb if one of the prior paint ops have failed to
+   * clean up after itself
+   */
 
+  assert (vgsurface->source_paint == 0);
+  vgsurface->source_paint = vgCreatePaint();
   if (source->type == CAIRO_PATTERN_TYPE_SOLID)
     {
       cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
-      _cairo_openvg_setup_solid_source (paint, solid);
-      return;
+      return _cairo_openvg_setup_solid_source (vgsurface, solid);
     }
   else if (source->type == CAIRO_PATTERN_TYPE_LINEAR)
     {
       cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *)source;
-      _cairo_openvg_setup_linear_source (paint, lpat);
-      return;
+      return _cairo_openvg_setup_linear_source (vgsurface, lpat);
     }
   else if (source->type == CAIRO_PATTERN_TYPE_RADIAL)
     {
       cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *)source;
-      _cairo_openvg_setup_radial_source (paint, rpat);
-      return;
+      return _cairo_openvg_setup_radial_source (vgsurface, rpat);
     }
   else if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
       cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *)source;
-      _cairo_openvg_setup_surface_source (paint, spat);
-      return;
+      return _cairo_openvg_setup_surface_source (vgsurface, spat);
     }
   else
     {
       printf ("not handling source of type: %i\n", source->type);
     }
+  return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static cairo_status_t
+teardown_source (cairo_openvg_surface_t *vgsurface,
+                 cairo_pattern_t        *source)
+{
+  if (vgsurface->source_paint)
+    {
+      vgDestroyPaint (vgsurface->source_paint);
+      vgsurface->source_paint = 0;
+    }
 }
 
 static cairo_int_status_t
@@ -483,10 +502,11 @@ _cairo_openvg_surface_stroke (void *asurface,
                               double toleance,
                               cairo_antialias_t antialias)
 {
+  cairo_openvg_surface_t *vgsurface = asurface;
+  cairo_status_t rv = CAIRO_STATUS_SUCCESS;
   VGfloat state[9];
   VGfloat strokeTransform[9];
   openvg_stroke_t vg_path;
-  VGPaint paint;
 
   vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
                                VG_PATH_DATATYPE_F,
@@ -510,20 +530,20 @@ _cairo_openvg_surface_stroke (void *asurface,
 
   vgSeti(VG_BLEND_MODE, _cairo_openvg_cairo_operator_to_openvg (op));
 
-  paint = vgCreatePaint();
-
-  setup_source (paint, source);
-
-  vgSetPaint(paint, VG_STROKE_PATH);
+  rv = setup_source (vgsurface, source);
+  if (rv)
+    goto BAIL;
 
+  vgSetPaint(vgsurface->source_paint, VG_STROKE_PATH);
 
   vgDrawPath (vg_path.path, VG_STROKE_PATH);
-  vgDestroyPaint (paint);
   vgDestroyPath (vg_path.path);
+  teardown_source (vgsurface, source);
 
+BAIL:
   vgLoadMatrix (state);
 
-  return CAIRO_STATUS_SUCCESS;
+  return rv;
 }
 
 static cairo_int_status_t
@@ -535,8 +555,12 @@ _cairo_openvg_surface_fill (void *asurface,
                          double toleance,
                          cairo_antialias_t antialias)
 {
+  cairo_openvg_surface_t *vgsurface = asurface;
+  cairo_status_t rv = CAIRO_STATUS_SUCCESS;
   openvg_stroke_t vg_path;
-  VGPaint paint;
+
+  if (op == CAIRO_OPERATOR_DEST)
+    return CAIRO_STATUS_SUCCESS;
 
   vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
                                VG_PATH_DATATYPE_F,
@@ -547,16 +571,19 @@ _cairo_openvg_surface_fill (void *asurface,
 
   vgSeti(VG_BLEND_MODE, _cairo_openvg_cairo_operator_to_openvg (op));
 
-  paint = vgCreatePaint();
 
-  setup_source (paint, source);
+  rv = setup_source (vgsurface, source);
+  if (rv)
+    goto BAIL;
 
-  vgSetPaint(paint, VG_FILL_PATH);
+  vgSetPaint(vgsurface->source_paint, VG_FILL_PATH);
   vgDrawPath (vg_path.path, VG_FILL_PATH);
-  vgDestroyPaint (paint);
   vgDestroyPath (vg_path.path);
 
-  return CAIRO_STATUS_SUCCESS;
+  teardown_source (vgsurface, source);
+BAIL:
+
+  return rv;
 }
 
 #if 0
-- 
1.6.0.4



More information about the cairo mailing list