зеркало из https://github.com/mozilla/gecko-dev.git
86 строки
3.0 KiB
Diff
86 строки
3.0 KiB
Diff
|
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");
|