summaryrefslogtreecommitdiff
path: root/gfx/cairo/win32-ExtCreatePen-zero-size.patch
blob: 3970015f7051f973ec763e1414034b3f09d65b35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
From: Robert O'Callahan <robert@ocallahan.org>
Bug 768348. Avoid ExtCreatePen failures by avoiding rounding widths and dash lengths down to zero. r=jrmuizel

diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
@@ -1251,22 +1251,24 @@ static cairo_int_status_t
 {
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
     HPEN pen;
     LOGBRUSH brush;
     COLORREF color;
     XFORM xform;
     DWORD pen_style;
+    DWORD pen_width;
     DWORD *dash_array;
     HGDIOBJ obj;
     unsigned int i;
     cairo_solid_pattern_t clear;
     cairo_matrix_t mat;
     double scale;
+    double scaled_width;
 
     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     if (status)
 	return status;
 
     if (op == CAIRO_OPERATOR_CLEAR) {
 	_cairo_win32_printing_surface_init_clear_color (surface, &clear);
 	source = (cairo_pattern_t*) &clear;
@@ -1288,17 +1290,21 @@ static cairo_int_status_t
     _cairo_matrix_factor_out_scale (&mat, &scale);
 
     pen_style = PS_GEOMETRIC;
     dash_array = NULL;
     if (style->num_dashes) {
 	pen_style |= PS_USERSTYLE;
 	dash_array = calloc (sizeof (DWORD), style->num_dashes);
 	for (i = 0; i < style->num_dashes; i++) {
-	    dash_array[i] = (DWORD) (scale * style->dash[i]);
+	    DWORD dashes = (DWORD) (scale * style->dash[i]);
+	    /* zero dash-lengths cause ExtCreatePen to fail. Make the dashes
+	     * longer if necessary.
+	     */
+	    dash_array[i] = MAX(1, dashes);
 	}
     } else {
 	pen_style |= PS_SOLID;
     }
 
     SetMiterLimit (surface->dc, (FLOAT) (style->miter_limit), NULL);
     if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
@@ -1310,18 +1316,29 @@ static cairo_int_status_t
 	/* Color not used as the pen will only be used by WidenPath() */
 	color = RGB (0,0,0);
     }
     brush.lbStyle = BS_SOLID;
     brush.lbColor = color;
     brush.lbHatch = 0;
     pen_style |= _cairo_win32_line_cap (style->line_cap);
     pen_style |= _cairo_win32_line_join (style->line_join);
+    scaled_width = scale * style->line_width;
+    if (scaled_width == 0.0)
+        return status;
+    pen_width = (DWORD)scaled_width;
+    if (pen_width == 0) {
+        /* ExtCreatePen will fail if passed zero width. We have to choose
+         * between drawing something too wide, or drawing nothing at all.
+         * Let's draw something.
+         */
+        pen_width = 1;
+    }
     pen = ExtCreatePen(pen_style,
-		       scale * style->line_width,
+		       pen_width,
 		       &brush,
 		       style->num_dashes,
 		       dash_array);
     if (pen == NULL)
 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ExtCreatePen");
     obj = SelectObject (surface->dc, pen);
     if (obj == NULL)
 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectObject");