diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index cce7040..909cf61 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -625,6 +625,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_ cairo_image_info_t mime_info; cairo_bool_t use_mime; DWORD mime_type; + cairo_bool_t rotated; /* If we can't use StretchDIBits with this surface, we can't do anything * here. @@ -673,29 +674,53 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_ use_mime = (status == CAIRO_STATUS_SUCCESS); - if (!use_mime && image->format != CAIRO_FORMAT_RGB24) { + m = pattern->base.matrix; + status = cairo_matrix_invert (&m); + /* _cairo_pattern_set_matrix guarantees invertibility */ + assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_multiply (&m, &m, &surface->ctm); + cairo_matrix_multiply (&m, &m, &surface->gdi_ctm); + /* Check if matrix can't be represented as only scaling or mirroring. + * Some printing devices don't support rotation with StretchDIBits. + */ + rotated = fabs (m.xx) < fabs (m.xy) || fabs (m.yy) < fabs (m.yx); + + if (!use_mime && (image->format != CAIRO_FORMAT_RGB24 || rotated)) { cairo_surface_t *opaque_surface; cairo_surface_pattern_t image_pattern; cairo_solid_pattern_t background_pattern; + int width = image->width, height = image->height; + if (rotated) { + width = image->height; + height = image->width; + } opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, - image->width, - image->height); + width, + height); if (opaque_surface->status) { status = opaque_surface->status; goto CLEANUP_OPAQUE_IMAGE; } - _cairo_pattern_init_solid (&background_pattern, - background_color); - status = _cairo_surface_paint (opaque_surface, - CAIRO_OPERATOR_SOURCE, - &background_pattern.base, - NULL); - if (status) - goto CLEANUP_OPAQUE_IMAGE; + if (image->format != CAIRO_FORMAT_RGB24) { + _cairo_pattern_init_solid (&background_pattern, + background_color); + status = _cairo_surface_paint (opaque_surface, + CAIRO_OPERATOR_SOURCE, + &background_pattern.base, + NULL); + if (status) + goto CLEANUP_OPAQUE_IMAGE; + } _cairo_pattern_init_for_surface (&image_pattern, &image->base); + if (rotated) { + /* swap X and Y axes so matrix is just scaling or mirroring */ + cairo_matrix_t swap_xy = { 0, 1, 1, 0, 0, 0 }; + cairo_pattern_set_matrix (&image_pattern.base, &swap_xy); + cairo_matrix_multiply (&m, &swap_xy, &m); + } status = _cairo_surface_paint (opaque_surface, CAIRO_OPERATOR_OVER, &image_pattern.base, @@ -721,13 +746,6 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_ bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; - m = pattern->base.matrix; - status = cairo_matrix_invert (&m); - /* _cairo_pattern_set_matrix guarantees invertibility */ - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&m, &m, &surface->ctm); - cairo_matrix_multiply (&m, &m, &surface->gdi_ctm); SaveDC (surface->win32.dc); _cairo_matrix_to_win32_xform (&m, &xform); @@ -1267,7 +1285,6 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, HPEN pen; LOGBRUSH brush; COLORREF color; - XFORM xform; DWORD pen_style; DWORD *dash_array; HGDIOBJ obj; @@ -1350,13 +1367,6 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, */ SaveDC (surface->win32.dc); - _cairo_matrix_to_win32_xform (&mat, &xform); - xform.eDx = 0.0f; - xform.eDy = 0.0f; - - if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY)) - return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform"); - if (source->type == CAIRO_PATTERN_TYPE_SOLID) { StrokePath (surface->win32.dc); } else { @@ -1365,10 +1375,6 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, if (!SelectClipPath (surface->win32.dc, RGN_AND)) return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectClipPath"); - /* Return to device space to paint the pattern */ - _cairo_matrix_to_win32_xform (&surface->gdi_ctm, &xform); - if (!SetWorldTransform (surface->win32.dc, &xform)) - return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ModifyWorldTransform"); status = _cairo_win32_printing_surface_paint_pattern (surface, source); } RestoreDC (surface->win32.dc, -1);