[cairo-commit] 6 commits - src/cairo-clip-polygon.c src/cairo-image-compositor.c src/cairo-surface-wrapper.c src/cairo-traps-compositor.c src/cairo-xlib-render-compositor.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Mar 6 13:18:04 PST 2012
src/cairo-clip-polygon.c | 26 +++++--
src/cairo-image-compositor.c | 120 ++++++++++++++++++++++++++++------
src/cairo-surface-wrapper.c | 8 +-
src/cairo-traps-compositor.c | 129 ++++++++++++++++++++++++++++++-------
src/cairo-xlib-render-compositor.c | 10 +-
5 files changed, 234 insertions(+), 59 deletions(-)
New commits:
commit 345460445973548374c171e30e6add02de1e1922
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 21:05:40 2012 +0000
xlib: Apply the glyph offset
The (dst_x, dst_y) parameters passed to the XRenderCompositeText are
misleading and do not perform any adjustment, so we have to do it
ourselves.
Fixes clip-operator
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c
index 86641b9..401313b 100644
--- a/src/cairo-xlib-render-compositor.c
+++ b/src/cairo-xlib-render-compositor.c
@@ -1217,8 +1217,8 @@ _emit_glyphs_chunk (cairo_xlib_display_t *display,
}
elts[nelt].chars = char8 + size * j;
elts[nelt].glyphset = info->glyphset;
- elts[nelt].xOff = glyphs[i].i.x;
- elts[nelt].yOff = glyphs[i].i.y;
+ elts[nelt].xOff = glyphs[i].i.x - dst_x;
+ elts[nelt].yOff = glyphs[i].i.y - dst_y;
}
switch (width) {
@@ -1245,9 +1245,9 @@ _emit_glyphs_chunk (cairo_xlib_display_t *display,
src->picture,
dst->picture,
use_mask ? info->xrender_format : NULL,
- src_x + elts[0].xOff,
- src_y + elts[0].yOff,
- elts[0].xOff - dst_x, elts[0].yOff - dst_y,
+ src_x + elts[0].xOff + dst_x,
+ src_y + elts[0].yOff + dst_y,
+ elts[0].xOff, elts[0].yOff,
(XGlyphElt8 *) elts, nelt);
if (elts != stack_elts)
commit ad758280b6e7d9f7bcc3b02796b3a1d9df908471
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 21:03:02 2012 +0000
traps: The CompositeTrapezoids requires the unbounded fixup for clipping
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index 371393c..284a0be 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -153,6 +153,21 @@ static void blt_in(void *closure,
&info->boxes);
}
+static void
+add_rect_with_offset (cairo_boxes_t *boxes, int x1, int y1, int x2, int y2, int dx, int dy)
+{
+ cairo_box_t box;
+ cairo_int_status_t status;
+
+ box.p1.x = _cairo_fixed_from_int (x1 - dx);
+ box.p1.y = _cairo_fixed_from_int (y1 - dy);
+ box.p2.x = _cairo_fixed_from_int (x2 - dx);
+ box.p2.y = _cairo_fixed_from_int (y2 - dy);
+
+ status = _cairo_boxes_add (boxes, CAIRO_ANTIALIAS_DEFAULT, &box);
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
+}
+
static cairo_int_status_t
combine_clip_as_traps (const cairo_traps_compositor_t *compositor,
cairo_surface_t *mask,
@@ -164,6 +179,8 @@ combine_clip_as_traps (const cairo_traps_compositor_t *compositor,
cairo_antialias_t antialias;
cairo_traps_t traps;
cairo_surface_t *src;
+ cairo_box_t box;
+ cairo_rectangle_int_t fixup;
int src_x, src_y;
cairo_int_status_t status;
@@ -196,8 +213,59 @@ combine_clip_as_traps (const cairo_traps_compositor_t *compositor,
extents,
antialias, &traps);
- cairo_surface_destroy (src);
+ _cairo_traps_extents (&traps, &box);
+ _cairo_box_round_to_rectangle (&box, &fixup);
_cairo_traps_fini (&traps);
+ cairo_surface_destroy (src);
+
+ if (status == CAIRO_INT_STATUS_SUCCESS &&
+ (fixup.width < extents->width || fixup.height < extents->height)) {
+ cairo_boxes_t clear;
+
+ _cairo_boxes_init (&clear);
+
+ /* top */
+ if (fixup.y != extents->y) {
+ add_rect_with_offset (&clear,
+ extents->x, extents->y,
+ extents->x + extents->width,
+ fixup.y,
+ extents->x, extents->y);
+ }
+ /* left */
+ if (fixup.x != extents->x) {
+ add_rect_with_offset (&clear,
+ extents->x, fixup.y,
+ fixup.x,
+ fixup.y + fixup.height,
+ extents->x, extents->y);
+ }
+ /* right */
+ if (fixup.x + fixup.width != extents->x + extents->width) {
+ add_rect_with_offset (&clear,
+ fixup.x + fixup.width,
+ fixup.y,
+ extents->x + extents->width,
+ fixup.y + fixup.height,
+ extents->x, extents->y);
+ }
+ /* bottom */
+ if (fixup.y + fixup.height != extents->y + extents->height) {
+ add_rect_with_offset (&clear,
+ extents->x,
+ fixup.y + fixup.height,
+ extents->x + extents->width,
+ extents->y + extents->height,
+ extents->x, extents->y);
+ }
+
+ status = compositor->fill_boxes (mask,
+ CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear);
+
+ _cairo_boxes_fini (&clear);
+ }
return status;
}
commit 753007ea0097ecd3ea9611dba69e995f755d5f5c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 15:01:05 2012 +0000
traps: Avoid double application of unaligned clip boxes
Both combine-with-clip functions now take care of any intersection with
clip boxes so the result would be to have overdrawn the unaligned clip
box mask twice.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index b1ade5c..371393c 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -316,6 +316,32 @@ traps_get_clip_surface (const cairo_traps_compositor_t *compositor,
return surface;
}
+static void blt_unaligned_boxes(const cairo_traps_compositor_t *compositor,
+ cairo_surface_t *surface,
+ int dx, int dy,
+ cairo_box_t *boxes,
+ int num_boxes)
+{
+ struct blt_in info;
+ int i;
+
+ info.compositor = compositor;
+ info.dst = surface;
+ _cairo_boxes_init (&info.boxes);
+ info.boxes.num_boxes = 1;
+ for (i = 0; i < num_boxes; i++) {
+ cairo_box_t *b = &boxes[i];
+
+ if (! _cairo_fixed_is_integer (b->p1.x) ||
+ ! _cairo_fixed_is_integer (b->p1.y) ||
+ ! _cairo_fixed_is_integer (b->p2.x) ||
+ ! _cairo_fixed_is_integer (b->p2.y))
+ {
+ do_unaligned_box(blt_in, &info, b, dx, dy);
+ }
+ }
+}
+
static cairo_surface_t *
create_composite_mask (const cairo_traps_compositor_t *compositor,
cairo_surface_t *dst,
@@ -326,9 +352,7 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
{
cairo_surface_t *surface, *src;
cairo_int_status_t status;
- struct blt_in info;
int src_x, src_y;
- int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -369,6 +393,8 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
&clear);
if (unlikely (status))
goto error;
+
+ surface->is_clear = TRUE;
}
if (mask_func) {
@@ -376,8 +402,10 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
CAIRO_OPERATOR_SOURCE, src, src_x, src_y,
extents->bounded.x, extents->bounded.y,
&extents->bounded, extents->clip);
- if (likely (status == CAIRO_INT_STATUS_SUCCESS))
+ if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+ surface->is_clear = FALSE;
goto out;
+ }
if (unlikely (status != CAIRO_INT_STATUS_UNSUPPORTED))
goto error;
}
@@ -390,24 +418,7 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
if (unlikely (status))
goto error;
- info.compositor = compositor;
- info.dst = surface;
- _cairo_boxes_init (&info.boxes);
- info.boxes.num_boxes = 1;
- for (i = 0; i < extents->clip->num_boxes; i++) {
- cairo_box_t *b = &extents->clip->boxes[i];
-
- if (! _cairo_fixed_is_integer (b->p1.x) ||
- ! _cairo_fixed_is_integer (b->p1.y) ||
- ! _cairo_fixed_is_integer (b->p2.x) ||
- ! _cairo_fixed_is_integer (b->p2.y))
- {
- do_unaligned_box(blt_in, &info, b,
- extents->bounded.x,
- extents->bounded.y);
- }
- }
-
+ surface->is_clear = FALSE;
if (extents->clip->path != NULL) {
status = combine_clip_as_traps (compositor, surface,
extents->clip, &extents->bounded);
@@ -418,12 +429,16 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
}
if (unlikely (status))
goto error;
+ } else if (extents->clip->boxes) {
+ blt_unaligned_boxes(compositor, surface,
+ extents->bounded.x, extents->bounded.y,
+ extents->clip->boxes, extents->clip->num_boxes);
+
}
out:
compositor->release (surface);
cairo_surface_destroy (src);
- surface->is_clear = FALSE;
return surface;
error:
commit d40b90a577f3dd159d3871185ed8d649a03a2a4e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 14:59:44 2012 +0000
clip: Use the boxes-intersection routine for computing the clip polygon
If we have more than a single box, run the boxes intersection as a
post-processing step on the clip polygon, as it should be faster than
doing it inline.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-clip-polygon.c b/src/cairo-clip-polygon.c
index 0e1968d..db0298f 100644
--- a/src/cairo-clip-polygon.c
+++ b/src/cairo-clip-polygon.c
@@ -88,15 +88,23 @@ _cairo_clip_get_polygon (const cairo_clip_t *clip,
if (! can_convert_to_polygon (clip))
return CAIRO_INT_STATUS_UNSUPPORTED;
- _cairo_polygon_init_with_clip (polygon, clip);
+ if (clip->num_boxes < 2)
+ _cairo_polygon_init_with_clip (polygon, clip);
+ else
+ _cairo_polygon_init_with_clip (polygon, NULL);
clip_path = clip->path;
status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
clip_path->tolerance,
polygon);
- if (unlikely (status)) {
- _cairo_polygon_fini (polygon);
- return status;
+ if (unlikely (status))
+ goto err;
+
+ if (clip->num_boxes > 1) {
+ status = _cairo_polygon_intersect_with_boxes (polygon, fill_rule,
+ clip->boxes, clip->num_boxes);
+ if (unlikely (status))
+ goto err;
}
polygon->limits = NULL;
@@ -115,15 +123,17 @@ _cairo_clip_get_polygon (const cairo_clip_t *clip,
status = _cairo_polygon_intersect (polygon, *fill_rule,
&next, clip_path->fill_rule);
_cairo_polygon_fini (&next);
- if (unlikely (status)) {
- _cairo_polygon_fini (polygon);
- return status;
- }
+ if (unlikely (status))
+ goto err;
*fill_rule = CAIRO_FILL_RULE_WINDING;
}
return CAIRO_STATUS_SUCCESS;
+
+err:
+ _cairo_polygon_fini (polygon);
+ return status;
}
cairo_bool_t
commit f8f0510f8929980f9b8da7ef0f39d231dfe24686
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 14:42:19 2012 +0000
image: Add unbounded support to the mono rasteriser fast-paths
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index fdbe2de..8db8250 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -1484,8 +1484,10 @@ _fill8_spans (void *abstract_renderer, int y, int h,
if (spans[0].coverage) {
int len = spans[1].x - spans[0].x;
uint8_t *d = r->u.fill.data + r->u.fill.stride*y + spans[0].x;
- while (len--)
- *d++ = r->u.fill.pixel;
+ if (len == 1)
+ *d = r->u.fill.pixel;
+ else
+ memset(d, r->u.fill.pixel, len);
}
spans++;
} while (--num_spans > 1);
@@ -1496,8 +1498,10 @@ _fill8_spans (void *abstract_renderer, int y, int h,
do {
int len = spans[1].x - spans[0].x;
uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x;
- while (len--)
- *d++ = r->u.fill.pixel;
+ if (len == 1)
+ *d = r->u.fill.pixel;
+ else
+ memset(d, r->u.fill.pixel, len);
yy++;
} while (--hh);
}
@@ -1721,6 +1725,83 @@ _mono_spans (void *abstract_renderer, int y, int h,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_status_t
+_mono_unbounded_spans (void *abstract_renderer, int y, int h,
+ const cairo_half_open_span_t *spans, unsigned num_spans)
+{
+ cairo_image_span_renderer_t *r = abstract_renderer;
+
+ if (num_spans == 0) {
+ pixman_image_composite32 (PIXMAN_OP_CLEAR,
+ r->src, NULL, r->u.composite.dst,
+ spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y,
+ 0, 0,
+ r->composite->unbounded.x, y,
+ r->composite->unbounded.width, h);
+ r->u.composite.mask_y = y + h;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ if (y != r->u.composite.mask_y) {
+ pixman_image_composite32 (PIXMAN_OP_CLEAR,
+ r->src, NULL, r->u.composite.dst,
+ spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y,
+ 0, 0,
+ r->composite->unbounded.x, r->u.composite.mask_y,
+ r->composite->unbounded.width, y - r->u.composite.mask_y);
+ }
+
+ if (spans[0].x != r->composite->unbounded.x) {
+ pixman_image_composite32 (PIXMAN_OP_CLEAR,
+ r->src, NULL, r->u.composite.dst,
+ spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y,
+ 0, 0,
+ r->composite->unbounded.x, y,
+ spans[0].x - r->composite->unbounded.x, h);
+ }
+
+ do {
+ int op = spans[0].coverage ? r->op : PIXMAN_OP_CLEAR;
+ pixman_image_composite32 (op,
+ r->src, NULL, r->u.composite.dst,
+ spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y,
+ 0, 0,
+ spans[0].x, y,
+ spans[1].x - spans[0].x, h);
+ spans++;
+ } while (--num_spans > 1);
+
+ if (spans[0].x != r->composite->unbounded.x + r->composite->unbounded.width) {
+ pixman_image_composite32 (PIXMAN_OP_CLEAR,
+ r->src, NULL, r->u.composite.dst,
+ spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y,
+ 0, 0,
+ spans[0].x, y,
+ r->composite->unbounded.x + r->composite->unbounded.width - spans[0].x, h);
+ }
+
+ r->u.composite.mask_y = y + h;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_mono_finish_unbounded_spans (void *abstract_renderer)
+{
+ cairo_image_span_renderer_t *r = abstract_renderer;
+
+ if (r->u.composite.mask_y < r->composite->unbounded.y + r->composite->unbounded.height) {
+ pixman_image_composite32 (PIXMAN_OP_CLEAR,
+ r->src, NULL, r->u.composite.dst,
+ r->composite->unbounded.x + r->u.composite.src_x, r->u.composite.mask_y + r->u.composite.src_y,
+ 0, 0,
+ r->composite->unbounded.x, r->u.composite.mask_y,
+ r->composite->unbounded.width,
+ r->composite->unbounded.y + r->composite->unbounded.height - r->u.composite.mask_y);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_int_status_t
mono_renderer_init (cairo_image_span_renderer_t *r,
const cairo_composite_rectangles_t *composite,
@@ -1785,23 +1866,22 @@ mono_renderer_init (cairo_image_span_renderer_t *r,
}
if (r->base.render_rows == NULL) {
- if (1) { /* XXX calling pixman_image_composite per span is too slow */
- r->src = _pixman_image_for_pattern (dst, &composite->source_pattern.base, FALSE,
- &composite->unbounded,
- &composite->source_sample_area,
- &r->u.composite.src_x, &r->u.composite.src_y);
- if (unlikely (r->src == NULL))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- r->u.composite.dst = to_pixman_image (composite->surface);
- r->op = _pixman_operator (composite->op);
+ r->src = _pixman_image_for_pattern (dst, &composite->source_pattern.base, FALSE,
+ &composite->unbounded,
+ &composite->source_sample_area,
+ &r->u.composite.src_x, &r->u.composite.src_y);
+ if (unlikely (r->src == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ r->u.composite.dst = to_pixman_image (composite->surface);
+ r->op = _pixman_operator (composite->op);
+ if (composite->is_bounded == 0) {
+ r->base.render_rows = _mono_unbounded_spans;
+ r->base.finish = _mono_finish_unbounded_spans;
+ r->u.composite.mask_y = composite->unbounded.y;
+ } else
r->base.render_rows = _mono_spans;
- } else{
- return CAIRO_INT_STATUS_UNSUPPORTED;
- }
}
- r->base.finish = NULL;
-
r->bpp = PIXMAN_FORMAT_BPP(dst->pixman_format);
return CAIRO_INT_STATUS_SUCCESS;
@@ -2316,7 +2396,6 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
r->base.render_rows = _inplace_spans;
}
- r->base.finish = NULL;
r->bpp = PIXMAN_FORMAT_BPP(dst->pixman_format);
return CAIRO_INT_STATUS_SUCCESS;
@@ -2342,6 +2421,7 @@ span_renderer_init (cairo_abstract_span_renderer_t *_r,
r->composite = composite;
r->mask = NULL;
r->src = NULL;
+ r->base.finish = NULL;
status = mono_renderer_init (r, composite, antialias, needs_clip);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
commit 5bd29eda63ee54daecfdfe36b12a1b6c4b592740
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 6 14:11:49 2012 +0000
surface-wrapper: Only apply the wrapped transform to the scaled-font
And not the device_transform of the target. This smells fishy, but
appears to make the test suite happy.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index 52d250c..fe9c42a 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -436,11 +436,13 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
_cairo_surface_wrapper_get_transform (wrapper, &m);
- if (! _cairo_matrix_is_translation (&m)) {
+ if (! _cairo_matrix_is_translation (&wrapper->transform)) {
cairo_matrix_t ctm;
- _cairo_matrix_multiply (&ctm, &m, &scaled_font->ctm);
-
+ /* XXX No device-transform? A bug in the tangle of layers? */
+ _cairo_matrix_multiply (&ctm,
+ &wrapper->transform,
+ &scaled_font->ctm);
dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face,
&scaled_font->font_matrix,
&ctm, &options);
More information about the cairo-commit
mailing list