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