[Libreoffice-commits] core.git: vcl/headless

Caolán McNamara caolanm at redhat.com
Wed Nov 29 20:41:37 UTC 2017


 vcl/headless/svpgdi.cxx |   48 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)

New commits:
commit ba4a124b0c0c66fd275f5147d55eeec27ce78da9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Nov 29 15:32:39 2017 +0000

    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 at collabora.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

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);


More information about the Libreoffice-commits mailing list