From 335ae97f4fdb70d3325a8337d27232ca610228fc Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Wed, 29 Nov 2017 15:32:39 +0000 Subject: Resolves: tdf#114117 draw page shadow mangled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when cairo had to stretch the 1 pixel dimension to fit the area. When its this 1 pixel case set the same settings we use for the stipple effect to get the expected interpolation Change-Id: I42d87d6d01ebdb44083351a9632860f5f0a3bf63 Reviewed-on: https://gerrit.libreoffice.org/45512 Reviewed-by: Michael Meeks Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- vcl/headless/svpgdi.cxx | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'vcl') diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index b9c7ba9a11f5..bcb0e46e8bec 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -282,10 +282,32 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rS cairo_clip(cr); + cairo_pattern_t* maskpattern = cairo_pattern_create_for_surface(mask); cairo_translate(cr, rTR.mnDestX, rTR.mnDestY); - cairo_scale(cr, (double)(rTR.mnDestWidth)/rTR.mnSrcWidth, ((double)rTR.mnDestHeight)/rTR.mnSrcHeight); + double fXScale = (double)(rTR.mnDestWidth)/rTR.mnSrcWidth; + double fYScale = ((double)rTR.mnDestHeight)/rTR.mnSrcHeight; + cairo_scale(cr, fXScale, fYScale); cairo_set_source_surface(cr, source, -rTR.mnSrcX, -rTR.mnSrcY); - cairo_mask_surface(cr, mask, -rTR.mnSrcX, -rTR.mnSrcY); + + //tdf#114117 when stretching a single pixel width/height source to fit an area + //set extend and filter to stretch it with simplest expected interpolation + if ((fXScale != 1.0 && rTR.mnSrcWidth == 1) || (fYScale != 1.0 && rTR.mnSrcHeight == 1)) + { + cairo_pattern_t* sourcepattern = cairo_get_source(cr); + cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_NEAREST); + cairo_pattern_set_extend(maskpattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_filter(maskpattern, CAIRO_FILTER_NEAREST); + } + + //this block is just "cairo_mask_surface", but we have to make it explicit + //because of the cairo_pattern_set_filter etc we may want applied + cairo_matrix_t matrix; + cairo_matrix_init_translate(&matrix, rTR.mnSrcX, rTR.mnSrcY); + cairo_pattern_set_matrix(maskpattern, &matrix); + cairo_mask(cr, maskpattern); + + cairo_pattern_destroy(maskpattern); releaseCairoContext(cr, false, extents); @@ -993,12 +1015,22 @@ static basegfx::B2DRange renderSource(cairo_t* cr, const SalTwoRect& rTR, cairo_clip(cr); cairo_translate(cr, rTR.mnDestX, rTR.mnDestY); + double fXScale = 1.0f; + double fYScale = 1.0f; if (rTR.mnSrcWidth != 0 && rTR.mnSrcHeight != 0) { - cairo_scale(cr, (double)(rTR.mnDestWidth)/rTR.mnSrcWidth, ((double)rTR.mnDestHeight)/rTR.mnSrcHeight); + fXScale = (double)(rTR.mnDestWidth)/rTR.mnSrcWidth; + fYScale = ((double)rTR.mnDestHeight)/rTR.mnSrcHeight; + cairo_scale(cr, fXScale, fYScale); } cairo_save(cr); cairo_set_source_surface(cr, source, -rTR.mnSrcX, -rTR.mnSrcY); + if ((fXScale != 1.0 && rTR.mnSrcWidth == 1) || (fYScale != 1.0 && rTR.mnSrcHeight == 1)) + { + cairo_pattern_t* sourcepattern = cairo_get_source(cr); + cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_NEAREST); + } cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); @@ -1135,8 +1167,16 @@ void SvpSalGraphics::drawMask( const SalTwoRect& rTR, cairo_clip(cr); cairo_translate(cr, rTR.mnDestX, rTR.mnDestY); - cairo_scale(cr, (double)(rTR.mnDestWidth)/rTR.mnSrcWidth, ((double)rTR.mnDestHeight)/rTR.mnSrcHeight); + double fXScale = (double)(rTR.mnDestWidth)/rTR.mnSrcWidth; + double fYScale = ((double)rTR.mnDestHeight)/rTR.mnSrcHeight; + cairo_scale(cr, fXScale, fYScale); cairo_set_source_surface(cr, aSurface.getSurface(), -rTR.mnSrcX, -rTR.mnSrcY); + if ((fXScale != 1.0 && rTR.mnSrcWidth == 1) || (fYScale != 1.0 && rTR.mnSrcHeight == 1)) + { + cairo_pattern_t* sourcepattern = cairo_get_source(cr); + cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_NEAREST); + } cairo_paint(cr); releaseCairoContext(cr, false, extents); -- cgit v1.2.3