summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/win32-ExtCreatePen-zero-size.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/win32-ExtCreatePen-zero-size.patch')
-rw-r--r--gfx/cairo/win32-ExtCreatePen-zero-size.patch85
1 files changed, 85 insertions, 0 deletions
diff --git a/gfx/cairo/win32-ExtCreatePen-zero-size.patch b/gfx/cairo/win32-ExtCreatePen-zero-size.patch
new file mode 100644
index 0000000000..3970015f70
--- /dev/null
+++ b/gfx/cairo/win32-ExtCreatePen-zero-size.patch
@@ -0,0 +1,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");