[cairo-commit] src/cairo-image-surface.c src/cairo-paginated-private.h src/cairo-paginated-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jul 29 10:40:28 PDT 2011
src/cairo-image-surface.c | 72 +++++++++++++++++++++++++++++++++++-------
src/cairo-paginated-private.h | 3 +
src/cairo-paginated-surface.c | 12 ++++++-
3 files changed, 74 insertions(+), 13 deletions(-)
New commits:
commit 2342e4da4fdbeed5672d586742fa19cf1018264c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 29 18:36:52 2011 +0100
image: extend support of direct replay for paginated surfaces
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3eb4e05..7a0ddc6 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -44,9 +44,10 @@
#include "cairo-composite-rectangles-private.h"
#include "cairo-default-context-private.h"
#include "cairo-error-private.h"
+#include "cairo-paginated-private.h"
+#include "cairo-pattern-private.h"
#include "cairo-recording-surface-private.h"
#include "cairo-region-private.h"
-#include "cairo-pattern-private.h"
#include "cairo-scaled-font-private.h"
#include "cairo-surface-snapshot-private.h"
#include "cairo-surface-subsurface-private.h"
@@ -2912,22 +2913,68 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
static cairo_bool_t
is_recording_pattern (const cairo_pattern_t *pattern)
{
- const cairo_surface_pattern_t *surface_pattern;
+ cairo_surface_t *surface;
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
return FALSE;
- surface_pattern = (const cairo_surface_pattern_t *) pattern;
- return _cairo_surface_is_recording (surface_pattern->surface);
+ surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+ if (_cairo_surface_is_paginated (surface))
+ surface = _cairo_paginated_surface_get_recording (surface);
+ return _cairo_surface_is_recording (surface);
}
static cairo_surface_t *
-pattern_get_surface (const cairo_pattern_t *pattern)
+recording_pattern_get_surface (const cairo_pattern_t *pattern)
+{
+ cairo_surface_t *surface;
+
+ surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+ if (_cairo_surface_is_paginated (surface))
+ surface = _cairo_paginated_surface_get_recording (surface);
+ return surface;
+}
+
+static cairo_bool_t
+op_reduces_to_source (cairo_operator_t op,
+ cairo_image_surface_t *dst)
+{
+ if (op == CAIRO_OPERATOR_SOURCE)
+ return TRUE;
+
+ if (dst->base.is_clear)
+ return op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD;
+
+ return FALSE;
+}
+
+static cairo_bool_t
+recording_pattern_contains_sample (const cairo_pattern_t *pattern,
+ const cairo_rectangle_int_t *extents)
{
- const cairo_surface_pattern_t *surface_pattern;
+ cairo_rectangle_int_t area;
+ cairo_recording_surface_t *surface;
+
+ if (! is_recording_pattern (pattern))
+ return FALSE;
+
+ if (pattern->extend == CAIRO_EXTEND_NONE)
+ return TRUE;
- surface_pattern = (const cairo_surface_pattern_t *) pattern;
- return surface_pattern->surface;
+ surface = (cairo_recording_surface_t *) recording_pattern_get_surface (pattern);
+ if (surface->unbounded)
+ return TRUE;
+
+ sampled_area ((cairo_surface_pattern_t *) pattern, extents, &area);
+ if (area.x >= surface->extents.x &&
+ area.y >= surface->extents.y &&
+ area.x + area.width <= surface->extents.x + surface->extents.width &&
+ area.y + area.height <= surface->extents.y + surface->extents.height)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
}
static cairo_status_t
@@ -2970,12 +3017,13 @@ _composite_boxes (cairo_image_surface_t *dst,
/* Are we just copying a recording surface? */
if (! need_clip_mask &&
- op == CAIRO_OPERATOR_SOURCE &&
- pattern->extend == CAIRO_EXTEND_NONE && /* or if sample is contained */
- is_recording_pattern (pattern))
+ op_reduces_to_source (op, dst) &&
+ recording_pattern_contains_sample (pattern, &extents->bounded))
{
cairo_clip_t *recording_clip;
+ /* XXX could also do tiling repeat modes... */
+
/* first clear the area about to be overwritten */
if (! dst->base.is_clear) {
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
@@ -3000,7 +3048,7 @@ _composite_boxes (cairo_image_surface_t *dst,
}
recording_clip = _cairo_clip_from_boxes (boxes);
- status = _cairo_recording_surface_replay_with_clip (pattern_get_surface (pattern),
+ status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (pattern),
&pattern->matrix,
&dst->base,
recording_clip);
diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h
index 42badbf..b827fab 100644
--- a/src/cairo-paginated-private.h
+++ b/src/cairo-paginated-private.h
@@ -154,6 +154,9 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
cairo_private cairo_surface_t *
_cairo_paginated_surface_get_target (cairo_surface_t *surface);
+cairo_private cairo_surface_t *
+_cairo_paginated_surface_get_recording (cairo_surface_t *surface);
+
cairo_private cairo_bool_t
_cairo_surface_is_paginated (cairo_surface_t *surface);
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 5fe3439..9595587 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -147,10 +147,20 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface)
assert (_cairo_surface_is_paginated (surface));
paginated_surface = (cairo_paginated_surface_t *) surface;
-
return paginated_surface->target;
}
+cairo_surface_t *
+_cairo_paginated_surface_get_recording (cairo_surface_t *surface)
+{
+ cairo_paginated_surface_t *paginated_surface;
+
+ assert (_cairo_surface_is_paginated (surface));
+
+ paginated_surface = (cairo_paginated_surface_t *) surface;
+ return paginated_surface->recording_surface;
+}
+
cairo_status_t
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
int width,
More information about the cairo-commit
mailing list