[cairo-commit] 3 commits - src/cairo-gstate.c src/cairo-image-compositor.c test/degenerate-solid-dash.c test/Makefile.sources test/reference

Chris Wilson ickle at kemper.freedesktop.org
Sun Apr 29 06:04:15 PDT 2012


 src/cairo-gstate.c                           |   35 +++++++++++--
 src/cairo-image-compositor.c                 |    6 +-
 test/Makefile.sources                        |    1 
 test/degenerate-solid-dash.c                 |   69 +++++++++++++++++++++++++++
 test/reference/degenerate-solid-dash.ref.png |binary
 5 files changed, 103 insertions(+), 8 deletions(-)

New commits:
commit 9176e640d7cb5cae5d89722aa560fba19bc08a8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 29 13:40:48 2012 +0100

    gstate: Reduce degenerate dash to solid
    
    If the dash specifies that the pen is always on (i.e. the total of the
    off segments is zero), then we can eliminate the dash pattern.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 23e8b18..650ed37 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -518,8 +518,8 @@ _cairo_gstate_get_line_join (cairo_gstate_t *gstate)
 cairo_status_t
 _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset)
 {
-    unsigned int i;
-    double dash_total;
+    double dash_total, on_total, off_total;
+    int i;
 
     free (gstate->stroke_style.dash);
 
@@ -539,12 +539,26 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
 
     memcpy (gstate->stroke_style.dash, dash, gstate->stroke_style.num_dashes * sizeof (double));
 
-    dash_total = 0.0;
-    for (i = 0; i < gstate->stroke_style.num_dashes; i++) {
+    on_total = off_total = dash_total = 0.0;
+    for (i = 0; i < num_dashes; i++) {
 	if (gstate->stroke_style.dash[i] < 0)
 	    return _cairo_error (CAIRO_STATUS_INVALID_DASH);
 
+	if (gstate->stroke_style.dash[i] == 0) {
+	    if (i > 0 && i < num_dashes - 1) {
+		gstate->stroke_style.dash[i-1] +=
+		    gstate->stroke_style.dash[i+1];
+		gstate->stroke_style.num_dashes -= 2;
+		i++;
+		continue;
+	    }
+	}
+
 	dash_total += gstate->stroke_style.dash[i];
+	if ((i & 1) == 0)
+	    on_total += gstate->stroke_style.dash[i];
+	else
+	    off_total += gstate->stroke_style.dash[i];
     }
 
     if (dash_total == 0.0)
@@ -552,8 +566,19 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
 
     /* An odd dash value indicate symmetric repeating, so the total
      * is twice as long. */
-    if (gstate->stroke_style.num_dashes & 1)
+    if (gstate->stroke_style.num_dashes & 1) {
 	dash_total *= 2;
+	on_total += off_total;
+    }
+
+    if (dash_total - on_total < CAIRO_FIXED_ERROR_DOUBLE) {
+	/* Degenerate dash -> solid line */
+	free (gstate->stroke_style.dash);
+	gstate->stroke_style.dash = NULL;
+	gstate->stroke_style.num_dashes = 0;
+	gstate->stroke_style.dash_offset = 0.0;
+	return CAIRO_STATUS_SUCCESS;
+    }
 
     /* The dashing code doesn't like a negative offset or a big positive
      * offset, so we compute an equivalent offset which is guaranteed to be
commit 47368d5e83f95dfed500f81068d7346a93145a20
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 29 14:01:11 2012 +0100

    image: Add a little bit of debugging to show number of boxes being drawn
    
    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 fb4b2fb..5a1ea4a 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -93,7 +93,7 @@ draw_image_boxes (void *_dst,
     struct _cairo_boxes_chunk *chunk;
     int i;
 
-    TRACE ((stderr, "%s\n", __FUNCTION__));
+    TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes));
 
     for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
 	for (i = 0; i < chunk->count; i++) {
@@ -325,7 +325,7 @@ fill_boxes (void		*_dst,
     uint32_t pixel;
     int i;
 
-    TRACE ((stderr, "%s\n", __FUNCTION__));
+    TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes));
 
     if (fill_reduces_to_source (op, color, dst) &&
 	color_to_pixel (color, dst->pixman_format, &pixel))
@@ -485,7 +485,7 @@ composite_boxes (void			*_dst,
     int i;
 
     /* XXX consider using a region? saves multiple prepare-composite */
-    TRACE ((stderr, "%s\n", __FUNCTION__));
+    TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes));
 
     if (((cairo_surface_t *)_dst)->is_clear &&
 	(op == CAIRO_OPERATOR_SOURCE ||
commit 0c14ce6dca3031320d2b9fb419aaf4e153d158d6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 29 13:55:10 2012 +0100

    test: Exercise degenerate dashes that are wholly solid
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 4d48714..4e1fb84 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -103,6 +103,7 @@ test_sources = \
 	degenerate-pen.c				\
 	degenerate-radial-gradient.c			\
 	degenerate-rel-curve-to.c			\
+	degenerate-solid-dash.c				\
 	drunkard-tails.c				\
 	device-offset.c					\
 	device-offset-fractional.c			\
diff --git a/test/degenerate-solid-dash.c b/test/degenerate-solid-dash.c
new file mode 100644
index 0000000..18457b4
--- /dev/null
+++ b/test/degenerate-solid-dash.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    const double dashes_1[] = { 10, 0 };
+    const double dashes_2[] = { 10, 0, 10, 10};
+    const double dashes_3[] = { 10, 0, 10, 0};
+
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+    cairo_set_source_rgb (cr, 0, 0, 0);
+
+    cairo_set_line_width (cr, 6);
+
+    cairo_set_dash (cr, NULL, 0, 0);
+    cairo_rectangle (cr, 10, 10, 30, 30);
+    cairo_stroke (cr);
+
+    cairo_translate (cr, 50, 0);
+    cairo_set_dash (cr, dashes_1, 2, 0);
+    cairo_rectangle (cr, 10, 10, 30, 30);
+    cairo_stroke (cr);
+
+    cairo_translate (cr, 0, 50);
+    cairo_set_dash (cr, dashes_2, 2, 0);
+    cairo_rectangle (cr, 10, 10, 30, 30);
+    cairo_stroke (cr);
+
+    cairo_translate (cr, -50, 0);
+    cairo_set_dash (cr, dashes_3, 2, 0);
+    cairo_rectangle (cr, 10, 10, 30, 30);
+    cairo_stroke (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_solid_dash,
+	    "Exercises degenerate dash ellison",
+	    "stroke, dash", /* keywords */
+	    NULL, /* requirements */
+	    100, 100,
+	    NULL, draw)
diff --git a/test/reference/degenerate-solid-dash.ref.png b/test/reference/degenerate-solid-dash.ref.png
new file mode 100644
index 0000000..e58c2e4
Binary files /dev/null and b/test/reference/degenerate-solid-dash.ref.png differ


More information about the cairo-commit mailing list