[cairo] [PATCH 12/39] [OpenVG] Made paint use the same source setup as stroke and fill, also enhanced pattern source.
tardyp at gmail.com
tardyp at gmail.com
Fri Jul 10 10:02:14 PDT 2009
From: Øyvind Kolås <pippin at gimp.org>
---
src/cairo-openvg-surface.c | 174 +++++++++++++++++++++++++++++--------------
1 files changed, 117 insertions(+), 57 deletions(-)
diff --git a/src/cairo-openvg-surface.c b/src/cairo-openvg-surface.c
index 379d30c..946c476 100644
--- a/src/cairo-openvg-surface.c
+++ b/src/cairo-openvg-surface.c
@@ -93,33 +93,6 @@ _cairo_openvg_surface_get_extents (void *asurface,
}
static cairo_int_status_t
-_cairo_openvg_surface_paint (void *asurface,
- cairo_operator_t op,
- cairo_pattern_t *source)
-{
- cairo_openvg_surface_t *s = asurface;
-
- if (source->type == CAIRO_PATTERN_TYPE_SOLID)
- {
- cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
- VGfloat color[] = {solid->color.red,
- solid->color.green,
- solid->color.blue,
- solid->color.alpha};
- vgSetfv (VG_CLEAR_COLOR, 4, color);
- vgClear (0, 0, s->width * 3, s->height * 2);
- }
- else
- {
- printf ("not supporting source of type %i for paint yet\n", source->type);
- return CAIRO_INT_STATUS_UNSUPPORTED;
- }
-
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
_cairo_openvg_surface_mask (void *asurface,
cairo_operator_t op,
cairo_pattern_t *source,
@@ -438,33 +411,86 @@ static cairo_status_t
_cairo_openvg_setup_surface_source (cairo_openvg_surface_t *vgsurface,
cairo_surface_pattern_t *spat)
{
- VGfloat color[] = {1.0, 1.0, 1.0, 1.0};
- vgSetParameterfv (vgsurface->source_paint, VG_PAINT_COLOR, 4, color);
- printf ("not handling source of type surface\n");
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_image_surface_t *image= (cairo_image_surface_t*)spat->surface;
+ cairo_rectangle_int_t extents;
+ unsigned char *data;
+
+ status = _cairo_surface_get_extents (spat->surface, &extents);
+ if (status)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- vgsurface->source_image = vgCreateImage (VG_sRGBA_8888, 128, 128, VG_IMAGE_QUALITY_BETTER);
+ if (!_cairo_surface_is_image (spat->surface))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ assert (image->format == CAIRO_FORMAT_RGB24 ||
+ image->format == CAIRO_FORMAT_ARGB32 ||
+ image->format == CAIRO_FORMAT_A8 ||
+ image->format == CAIRO_FORMAT_A1);
+
+ vgsurface->source_image = vgCreateImage (VG_sRGBA_8888,
+ image->width, image->height, VG_IMAGE_QUALITY_FASTER);
+ /* NONALIASED, FASTER, BETTER */
+
+ data = malloc (image->width * image->height * 4);
+
+ /* This extra allocation and copy/conversion should not be neccesary if the OpenVG implementation
+ * supports the pixelformats in the specification, at the moment it doesn't seem like neither
+ * ShivaVG nor AmantihVG does so however.
+ */
{
- unsigned char *data = malloc (128*128*4);
int i;
- for (i=0;i<128*128*4;i++)
+ for (i=0; i<image->width * image->height; i++)
{
- data[i] = 0;/*rand() % 255;*/
- if (i%4 == 3)
- data[i] = 255;
- if (i%4 == 2)
- data[i] = rand ()%255;
+ data[4*i+0] = image->data[4*i+3];
+ data[4*i+1] = image->data[4*i+0];
+ data[4*i+2] = image->data[4*i+1];
+ data[4*i+3] = image->data[4*i+2];
}
+ }
- vgImageSubData (vgsurface->source_image, data, 128*4, VG_sRGBA_8888, 0,
- 0, 128, 128);
+ vgImageSubData (vgsurface->source_image, data, image->width*4,
+ VG_sRGBA_8888 | (0 << 6), 0, 0, image->width, image->height);
- free (data);
- }
-
+ free (data);
- return CAIRO_STATUS_SUCCESS;
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ vgSetParameteri (vgsurface->source_paint,
+ VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
+
+ switch (spat->base.extend)
+ {
+ case CAIRO_EXTEND_PAD:
+ vgSetParameteri(vgsurface->source_paint,
+ VG_PAINT_PATTERN_TILING_MODE,
+ VG_TILE_PAD);
+ break;
+ case CAIRO_EXTEND_NONE:
+ vgSetParameteri(vgsurface->source_paint,
+ VG_PAINT_PATTERN_TILING_MODE,
+ VG_TILE_FILL);
+ {
+ VGfloat color[] = {0,0,0,0};
+ vgSetfv (VG_TILE_FILL_COLOR, 4, color);
+ }
+
+ break;
+ case CAIRO_EXTEND_REPEAT:
+ vgSetParameteri(vgsurface->source_paint,
+ VG_PAINT_PATTERN_TILING_MODE,
+ VG_TILE_REPEAT);
+ break;
+ case CAIRO_EXTEND_REFLECT:
+ vgSetParameteri(vgsurface->source_paint,
+ VG_PAINT_PATTERN_TILING_MODE,
+ VG_TILE_REFLECT);
+ default:
+ break;
+ }
+
+
+ vgPaintPattern(vgsurface->source_paint, vgsurface->source_image);
+
+ return status;
}
static cairo_status_t
@@ -515,7 +541,7 @@ teardown_source (cairo_openvg_surface_t *vgsurface,
}
if (vgsurface->source_image)
{
- vgDestroyImage (vgsurface->source_paint);
+ vgDestroyImage (vgsurface->source_image);
vgsurface->source_image = 0;
}
return CAIRO_STATUS_SUCCESS;
@@ -606,22 +632,55 @@ _cairo_openvg_surface_fill (void *asurface,
if (rv)
goto BAIL;
+ vgSetPaint(vgsurface->source_paint, VG_FILL_PATH);
+ vgDrawPath (vg_path.path, VG_FILL_PATH);
+ vgDestroyPath (vg_path.path);
+ teardown_source (vgsurface, source);
+BAIL:
+ return rv;
+}
- if (vgsurface->source_image)
- {
- printf ("WARNING: attempting to paint with image pattern\n");
- vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
- vgSetParameteri(vgsurface->source_image, VG_PAINT_PATTERN_TILING_MODE,
- VG_TILE_REPEAT);
- vgPaintPattern(vgsurface->source_paint, vgsurface->source_image);
- }
- vgSetPaint(vgsurface->source_paint, VG_FILL_PATH);
+static cairo_int_status_t
+_cairo_openvg_surface_paint (void *asurface,
+ cairo_operator_t op,
+ cairo_pattern_t *source)
+{
+ cairo_openvg_surface_t *vgsurface = asurface;
+ cairo_status_t rv = CAIRO_STATUS_SUCCESS;
+ openvg_stroke_t vg_path;
- vgDrawPath (vg_path.path, VG_FILL_PATH);
+ if (op == CAIRO_OPERATOR_DEST)
+ return CAIRO_STATUS_SUCCESS;
- vgDestroyPath (vg_path.path);
+ vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F,
+ 1,0,0,0, VG_PATH_CAPABILITY_ALL);
+ vg_path.ctm_inverse = NULL;
+
+ vgSeti(VG_BLEND_MODE, _cairo_openvg_cairo_operator_to_openvg (op));
+
+ rv = setup_source (vgsurface, source);
+ if (rv)
+ goto BAIL;
+
+ vgSetPaint(vgsurface->source_paint, VG_FILL_PATH);
+
+ { /* creating a rectangular path that should cover the extent */
+ VGPath fullext; VGubyte segs[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS, VG_LINE_TO_ABS,
+ VG_CLOSE_PATH};
+ VGfloat data[] = {0,0,
+ vgsurface->width, 0,
+ vgsurface->width, vgsurface->height,
+ 0, vgsurface->height};
+ fullext = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1,0,0,0, VG_PATH_CAPABILITY_ALL);
+ vgAppendPathData(fullext, sizeof(segs), segs, data);
+ vgDrawPath (fullext, VG_FILL_PATH);
+ vgDestroyPath (fullext);
+ }
teardown_source (vgsurface, source);
BAIL:
@@ -629,6 +688,7 @@ BAIL:
return rv;
}
+
#if 0
static cairo_int_status_t
_cairo_openvg_surface_show_glyphs (void *asurface,
--
1.6.0.4
More information about the cairo
mailing list