[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