1From: Robert O'Callahan <robert@ocallahan.org>
2Bug 768348. Avoid ExtCreatePen failures by avoiding rounding widths and dash lengths down to zero. r=jrmuizel
3
4diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
5--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
6+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
7@@ -1251,22 +1251,24 @@ static cairo_int_status_t
8 {
9     cairo_win32_surface_t *surface = abstract_surface;
10     cairo_int_status_t status;
11     HPEN pen;
12     LOGBRUSH brush;
13     COLORREF color;
14     XFORM xform;
15     DWORD pen_style;
16+    DWORD pen_width;
17     DWORD *dash_array;
18     HGDIOBJ obj;
19     unsigned int i;
20     cairo_solid_pattern_t clear;
21     cairo_matrix_t mat;
22     double scale;
23+    double scaled_width;
24
25     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
26     if (status)
27 	return status;
28
29     if (op == CAIRO_OPERATOR_CLEAR) {
30 	_cairo_win32_printing_surface_init_clear_color (surface, &clear);
31 	source = (cairo_pattern_t*) &clear;
32@@ -1288,17 +1290,21 @@ static cairo_int_status_t
33     _cairo_matrix_factor_out_scale (&mat, &scale);
34
35     pen_style = PS_GEOMETRIC;
36     dash_array = NULL;
37     if (style->num_dashes) {
38 	pen_style |= PS_USERSTYLE;
39 	dash_array = calloc (sizeof (DWORD), style->num_dashes);
40 	for (i = 0; i < style->num_dashes; i++) {
41-	    dash_array[i] = (DWORD) (scale * style->dash[i]);
42+	    DWORD dashes = (DWORD) (scale * style->dash[i]);
43+	    /* zero dash-lengths cause ExtCreatePen to fail. Make the dashes
44+	     * longer if necessary.
45+	     */
46+	    dash_array[i] = MAX(1, dashes);
47 	}
48     } else {
49 	pen_style |= PS_SOLID;
50     }
51
52     SetMiterLimit (surface->dc, (FLOAT) (style->miter_limit), NULL);
53     if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
54 	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
55@@ -1310,18 +1316,29 @@ static cairo_int_status_t
56 	/* Color not used as the pen will only be used by WidenPath() */
57 	color = RGB (0,0,0);
58     }
59     brush.lbStyle = BS_SOLID;
60     brush.lbColor = color;
61     brush.lbHatch = 0;
62     pen_style |= _cairo_win32_line_cap (style->line_cap);
63     pen_style |= _cairo_win32_line_join (style->line_join);
64+    scaled_width = scale * style->line_width;
65+    if (scaled_width == 0.0)
66+        return status;
67+    pen_width = (DWORD)scaled_width;
68+    if (pen_width == 0) {
69+        /* ExtCreatePen will fail if passed zero width. We have to choose
70+         * between drawing something too wide, or drawing nothing at all.
71+         * Let's draw something.
72+         */
73+        pen_width = 1;
74+    }
75     pen = ExtCreatePen(pen_style,
76-		       scale * style->line_width,
77+		       pen_width,
78 		       &brush,
79 		       style->num_dashes,
80 		       dash_array);
81     if (pen == NULL)
82 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ExtCreatePen");
83     obj = SelectObject (surface->dc, pen);
84     if (obj == NULL)
85 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectObject");
86