gfx/cairo/win32-ExtCreatePen-zero-size.patch

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/win32-ExtCreatePen-zero-size.patch	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,85 @@
     1.4 +From: Robert O'Callahan <robert@ocallahan.org>
     1.5 +Bug 768348. Avoid ExtCreatePen failures by avoiding rounding widths and dash lengths down to zero. r=jrmuizel
     1.6 +
     1.7 +diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
     1.8 +--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
     1.9 ++++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
    1.10 +@@ -1251,22 +1251,24 @@ static cairo_int_status_t
    1.11 + {
    1.12 +     cairo_win32_surface_t *surface = abstract_surface;
    1.13 +     cairo_int_status_t status;
    1.14 +     HPEN pen;
    1.15 +     LOGBRUSH brush;
    1.16 +     COLORREF color;
    1.17 +     XFORM xform;
    1.18 +     DWORD pen_style;
    1.19 ++    DWORD pen_width;
    1.20 +     DWORD *dash_array;
    1.21 +     HGDIOBJ obj;
    1.22 +     unsigned int i;
    1.23 +     cairo_solid_pattern_t clear;
    1.24 +     cairo_matrix_t mat;
    1.25 +     double scale;
    1.26 ++    double scaled_width;
    1.27 + 
    1.28 +     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
    1.29 +     if (status)
    1.30 + 	return status;
    1.31 + 
    1.32 +     if (op == CAIRO_OPERATOR_CLEAR) {
    1.33 + 	_cairo_win32_printing_surface_init_clear_color (surface, &clear);
    1.34 + 	source = (cairo_pattern_t*) &clear;
    1.35 +@@ -1288,17 +1290,21 @@ static cairo_int_status_t
    1.36 +     _cairo_matrix_factor_out_scale (&mat, &scale);
    1.37 + 
    1.38 +     pen_style = PS_GEOMETRIC;
    1.39 +     dash_array = NULL;
    1.40 +     if (style->num_dashes) {
    1.41 + 	pen_style |= PS_USERSTYLE;
    1.42 + 	dash_array = calloc (sizeof (DWORD), style->num_dashes);
    1.43 + 	for (i = 0; i < style->num_dashes; i++) {
    1.44 +-	    dash_array[i] = (DWORD) (scale * style->dash[i]);
    1.45 ++	    DWORD dashes = (DWORD) (scale * style->dash[i]);
    1.46 ++	    /* zero dash-lengths cause ExtCreatePen to fail. Make the dashes
    1.47 ++	     * longer if necessary.
    1.48 ++	     */
    1.49 ++	    dash_array[i] = MAX(1, dashes);
    1.50 + 	}
    1.51 +     } else {
    1.52 + 	pen_style |= PS_SOLID;
    1.53 +     }
    1.54 + 
    1.55 +     SetMiterLimit (surface->dc, (FLOAT) (style->miter_limit), NULL);
    1.56 +     if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
    1.57 + 	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
    1.58 +@@ -1310,18 +1316,29 @@ static cairo_int_status_t
    1.59 + 	/* Color not used as the pen will only be used by WidenPath() */
    1.60 + 	color = RGB (0,0,0);
    1.61 +     }
    1.62 +     brush.lbStyle = BS_SOLID;
    1.63 +     brush.lbColor = color;
    1.64 +     brush.lbHatch = 0;
    1.65 +     pen_style |= _cairo_win32_line_cap (style->line_cap);
    1.66 +     pen_style |= _cairo_win32_line_join (style->line_join);
    1.67 ++    scaled_width = scale * style->line_width;
    1.68 ++    if (scaled_width == 0.0)
    1.69 ++        return status;
    1.70 ++    pen_width = (DWORD)scaled_width;
    1.71 ++    if (pen_width == 0) {
    1.72 ++        /* ExtCreatePen will fail if passed zero width. We have to choose
    1.73 ++         * between drawing something too wide, or drawing nothing at all.
    1.74 ++         * Let's draw something.
    1.75 ++         */
    1.76 ++        pen_width = 1;
    1.77 ++    }
    1.78 +     pen = ExtCreatePen(pen_style,
    1.79 +-		       scale * style->line_width,
    1.80 ++		       pen_width,
    1.81 + 		       &brush,
    1.82 + 		       style->num_dashes,
    1.83 + 		       dash_array);
    1.84 +     if (pen == NULL)
    1.85 + 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ExtCreatePen");
    1.86 +     obj = SelectObject (surface->dc, pen);
    1.87 +     if (obj == NULL)
    1.88 + 	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectObject");

mercurial