summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-11-29 15:32:39 +0000
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2017-12-18 01:07:50 -0500
commit8945637c4b513884da0f70b9773aca95dd7c95f5 (patch)
tree3806051214c8678bcc6cec3ed8ca078c3ac1a18c /vcl
parent4e58b2b3af6c13464acef59de064b109519c889d (diff)
Resolves: tdf#114117 draw page shadow mangled
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/45511 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit ba4a124b0c0c66fd275f5147d55eeec27ce78da9) (cherry picked from commit fc50d99be7e802089447d162412a9698d52c8f34)
Diffstat (limited to 'vcl')
-rw-r--r--vcl/headless/svpgdi.cxx48
1 files changed, 44 insertions, 4 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 910cefbe4d69..8f09939df899 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -281,10 +281,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);
@@ -992,12 +1014,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);
@@ -1134,8 +1166,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);