diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 06:51:01 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 09:58:20 -0400 |
commit | 0bfe6b819b569501052a6ebe1cbf64cdaf669d38 (patch) | |
tree | 436f42a11d3c0485c0be977ffa06f9a8f8e60102 | |
parent | 25c1b0c0e8079355924134a2a84d243b23da69fe (diff) |
more flesh
-rw-r--r-- | src/cairo-pixman-surface.c | 216 |
1 files changed, 212 insertions, 4 deletions
diff --git a/src/cairo-pixman-surface.c b/src/cairo-pixman-surface.c index 3a7b3ec0..61ba2d96 100644 --- a/src/cairo-pixman-surface.c +++ b/src/cairo-pixman-surface.c @@ -43,6 +43,7 @@ #include "cairo-default-context-private.h" #include "cairo-image-surface-private.h" #include "cairo-pattern-private.h" +#include "cairo-clip-inline.h" extern const cairo_surface_backend_t cairo_pixman_surface_backend; @@ -199,6 +200,20 @@ create_image_surface (cairo_pixman_surface_t *psurface) format = CAIRO_FORMAT_RGB30; break; + case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_b8g8r8a8: + case PIXMAN_b8g8r8x8: case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8: + case PIXMAN_x14r6g6b6: case PIXMAN_a2r10g10b10: case PIXMAN_x2b10g10r10: + case PIXMAN_a2b10g10r10: case PIXMAN_a8r8g8b8_sRGB: case PIXMAN_r8g8b8: + case PIXMAN_b8g8r8: case PIXMAN_b5g6r5: case PIXMAN_a1r5g5b5: + case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5: case PIXMAN_x1b5g5r5: + case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4: case PIXMAN_a4b4g4r4: + case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2: case PIXMAN_b2g3r3: + case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2: case PIXMAN_g8: + case PIXMAN_x4a4: case PIXMAN_a4: case PIXMAN_r1g2b1: case PIXMAN_c8: + case PIXMAN_b1g2r1: case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: + case PIXMAN_c4: case PIXMAN_g4: case PIXMAN_g1: + case PIXMAN_yuy2: case PIXMAN_yv12: + default: format = CAIRO_FORMAT_ARGB32; must_copy = TRUE; @@ -273,7 +288,7 @@ cairo_pixman_surface_acquire_source_image (void *abstract_sur cairo_image_surface_t **image_out, void **image_extra) { - cairo_pixman_surface_t *psurface; + cairo_pixman_surface_t *psurface = abstract_surface; *image_out = (cairo_image_surface_t *)create_image_surface (psurface); *image_extra = NULL; @@ -293,7 +308,9 @@ cairo_pixman_surface_release_source_image (void *abstract_surf static cairo_surface_t * cairo_pixman_surface_snapshot (void *abstract_surface) { - /* huh? */ + cairo_pixman_surface_t *psurface = abstract_surface; + + return create_image_surface (psurface); } static cairo_bool_t @@ -320,6 +337,74 @@ cairo_pixman_surface_get_font_options (void *abstract_surface, _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON); } +static void +set_properties (pixman_image_t *image, cairo_pattern_t *pattern) +{ + cairo_matrix_t *matrix = &(pattern->matrix); + pixman_transform_t transform; + pixman_filter_t filter; + pixman_repeat_t repeat; + + /* Transform */ + transform.matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx); + transform.matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy); + transform.matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0); + transform.matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx); + transform.matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy); + transform.matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0); + + transform.matrix[2][0] = 0; + transform.matrix[2][1] = 0; + transform.matrix[2][2] = pixman_fixed_1; + + pixman_image_set_transform (image, &transform); + + /* Filter */ + switch (pattern->filter) + { + case CAIRO_FILTER_FAST: + filter = PIXMAN_FILTER_FAST; + break; + case CAIRO_FILTER_GOOD: + filter = PIXMAN_FILTER_GOOD; + break; + case CAIRO_FILTER_BEST: + filter = PIXMAN_FILTER_BEST; + break; + case CAIRO_FILTER_NEAREST: + filter = PIXMAN_FILTER_NEAREST; + break; + case CAIRO_FILTER_BILINEAR: + filter = PIXMAN_FILTER_BILINEAR; + break; + case CAIRO_FILTER_GAUSSIAN: + break; + } + + pixman_image_set_filter (image, filter, NULL, -1); + + /* Repeat mode */ + switch (pattern->extend) + { + case CAIRO_EXTEND_NONE: + repeat = PIXMAN_REPEAT_NONE; + break; + case CAIRO_EXTEND_REPEAT: + repeat = PIXMAN_REPEAT_NORMAL; + break; + case CAIRO_EXTEND_REFLECT: + repeat = PIXMAN_REPEAT_REFLECT; + break; + case CAIRO_EXTEND_PAD: + repeat = PIXMAN_REPEAT_PAD; + break; + } + + pixman_image_set_repeat (image, repeat); + + pixman_image_set_component_alpha (image, pattern->has_component_alpha); +} + static pixman_image_t * pimage_from_solid_pattern (cairo_solid_pattern_t *solid) { @@ -333,10 +418,102 @@ pimage_from_solid_pattern (cairo_solid_pattern_t *solid) return pixman_image_create_solid_fill (&pcolor); } +typedef struct acquire_source_cleanup_t +{ + cairo_surface_t * surface; + cairo_image_surface_t * image; + void * extra; +} acquire_source_cleanup_t; + +static void +clean_up_acquire (pixman_image_t *image, void *closure) +{ + acquire_source_cleanup_t *info = closure; + + _cairo_surface_release_source_image ( + info->surface, info->image, info->extra); +} + static pixman_image_t * -pimage_from_surface_pattern (cairo_surface_pattern_t *surface) +pimage_from_surface_pattern (cairo_surface_pattern_t *pattern) { + pixman_image_t *simage, *result; + cairo_status_t status; + cairo_image_surface_t *image = NULL; + acquire_source_cleanup_t *info = NULL; + /* First, get a pixman image that has the right bits */ + switch (pattern->surface->type) + { + case CAIRO_SURFACE_TYPE_PIXMAN: + simage = ((cairo_pixman_surface_t *)pattern->surface)->pimage; + break; + + case CAIRO_SURFACE_TYPE_IMAGE: + simage = ((cairo_image_surface_t *)pattern->surface)->pixman_image; + break; + + case CAIRO_SURFACE_TYPE_PDF: + case CAIRO_SURFACE_TYPE_PS: + case CAIRO_SURFACE_TYPE_XLIB: + case CAIRO_SURFACE_TYPE_XCB: + case CAIRO_SURFACE_TYPE_GLITZ: + case CAIRO_SURFACE_TYPE_QUARTZ: + case CAIRO_SURFACE_TYPE_WIN32: + case CAIRO_SURFACE_TYPE_BEOS: + case CAIRO_SURFACE_TYPE_DIRECTFB: + case CAIRO_SURFACE_TYPE_SVG: + case CAIRO_SURFACE_TYPE_OS2: + case CAIRO_SURFACE_TYPE_WIN32_PRINTING: + case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: + case CAIRO_SURFACE_TYPE_SCRIPT: + case CAIRO_SURFACE_TYPE_QT: + case CAIRO_SURFACE_TYPE_RECORDING: + case CAIRO_SURFACE_TYPE_VG: + case CAIRO_SURFACE_TYPE_GL: + case CAIRO_SURFACE_TYPE_DRM: + case CAIRO_SURFACE_TYPE_TEE: + case CAIRO_SURFACE_TYPE_XML: + case CAIRO_SURFACE_TYPE_SKIA: + case CAIRO_SURFACE_TYPE_SUBSURFACE: + case CAIRO_SURFACE_TYPE_COGL: + default: + if (!(info = malloc (sizeof (acquire_source_cleanup_t)))) + return NULL; + + info->surface = pattern->surface; + status = _cairo_surface_acquire_source_image ( + pattern->surface, &info->image, &info->extra); + + if (unlikely (status)) + { + /* FIXME */; + } + + simage = image->pixman_image; + break; + } + + /* Then create a clone of that image */ + result = pixman_image_create_bits ( + pixman_image_get_format (simage), + pixman_image_get_width (simage), + pixman_image_get_height (simage), + pixman_image_get_data (simage), + pixman_image_get_stride (simage)); + + if (unlikely (result == NULL)) + { + /* FIXME */; + } + + if (info) + pixman_image_set_destroy_function (result, clean_up_acquire, info); + + /* Then set the right properties on the clone */ + set_properties (result, (cairo_pattern_t *)pattern); + + return result; } static pixman_image_t * @@ -360,14 +537,45 @@ pimage_from_pattern (const cairo_pattern_t *pattern) } } +static pixman_image_t * +clip_to_image (const cairo_clip_t *clip) +{ + pixman_image_t *image; + int i; + + image = pixman_image_create_bits ( + PIXMAN_a8, clip->extents.width, clip->extents.height, NULL, -1); + + for (i = 0; i < clip->num_boxes; ++i) + { + cairo_box_t *box = &(clip->boxes[i]); + } + + return image; +} + static cairo_int_status_t cairo_pixman_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_clip_t *clip) { - pixman_image_t *iamge = pimage_from_pattern (source); + cairo_pixman_surface_t *psurface = abstract_surface; + pixman_image_t *image = pimage_from_pattern (source); + pixman_image_t *clip_image = NULL; + + clip_image = clip_to_image (clip); + + if (clip) + { + if (_cairo_clip_is_all_clipped (clip)) + return CAIRO_STATUS_SUCCESS; + + clip_image = clip_to_image (clip); + } + + } static cairo_int_status_t |