[cairo-commit] 3 commits - src/cairo-clip.c src/cairo-clip-private.h src/cairo-gl-surface.c src/cairo-image-surface.c src/cairo-surface-fallback.c src/cairo-xcb-surface-render.c src/drm test/Makefile.am test/Makefile.sources test/partial-clip-text.c test/partial-clip-text.ps.ref.png test/partial-clip-text.ref.png test/partial-clip-text.svg.ref.png
Chris Wilson
ickle at kemper.freedesktop.org
Mon Jul 12 08:41:20 PDT 2010
src/cairo-clip-private.h | 4 ++
src/cairo-clip.c | 22 +++++++++++-----
src/cairo-gl-surface.c | 4 +-
src/cairo-image-surface.c | 33 +++++++++++++++++-------
src/cairo-surface-fallback.c | 10 +++----
src/cairo-xcb-surface-render.c | 10 +++----
src/drm/cairo-drm-i915-glyphs.c | 2 -
src/drm/cairo-drm-i915-surface.c | 8 ++---
src/drm/cairo-drm-i965-glyphs.c | 2 -
src/drm/cairo-drm-i965-surface.c | 8 ++---
test/Makefile.am | 3 ++
test/Makefile.sources | 1
test/partial-clip-text.c | 50 +++++++++++++++++++++++++++++++++++++
test/partial-clip-text.ps.ref.png |binary
test/partial-clip-text.ref.png |binary
test/partial-clip-text.svg.ref.png |binary
16 files changed, 119 insertions(+), 38 deletions(-)
New commits:
commit ef0679333da881bd83b0bb4db546ea9c68f81f89
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 12 16:07:27 2010 +0100
image: Manually clip against bounds when rendering directly
This is path is slightly peculiar in that it explicitly avoid the
intermediate mask and the geometry is not pre-clipped.
This in conjunction with the previous commit fixes:
Clip doesn't work for text
https://bugs.freedesktop.org/show_bug.cgi?id=29008
which is captured in test/partial-clip-text.
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 1f8e9b1..e111973 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -3939,6 +3939,8 @@ _composite_glyphs (void *closure,
glyph_surface = scaled_glyph->surface;
if (glyph_surface->width && glyph_surface->height) {
+ int x1, y1, x2, y2;
+
/* round glyph locations to the nearest pixel */
/* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */
x = _cairo_lround (info->glyphs[i].x -
@@ -3946,13 +3948,26 @@ _composite_glyphs (void *closure,
y = _cairo_lround (info->glyphs[i].y -
glyph_surface->base.device_transform.y0);
+ x1 = x;
+ if (x1 < extents->x)
+ x1 = extents->x;
+ x2 = x + glyph_surface->width;
+ if (x2 > extents->x + extents->width)
+ x2 = extents->x + extents->width;
+
+ y1 = y;
+ if (y1 < extents->y)
+ y1 = extents->y;
+ y2 = y + glyph_surface->height;
+ if (y2 > extents->y + extents->height)
+ y2 = extents->y + extents->height;
+
pixman_image_composite32 (pixman_op,
src, glyph_surface->pixman_image, dst,
- x + src_x, y + src_y,
+ x1 + src_x, y1 + src_y,
0, 0,
- x - dst_x, y - dst_y,
- glyph_surface->width,
- glyph_surface->height);
+ x1 - dst_x, y1 - dst_y,
+ x2 - x1, y2 - y1);
}
}
_cairo_scaled_font_thaw_cache (info->font);
commit 679e5a600bd7dae6cbde83070fb1f7355f8025a7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 12 16:06:32 2010 +0100
Differentiate between reducing clip to composite extents and a rectangle
This is required for handling glyphs when rendering directly to the
surface.
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 7c7b84f..faf4864 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -136,6 +136,10 @@ _cairo_clip_to_boxes (cairo_clip_t **clip,
cairo_private cairo_bool_t
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
+ const cairo_rectangle_int_t *rect);
+
+cairo_private cairo_bool_t
+_cairo_clip_contains_extents (cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents);
cairo_private void
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 0c6cb74..3bd7edc 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -1106,18 +1106,13 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
cairo_bool_t
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
- const cairo_composite_rectangles_t *extents)
+ const cairo_rectangle_int_t *rect)
{
- cairo_clip_path_t *clip_path;
- const cairo_rectangle_int_t *rect;
+ cairo_clip_path_t *clip_path = clip->path;
if (clip == NULL)
return FALSE;
- rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
-
- clip_path = clip->path;
-
if (clip_path->extents.x > rect->x ||
clip_path->extents.y > rect->y ||
clip_path->extents.x + clip_path->extents.width < rect->x + rect->width ||
@@ -1147,6 +1142,19 @@ _cairo_clip_contains_rectangle (cairo_clip_t *clip,
return TRUE;
}
+cairo_bool_t
+_cairo_clip_contains_extents (cairo_clip_t *clip,
+ const cairo_composite_rectangles_t *extents)
+{
+ const cairo_rectangle_int_t *rect;
+
+ if (clip == NULL)
+ return FALSE;
+
+ rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
+ return _cairo_clip_contains_rectangle (clip, rect);
+}
+
void
_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
{
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index e2ad7e4..e53506c 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1487,7 +1487,7 @@ _cairo_gl_surface_stroke (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -1552,7 +1552,7 @@ _cairo_gl_surface_fill (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
#if 0
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 383df99..1f8e9b1 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -3229,7 +3229,7 @@ _cairo_image_surface_paint (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -3347,7 +3347,7 @@ _cairo_image_surface_mask (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
@@ -3581,7 +3581,7 @@ _cairo_image_surface_stroke (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -3672,7 +3672,7 @@ _cairo_image_surface_fill (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (extents.is_bounded && clip != NULL) {
@@ -3991,7 +3991,7 @@ _cairo_image_surface_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 1edeac0..99ea07e 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -903,7 +903,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
@@ -1012,7 +1012,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
@@ -1060,7 +1060,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
@@ -1153,7 +1153,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
@@ -1326,7 +1326,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index fef12ec..6e6255e 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -3129,7 +3129,7 @@ _cairo_xcb_surface_render_paint (cairo_xcb_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -3196,7 +3196,7 @@ _cairo_xcb_surface_render_mask (cairo_xcb_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
@@ -3483,7 +3483,7 @@ _cairo_xcb_surface_render_stroke (cairo_xcb_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -3666,7 +3666,7 @@ _cairo_xcb_surface_render_fill (cairo_xcb_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -4630,7 +4630,7 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL) {
diff --git a/src/drm/cairo-drm-i915-glyphs.c b/src/drm/cairo-drm-i915-glyphs.c
index 40c8106..9944f15 100644
--- a/src/drm/cairo-drm-i915-glyphs.c
+++ b/src/drm/cairo-drm-i915-glyphs.c
@@ -310,7 +310,7 @@ i915_surface_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
diff --git a/src/drm/cairo-drm-i915-surface.c b/src/drm/cairo-drm-i915-surface.c
index f80612c..8d365dd 100644
--- a/src/drm/cairo-drm-i915-surface.c
+++ b/src/drm/cairo-drm-i915-surface.c
@@ -1889,7 +1889,7 @@ i915_surface_fill_with_alpha (void *abstract_dst,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (extents.is_bounded && clip != NULL) {
@@ -2004,7 +2004,7 @@ i915_surface_paint_with_alpha (void *abstract_dst,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -2099,7 +2099,7 @@ i915_surface_mask (void *abstract_dst,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
@@ -2243,7 +2243,7 @@ i915_surface_stroke (void *abstract_dst,
if (unlikely (status))
return status;
- if (_cairo_clip_contains_rectangle (clip, &extents))
+ if (_cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
diff --git a/src/drm/cairo-drm-i965-glyphs.c b/src/drm/cairo-drm-i965-glyphs.c
index e1ec95d..c66a63d 100644
--- a/src/drm/cairo-drm-i965-glyphs.c
+++ b/src/drm/cairo-drm-i965-glyphs.c
@@ -252,7 +252,7 @@ i965_surface_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
- if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents))
+ if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents.mask))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
diff --git a/src/drm/cairo-drm-i965-surface.c b/src/drm/cairo-drm-i965-surface.c
index a944fb3..e578d6f 100644
--- a/src/drm/cairo-drm-i965-surface.c
+++ b/src/drm/cairo-drm-i965-surface.c
@@ -1110,7 +1110,7 @@ i965_surface_paint (void *abstract_dst,
if (unlikely (status))
return status;
- if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents))
+ if (clip != NULL && _cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -1163,7 +1163,7 @@ i965_surface_mask (void *abstract_dst,
if (unlikely (status))
return status;
- if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents))
+ if (clip != NULL && _cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL && extents.is_bounded) {
@@ -1306,7 +1306,7 @@ i965_surface_stroke (void *abstract_dst,
if (unlikely (status))
return status;
- if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents))
+ if (clip != NULL && _cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
@@ -1413,7 +1413,7 @@ i965_surface_fill (void *abstract_dst,
if (unlikely (status))
return status;
- if (clip != NULL && _cairo_clip_contains_rectangle (clip, &extents))
+ if (clip != NULL && _cairo_clip_contains_extents (clip, &extents))
clip = NULL;
if (clip != NULL) {
commit 8546a877889bfafc056c867bc9aea25e9fdcdef0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 12 16:27:29 2010 +0100
test: Add partial-clip-text
This exercises a bug found by Igor Nikitin:
https://bugs.freedesktop.org/show_bug.cgi?id=29008
diff --git a/test/Makefile.am b/test/Makefile.am
index cfb8104..99d015c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -948,6 +948,9 @@ REFERENCE_IMAGES = \
paint-with-alpha.ref.png \
paint-with-alpha.svg.ref.png \
paint.ref.png \
+ partial-clip-text.ref.png \
+ partial-clip-text.ps.ref.png \
+ partial-clip-text.svg.ref.png \
partial-coverage-half-reference.ref.png \
partial-coverage-half-triangles.ref.png \
partial-coverage-intersecting-quads.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 99aab70..42afafd 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -182,6 +182,7 @@ test_sources = \
paint-repeat.c \
paint-source-alpha.c \
paint-with-alpha.c \
+ partial-clip-text.c \
partial-coverage.c \
path-append.c \
path-stroke-twice.c \
diff --git a/test/partial-clip-text.c b/test/partial-clip-text.c
new file mode 100644
index 0000000..f467a5f
--- /dev/null
+++ b/test/partial-clip-text.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Igor Nikitin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Igor Nikitin <igor_nikitin at valentina-db.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb( cr, 0, 0, 0 );
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, 40, 5);
+ cairo_clip (cr);
+
+ cairo_move_to (cr, 0, 12);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_show_text (cr, "CAIRO");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (partial_clip_text,
+ "Tests drawing text through a single, partial clip.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ 40, 15,
+ NULL, draw)
diff --git a/test/partial-clip-text.ps.ref.png b/test/partial-clip-text.ps.ref.png
new file mode 100644
index 0000000..049bba5
Binary files /dev/null and b/test/partial-clip-text.ps.ref.png differ
diff --git a/test/partial-clip-text.ref.png b/test/partial-clip-text.ref.png
new file mode 100644
index 0000000..6deaf75
Binary files /dev/null and b/test/partial-clip-text.ref.png differ
diff --git a/test/partial-clip-text.svg.ref.png b/test/partial-clip-text.svg.ref.png
new file mode 100644
index 0000000..dc3fc58
Binary files /dev/null and b/test/partial-clip-text.svg.ref.png differ
More information about the cairo-commit
mailing list