Bug 885585 - Work around Quartz issue where a stroke with a dasharray whose gaps add up to zero does not render. r=vlad,longsonr
☠☠ backed out by 75895fe57f56 ☠ ☠
authorCameron McCormack <cam@mcc.id.au>
Sun, 23 Jun 2013 12:36:23 +1000
changeset 147685 fd367ec484cff58d5e07922faebd63ad5fed60d6
parent 147684 319ce193cdae1a1d846d4dabc89db1487ee495d6
child 147686 e762fad3e026b528940b5261ea6417d8ea06302f
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad, longsonr
bugs885585
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 885585 - Work around Quartz issue where a stroke with a dasharray whose gaps add up to zero does not render. r=vlad,longsonr
gfx/cairo/README
gfx/cairo/cairo/src/cairo-quartz-surface.c
gfx/cairo/dasharray-zero-gap.patch
layout/reftests/svg/reftest.list
layout/reftests/svg/stroke-dasharray-01-ref.svg
layout/reftests/svg/stroke-dasharray-01.svg
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -201,16 +201,18 @@ handle-multi-path-clip.patch: bug 813124
 win32-gdi-font-cache.patch: Bug 717178, cache GDI font faces to reduce usage of GDI resources
 
 win32-gdi-font-cache-no-HFONT.patch: Bug 717178, don't cache GDI font faces when an HFONT belonging to the caller is passed in
 
 fix-win32-font-assertion.patch: Bug 838617, fix assertion from bug 717178 that was in the wrong place
 
 xlib-flush-glyphs.patch: bug 839745, flush glyphs when necessary
 
