[cairo-commit] 4 commits - src/cairo-ps-surface.c
test/dash-zero-length.c test/dash-zero-length-ps-argb32-ref.png
test/dash-zero-length-ref.png
test/dash-zero-length-rgb24-ref.png test/leaky-dash.c
test/Makefile.am test/text-pattern-pdf-argb32-ref.png
test/text-pattern-ps-argb32-ref.png
Carl Worth
cworth at kemper.freedesktop.org
Wed Jun 28 21:30:46 PDT 2006
src/cairo-ps-surface.c | 79 ++++++++++++++++++++++++++++-
test/Makefile.am | 1
test/dash-zero-length-ps-argb32-ref.png |binary
test/dash-zero-length-ref.png |binary
test/dash-zero-length-rgb24-ref.png |binary
test/dash-zero-length.c | 85 +++++++++++++++++++++-----------
test/leaky-dash.c | 3 -
test/text-pattern-pdf-argb32-ref.png |binary
test/text-pattern-ps-argb32-ref.png |binary
9 files changed, 134 insertions(+), 34 deletions(-)
New commits:
diff-tree 8effd25c1b05607ff6501821f1d80745677d8e72 (from a64b946ee0512d85d3c790c67aad8a882c5c3533)
Author: Carl Worth <cworth at cworth.org>
Date: Thu Jun 29 06:25:24 2006 +0200
Update PDF and PS reference images for test/text-pattern.
diff --git a/test/text-pattern-pdf-argb32-ref.png b/test/text-pattern-pdf-argb32-ref.png
new file mode 100644
index 0000000..17afd64
Binary files /dev/null and b/test/text-pattern-pdf-argb32-ref.png differ
diff --git a/test/text-pattern-ps-argb32-ref.png b/test/text-pattern-ps-argb32-ref.png
new file mode 100644
index 0000000..1bc8dd4
Binary files /dev/null and b/test/text-pattern-ps-argb32-ref.png differ
diff-tree a64b946ee0512d85d3c790c67aad8a882c5c3533 (from 734e10709f5c62c0b64e51a03df8e109e7eebe0d)
Author: Carl Worth <cworth at cworth.org>
Date: Thu Jun 29 06:24:44 2006 +0200
Mark test/leaky-dash as an expected failure.
diff --git a/test/Makefile.am b/test/Makefile.am
index 4da7ed4..bd2e9a6 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -292,6 +292,7 @@ XFAIL_TESTS = \
a8-mask \
extend-reflect \
filter-nearest-offset \
+leaky-dash \
pixman-rotate \
self-intersecting \
text-rotate
diff --git a/test/leaky-dash.c b/test/leaky-dash.c
index 95c5ca7..44f04f0 100644
--- a/test/leaky-dash.c
+++ b/test/leaky-dash.c
@@ -64,5 +64,6 @@ draw (cairo_t *cr, int width, int height
int
main (void)
{
- return cairo_test (&test, draw);
+ return cairo_test_expect_failure (&test, draw,
+ "known bug (#4863) which has existed since the 1.0 release");
}
diff-tree 734e10709f5c62c0b64e51a03df8e109e7eebe0d (from 8aa306caac99ebe074a6cde8b424b1780cafefee)
Author: Carl Worth <cworth at cworth.org>
Date: Thu Jun 29 06:12:48 2006 +0200
Add several more stress tests to test/dash-zero-length
diff --git a/test/dash-zero-length-ps-argb32-ref.png b/test/dash-zero-length-ps-argb32-ref.png
index 5c7fab5..897f25f 100644
Binary files a/test/dash-zero-length-ps-argb32-ref.png and b/test/dash-zero-length-ps-argb32-ref.png differ
diff --git a/test/dash-zero-length-ref.png b/test/dash-zero-length-ref.png
index aca856f..16024f4 100644
Binary files a/test/dash-zero-length-ref.png and b/test/dash-zero-length-ref.png differ
diff --git a/test/dash-zero-length-rgb24-ref.png b/test/dash-zero-length-rgb24-ref.png
index f5e40e8..41b595c 100644
Binary files a/test/dash-zero-length-rgb24-ref.png and b/test/dash-zero-length-rgb24-ref.png differ
diff --git a/test/dash-zero-length.c b/test/dash-zero-length.c
index a5d0047..2014c07 100644
--- a/test/dash-zero-length.c
+++ b/test/dash-zero-length.c
@@ -26,7 +26,7 @@
#include "cairo-test.h"
#define IMAGE_WIDTH 19
-#define IMAGE_HEIGHT 25
+#define IMAGE_HEIGHT 61
/* A test of the two extremes of dashing: a solid line
* and an invisible one. Also test that capping works
@@ -39,44 +39,71 @@ cairo_test_t test = {
IMAGE_WIDTH, IMAGE_HEIGHT
};
+static void
+draw_dash (cairo_t *cr, double *dash, int num_dashes)
+{
+ cairo_set_dash (cr, dash, num_dashes, 0.0);
+ cairo_move_to (cr, 1, 2);
+ cairo_line_to (cr, 18, 2);
+ cairo_stroke (cr);
+ cairo_translate (cr, 0, 3);
+}
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
- double solid_line[] = { 4, 0 };
- double invisible_line[] = { 0, 4 };
- double dotted_line[] = { 0, 6 };
- double rounded_line[] = { 2, 6 };
+ static double solid_line[] = { 4, 0 };
+ static double invisible_line[] = { 0, 4 };
+ static double dotted_line[] = { 0, 6 };
+ static double zero_1_of_3[] = { 0, 2, 3 };
+ static double zero_2_of_3[] = { 1, 0, 3 };
+ static double zero_3_of_3[] = { 1, 2, 0 };
+ static double zero_1_of_4[] = { 0, 2, 3, 4 };
+ static double zero_2_of_4[] = { 1, 0, 3, 4 };
+ static double zero_3_of_4[] = { 1, 2, 0, 4 };
+ static double zero_4_of_4[] = { 1, 2, 3, 0 };
+ static double zero_1_2_of_4[] = { 0, 0, 3, 4 };
+ static double zero_1_3_of_4[] = { 0, 2, 0, 4 };
+/* Clearly it would be nice to draw this one as well, but it seems to trigger a bug in ghostscript. */
+#if BUG_FIXED_IN_GHOSTSCRIPT
+ static double zero_1_4_of_4[] = { 0, 2, 3, 0 };
+#endif
+ static double zero_2_3_of_4[] = { 1, 0, 0, 4 };
+ static double zero_2_4_of_4[] = { 1, 0, 3, 0 };
+ static double zero_3_4_of_4[] = { 1, 2, 0, 0 };
+ static double zero_1_2_3_of_4[] = { 0, 0, 0, 4 };
+ static double zero_1_2_4_of_4[] = { 0, 0, 3, 0 };
+ static double zero_1_3_4_of_4[] = { 0, 2, 0, 0 };
+ static double zero_2_3_4_of_4[] = { 1, 0, 0, 0 };
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_set_line_width (cr, 2);
- /* draw a solid line */
- cairo_set_dash (cr, solid_line, 2, 0);
- cairo_move_to (cr, 1, 2);
- cairo_line_to (cr, 18, 2);
- cairo_stroke (cr);
-
- /* draw an invisible line */
- cairo_set_dash (cr, invisible_line, 2, 0);
- cairo_move_to (cr, 1, 8);
- cairo_line_to (cr, 18, 8);
- cairo_stroke (cr);
+ draw_dash (cr, solid_line, 2);
+ draw_dash (cr, invisible_line, 2);
- /* draw a dotted line */
- cairo_set_line_width (cr, 5);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_dash (cr, dotted_line, 2, 0);
- cairo_move_to (cr, 5, 13);
- cairo_line_to (cr, 18, 13);
- cairo_stroke (cr);
+ draw_dash (cr, dotted_line, 2);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
- /* draw a rounded line */
- cairo_set_line_width (cr, 5);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_dash (cr, rounded_line, 2, 2);
- cairo_move_to (cr, 5, 20);
- cairo_line_to (cr, 18, 20);
- cairo_stroke (cr);
+ draw_dash (cr, zero_1_of_3, 3);
+ draw_dash (cr, zero_2_of_3, 3);
+ draw_dash (cr, zero_3_of_3, 3);
+ draw_dash (cr, zero_1_of_4, 4);
+ draw_dash (cr, zero_2_of_4, 4);
+ draw_dash (cr, zero_3_of_4, 4);
+ draw_dash (cr, zero_4_of_4, 4);
+ draw_dash (cr, zero_1_2_of_4, 4);
+ draw_dash (cr, zero_1_3_of_4, 4);
+#if BUG_FIXED_IN_GHOSTSCRIPT
+ draw_dash (cr, zero_1_4_of_4, 4);
+#endif
+ draw_dash (cr, zero_2_3_of_4, 4);
+ draw_dash (cr, zero_2_4_of_4, 4);
+ draw_dash (cr, zero_3_4_of_4, 4);
+ draw_dash (cr, zero_1_2_3_of_4, 4);
+ draw_dash (cr, zero_1_2_4_of_4, 4);
+ draw_dash (cr, zero_1_3_4_of_4, 4);
+ draw_dash (cr, zero_2_3_4_of_4, 4);
return CAIRO_TEST_SUCCESS;
}
diff-tree 8aa306caac99ebe074a6cde8b424b1780cafefee (from 7285499700a4f0f4bb95f003d0c730246bf3eabd)
Author: Carl Worth <cworth at cworth.org>
Date: Thu Jun 29 05:13:37 2006 +0200
PS: Fix for dash-zero-length
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index d72c3c0..b45e6f9 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1805,15 +1805,82 @@ _cairo_ps_surface_stroke (void *abstra
cairo_ps_surface_t *surface = abstract_surface;
cairo_output_stream_t *stream = surface->stream;
cairo_int_status_t status;
+ double *dash = style->dash;
+ int num_dashes = style->num_dashes;
+ double dash_offset = style->dash_offset;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return _analyze_operation (surface, op, source);
assert (operation_supported (surface, op, source));
+
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_stroke\n");
+ /* PostScript has "special needs" when it comes to zero-length
+ * dash segments with butt caps. It apparently (at least
+ * according to ghostscript) draws hairlines for this
+ * case. That's not what the cairo semantics want, so we first
+ * touch up the array to eliminate any 0.0 values that will
+ * result in "on" segments.
+ */
+ if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
+ int i;
+
+ /* If there's an odd number of dash values they will each get
+ * interpreted as both on and off. So we first explicitly
+ * expand the array to remove the duplicate usage so that we
+ * can modify some of the values.
+ */
+ if (num_dashes % 2) {
+ dash = malloc (2 * num_dashes * sizeof (double));
+ if (dash == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ memcpy (dash, style->dash, num_dashes * sizeof (double));
+ memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
+
+ num_dashes *= 2;
+ }
+
+ for (i = 0; i < num_dashes; i += 2) {
+ if (dash[i] == 0.0) {
+ /* If we're at the front of the list, we first rotate
+ * two elements from the end of the list to the front
+ * of the list before folding away the 0.0. Or, if
+ * there are only two dash elements, then there is
+ * nothing at all to draw.
+ */
+ if (i == 0) {
+ double last_two[2];
+
+ if (num_dashes == 2) {
+ if (dash != style->dash)
+ free (dash);
+ return CAIRO_STATUS_SUCCESS;
+ }
+ /* The cases of num_dashes == 0, 1, or 3 elements
+ * cannot exist, so the rotation of 2 elements
+ * will always be safe */
+ memcpy (last_two, dash + num_dashes - 2, sizeof (last_two));
+ memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double));
+ memcpy (dash, last_two, sizeof (last_two));
+ dash_offset += dash[0] + dash[1];
+ i = 2;
+ }
+ dash[i-1] += dash[i+1];
+ num_dashes -= 2;
+ memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double));
+ /* If we might have just rotated, it's possible that
+ * we rotated a 0.0 value to the front of the list.
+ * Set i to -2 so it will get incremented to 0. */
+ if (i == 2)
+ i = -2;
+ }
+ }
+ }
+
emit_pattern (surface, source);
_cairo_output_stream_printf (stream,
@@ -1836,14 +1903,18 @@ _cairo_ps_surface_stroke (void *abstra
_cairo_output_stream_printf (stream, "%d setlinejoin\n",
_cairo_ps_line_join (style->line_join));
/* dashes */
- if (style->num_dashes) {
+ if (num_dashes) {
int d;
+
_cairo_output_stream_printf (stream, "[");
- for (d = 0; d < style->num_dashes; d++)
- _cairo_output_stream_printf (stream, " %f", style->dash[d]);
+ for (d = 0; d < num_dashes; d++)
+ _cairo_output_stream_printf (stream, " %f", dash[d]);
_cairo_output_stream_printf (stream, "] %f setdash\n",
- style->dash_offset);
+ dash_offset);
}
+ if (dash != style->dash)
+ free (dash);
+
/* miter limit */
_cairo_output_stream_printf (stream, "%f setmiterlimit\n",
style->miter_limit);
More information about the cairo-commit
mailing list