summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 06:51:01 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 09:58:20 -0400
commit0bfe6b819b569501052a6ebe1cbf64cdaf669d38 (patch)
tree436f42a11d3c0485c0be977ffa06f9a8f8e60102
parent25c1b0c0e8079355924134a2a84d243b23da69fe (diff)
more flesh
-rw-r--r--src/cairo-pixman-surface.c216
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