[cairo-commit] 4 commits - src/cairo-clip.c src/cairo-pdf-surface.c src/cairo-surface.c test/clip-all.c test/clip-empty.c test/clip-empty-ref.png test/Makefile.am
Chris Wilson
ickle at kemper.freedesktop.org
Tue Nov 6 07:31:43 PST 2007
src/cairo-clip.c | 6 ++++
src/cairo-pdf-surface.c | 36 ++++++++++++++----------
src/cairo-surface.c | 61 ++++++++++++++++++++++++++++++++++------
test/Makefile.am | 2 +
test/clip-all.c | 10 ++++++
test/clip-empty-ref.png |binary
test/clip-empty.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 164 insertions(+), 23 deletions(-)
New commits:
commit 62d64e12aa9264a17c9bb7d6ae154a1778f0c7e1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 6 14:24:52 2007 +0000
[cairo-pdf-surface] Create a new path for an empty clip.
If the clip path is empty, then we need to start a new path otherwise
the clip is ineffective.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 6db1018..695e6e9 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3995,26 +3995,34 @@ _cairo_pdf_surface_emit_clip (cairo_pdf_surface_t *surface,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule)
{
- cairo_status_t status;
const char *pdf_operator;
- pdf_path_info_t info;
if (path == NULL) {
_cairo_output_stream_printf (surface->output, "Q q\r\n");
return CAIRO_STATUS_SUCCESS;
}
- info.output = surface->output;
- info.cairo_to_pdf = &surface->cairo_to_pdf;
- info.ctm_inverse = NULL;
-
- status = _cairo_path_fixed_interpret (path,
- CAIRO_DIRECTION_FORWARD,
- _cairo_pdf_path_move_to,
- _cairo_pdf_path_line_to,
- _cairo_pdf_path_curve_to,
- _cairo_pdf_path_close_path,
- &info);
+ if (! path->has_current_point) {
+ /* construct an empty path */
+ _cairo_output_stream_printf (surface->output, "0 0 m ");
+ } else {
+ pdf_path_info_t info;
+ cairo_status_t status;
+
+ info.output = surface->output;
+ info.cairo_to_pdf = &surface->cairo_to_pdf;
+ info.ctm_inverse = NULL;
+
+ status = _cairo_path_fixed_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cairo_pdf_path_move_to,
+ _cairo_pdf_path_line_to,
+ _cairo_pdf_path_curve_to,
+ _cairo_pdf_path_close_path,
+ &info);
+ if (status)
+ return status;
+ }
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
@@ -4031,7 +4039,7 @@ _cairo_pdf_surface_emit_clip (cairo_pdf_surface_t *surface,
"%s n\r\n",
pdf_operator);
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
commit b4057b8643cf02439b6033d7443d0d4c42220a62
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 6 09:45:54 2007 +0000
[cairo-clip] Special case using an empty clip path.
Detect when the user calls cairo_clip() with an empty clip path and
mark the clip as all_clipped.
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 8254105..0fed3f6 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -537,6 +537,12 @@ _cairo_clip_clip (cairo_clip_t *clip,
if (clip->all_clipped)
return CAIRO_STATUS_SUCCESS;
+ /* catch the empty clip path */
+ if (! path->has_current_point) {
+ _cairo_clip_set_all_clipped (clip, target);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
status = _cairo_clip_intersect_path (clip,
path, fill_rule, tolerance,
antialias);
commit 2f0867b43fbc9a385a32a2a39895f4c3559f6ddf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Nov 6 09:44:03 2007 +0000
[cairo-surface] Handle the all clipped out case.
Explicitly handle a clip which represents that the entire surface is
clipped out.
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=13084.
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 97a8b9e..ed332f5 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1903,6 +1903,38 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
+
+/**
+ * _cairo_surface_set_empty_clip_path:
+ * @surface: the #cairo_surface_t to set the clip on
+ * @serial: the clip serial number associated with the clip path
+ *
+ * Create an empty clip path, one that represents the entire surface clipped
+ * out, and assigns the given clipping serial to the surface.
+ **/
+static cairo_status_t
+_cairo_surface_set_empty_clip_path (cairo_surface_t *surface,
+ unsigned int serial)
+{
+ cairo_path_fixed_t path;
+ cairo_status_t status;
+
+ _cairo_path_fixed_init (&path);
+
+ status = surface->backend->intersect_clip_path (surface,
+ &path,
+ CAIRO_FILL_RULE_WINDING,
+ 0,
+ CAIRO_ANTIALIAS_DEFAULT);
+
+ if (status == CAIRO_STATUS_SUCCESS)
+ surface->current_clip_serial = serial;
+
+ _cairo_path_fixed_fini (&path);
+
+ return _cairo_surface_set_error (surface, status);
+}
+
cairo_status_t
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
{
@@ -1926,15 +1958,26 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
return CAIRO_STATUS_SUCCESS;
if (clip) {
- if (clip->path)
- return _cairo_surface_set_clip_path (surface,
- clip->path,
- clip->serial);
-
- if (clip->has_region)
- return _cairo_surface_set_clip_region (surface,
- &clip->region,
- clip->serial);
+ if (clip->all_clipped) {
+ if (surface->backend->intersect_clip_path != NULL)
+ return _cairo_surface_set_empty_clip_path (surface,
+ clip->serial);
+
+ if (surface->backend->set_clip_region != NULL)
+ return _cairo_surface_set_clip_region (surface,
+ &clip->region,
+ clip->serial);
+ } else {
+ if (clip->path)
+ return _cairo_surface_set_clip_path (surface,
+ clip->path,
+ clip->serial);
+
+ if (clip->has_region)
+ return _cairo_surface_set_clip_region (surface,
+ &clip->region,
+ clip->serial);
+ }
}
return _cairo_surface_reset_clip (surface);
commit 641215b2b018e98b298db5042360e2e22ab5a0aa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 5 22:22:42 2007 +0000
[test/clip-all] Combine text and everything clipped out.
https://bugs.freedesktop.org/show_bug.cgi?id=13084 demonstrates a
regression where the clip is ignored by the xlib backend whilst
rendering text. Therefore we extend the current test cases to combine
a clip that represents everything clipped out with the rendering of
text. For completeness, we add a new test case that exactly mimics the
sequence of cairo operations that lead to the discovery of this bug -
namely the rendering of text with an empty clip path.
diff --git a/test/Makefile.am b/test/Makefile.am
index bf10ba9..3975bd0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -8,6 +8,7 @@ caps-joins \
caps-joins-alpha \
caps-sub-paths \
clip-all \
+clip-empty \
clip-fill-rule \
clip-fill-rule-pixel-aligned \
clip-nesting \
@@ -221,6 +222,7 @@ REFERENCE_IMAGES = \
caps-joins-ref.png \
caps-sub-paths-ref.png \
clip-all-ref.png \
+ clip-empty-ref.png \
clip-fill-rule-pixel-aligned-ref.png \
clip-fill-rule-pixel-aligned-rgb24-ref.png \
clip-fill-rule-ps-argb32-ref.png \
diff --git a/test/clip-all.c b/test/clip-all.c
index 2ff883d..b38e7b9 100644
--- a/test/clip-all.c
+++ b/test/clip-all.c
@@ -62,6 +62,16 @@ draw (cairo_t *cr, int width, int height)
cairo_set_source_rgb (cr, 1, 1, 0);
cairo_fill (cr);
+ /* https://bugs.freedesktop.org/show_bug.cgi?id=13084 */
+ cairo_select_font_face (cr,
+ "Bitstream Vera Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_move_to (cr, 0., SIZE);
+ cairo_show_text (cr, "cairo");
+
+
return CAIRO_TEST_SUCCESS;
}
diff --git a/test/clip-empty-ref.png b/test/clip-empty-ref.png
new file mode 100644
index 0000000..6c14df5
Binary files /dev/null and b/test/clip-empty-ref.png differ
diff --git a/test/clip-empty.c b/test/clip-empty.c
new file mode 100644
index 0000000..9049153
--- /dev/null
+++ b/test/clip-empty.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_test_draw_function_t draw;
+
+cairo_test_t test = {
+ "clip-empty",
+ "Test clipping with an empty clip path",
+ SIZE, SIZE,
+ draw
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_reset_clip (cr);
+ cairo_clip (cr);
+
+ cairo_translate (cr, .5, .5);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ /* https://bugs.freedesktop.org/show_bug.cgi?id=13084 */
+ cairo_select_font_face (cr,
+ "Bitstream Vera Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_move_to (cr, 0., SIZE);
+ cairo_show_text (cr, "cairo");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+ return cairo_test (&test);
+}
More information about the cairo-commit
mailing list