+dasharray-zero-gap.patch: bug 885585, ensure strokes get painted when the gaps in a dash array are all zero length
+
 ==== pixman patches ====
 
 pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
 
 pixman-rename-and-endian.patch: include cairo-platform.h for renaming of external symbols and endian macros
 
 NOTE: we previously supported ARM assembler on MSVC, this has been removed because of the maintenance burden
 
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -2573,29 +2573,43 @@ static cairo_int_status_t
 
     if (style->dash && style->num_dashes) {
 #define STATIC_DASH 32
 	cairo_quartz_float_t sdash[STATIC_DASH];
 	cairo_quartz_float_t *fdash = sdash;
 	unsigned int max_dashes = style->num_dashes;
 	unsigned int k;
 
-	if (style->num_dashes%2)
-	    max_dashes *= 2;
-	if (max_dashes > STATIC_DASH)
-	    fdash = _cairo_malloc_ab (max_dashes, sizeof (cairo_quartz_float_t));
-	if (fdash == NULL)
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	for (k = 0; k < max_dashes; k++)
-	    fdash[k] = (cairo_quartz_float_t) style->dash[k % style->num_dashes];
-
-	CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, max_dashes);
-	if (fdash != sdash)
-	    free (fdash);
+	bool set_line_dash = false;
+	if (style->num_dashes % 2 == 0) {
+	    for (k = 1; k < max_dashes; k++) {
+		if (style->dash[k]) {
+		    set_line_dash = true;
+		    break;
+		}
+	    }
+	} else
+	    set_line_dash = true;
+
+	if (set_line_dash) {
+	    if (style->num_dashes%2)
+		max_dashes *= 2;
+	    if (max_dashes > STATIC_DASH)
+		fdash = _cairo_malloc_ab (max_dashes, sizeof (cairo_quartz_float_t));
+	    if (fdash == NULL)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	    for (k = 0; k < max_dashes; k++)
+		fdash[k] = (cairo_quartz_float_t) style->dash[k % style->num_dashes];
+
+	    CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, max_dashes);
+	    if (fdash != sdash)
+		free (fdash);
+	} else
+	    CGContextSetLineDash (state.context, 0, NULL, 0);
     } else
 	CGContextSetLineDash (state.context, 0, NULL, 0);
 
 
     _cairo_quartz_cairo_path_to_quartz_context (path, state.context);
 
     _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
     CGContextConcatCTM (state.context, strokeTransform);
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/dasharray-zero-gap.patch
@@ -0,0 +1,60 @@
+diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
+--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
++++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
+@@ -2573,29 +2573,43 @@ static cairo_int_status_t
+ 
+     if (style->dash && style->num_dashes) {
+ #define STATIC_DASH 32
+ 	cairo_quartz_float_t sdash[STATIC_DASH];
+ 	cairo_quartz_float_t *fdash = sdash;
+ 	unsigned int max_dashes = style->num_dashes;
+ 	unsigned int k;
+ 
+-	if (style->num_dashes%2)
+-	    max_dashes *= 2;
+-	if (max_dashes > STATIC_DASH)
+-	    fdash = _cairo_malloc_ab (max_dashes, sizeof (cairo_quartz_float_t));
+-	if (fdash == NULL)
+-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+-
+-	for (k = 0; k < max_dashes; k++)
+-	    fdash[k] = (cairo_quartz_float_t) style->dash[k % style->num_dashes];
+-
+-	CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, max_dashes);
+-	if (fdash != sdash)
+-	    free (fdash);
++	bool set_line_dash = false;
++	if (style->num_dashes % 2 == 0) {
++	    for (k = 1; k < max_dashes; k++) {
++		if (style->dash[k]) {
++		    set_line_dash = true;
++		    break;
++		}
++	    }
++	} else
++	    set_line_dash = true;
++
++	if (set_line_dash) {
++	    if (style->num_dashes%2)
++		max_dashes *= 2;
++	    if (max_dashes > STATIC_DASH)
++		fdash = _cairo_malloc_ab (max_dashes, sizeof (cairo_quartz_float_t));
++	    if (fdash == NULL)
++		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
++
++	    for (k = 0; k < max_dashes; k++)
++		fdash[k] = (cairo_quartz_float_t) style->dash[k % style->num_dashes];
++
++	    CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, max_dashes);
++	    if (fdash != sdash)
++		free (fdash);
++	} else
++	    CGContextSetLineDash (state.context, 0, NULL, 0);
+     } else
+ 	CGContextSetLineDash (state.context, 0, NULL, 0);
+ 
+ 
+     _cairo_quartz_cairo_path_to_quartz_context (path, state.context);
+ 
+     _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
+     CGContextConcatCTM (state.context, strokeTransform);
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -304,16 +304,17 @@ fuzzy-if(OSX==10.7,6,2) fuzzy-if(OSX==10
 == text-layout-05.svg text-layout-05-ref.svg
 fuzzy-if(cocoaWidget&&layersGPUAccelerated,1,3) == text-layout-06.svg text-layout-06-ref.svg
 == text-layout-07.svg text-layout-07-ref.svg
 pref(svg.text.css-frames.enabled,true) == text-layout-08.svg text-layout-08-ref.svg
 == text-scale-01.svg text-scale-01-ref.svg
 HTTP(..) == text-scale-02.svg text-scale-02-ref.svg
 HTTP(..) == text-scale-03.svg text-scale-03-ref.svg
 == text-stroke-scaling-01.svg text-stroke-scaling-01-ref.svg
+== stroke-dasharray-01.svg stroke-dasharray-01-ref.svg
 == stroke-dasharray-and-pathLength-01.svg pass.svg
 == stroke-dasharray-and-text-01.svg stroke-dasharray-and-text-01-ref.svg 
 == stroke-linecap-square-w-zero-length-segs-01.svg pass.svg
 == stroke-linecap-square-w-zero-length-segs-02.svg pass.svg
 == textPath-01.svg textPath-01-ref.svg
 == textPath-02.svg pass.svg
 == textPath-03.svg pass.svg
 == text-style-01a.svg text-style-01-ref.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/stroke-dasharray-01-ref.svg
@@ -0,0 +1,14 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Reference for a stroke with a dasharray whose gaps add up to 0 still painting</title>
+  <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=885585 -->
+
+  <g fill="none" stroke="black" stroke-width="2">
+    <path d="M 100,100 v 100"/>
+    <path d="M 110,100 h 100"/>
+    <path d="M 120,120 l 100,100"/>
+  </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/stroke-dasharray-01.svg
@@ -0,0 +1,14 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Test for a stroke with a dasharray whose gaps add up to 0 still painting</title>
+  <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=885585 -->
+
+  <g fill="none" stroke="black" stroke-width="2" stroke-dasharray="10 0">
+    <path d="M 100,100 v 100"/>
+    <path d="M 110,100 h 100"/>
+    <path d="M 120,120 l 100,100"/>
+  </g>
+</svg>