vcl/inc/salgdi.hxx              |    2 
 vcl/source/gdi/salgdilayout.cxx |  158 ++++++++++++----------------------------
 2 files changed, 49 insertions(+), 111 deletions(-)

New commits:
commit 6a54960f6b38a7d549ed33419cf55f4e718cf7b9
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Jul 17 17:04:27 2020 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Jul 20 11:38:40 2020 +0200

    tdf#134085 DrawTransformedBitmap in wrong place for RTL
    
    The return of mirror wasn't used, so no effort at a rtl mirror
    was made anyway.
    
    Looking at the similar case of polygons, the highlight polygons
    in the recently used view are also missing, they have also been
    misplaced
    
    we don't want to mirror polygons, we want to translate them
    to appear at their mirrored bounding box.
    
    Change-Id: Iefd853883bb6b99a352ce6969ceef7bd57046bc2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98982
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 76f367544203..6e772d24cf24 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -205,10 +205,8 @@ public:
     void                        mirror( tools::Rectangle& rRect, const 
OutputDevice*, bool bBack = false ) const;
     void                        mirror( vcl::Region& rRgn, const OutputDevice 
*pOutDev ) const;
     void                        mirror( ImplControlValue&, const OutputDevice* 
) const;
-    basegfx::B2DPoint           mirror( const basegfx::B2DPoint& i_rPoint, 
const OutputDevice *pOutDev ) const;
     basegfx::B2DPolyPolygon     mirror( const basegfx::B2DPolyPolygon& 
i_rPoly, const OutputDevice *pOutDev ) const;
     const basegfx::B2DHomMatrix& getMirror( const OutputDevice *pOutDev ) 
const;
-    basegfx::B2DHomMatrix       mirror( const basegfx::B2DHomMatrix& 
i_rMatrix, const OutputDevice *pOutDev ) const;
 
     // non virtual methods; these do possible coordinate mirroring and
     // then delegate to protected virtual methods
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 0a50329f62f0..f477127874f8 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -290,20 +290,6 @@ void SalGraphics::mirror( tools::Rectangle& rRect, const 
OutputDevice *pOutDev,
     rRect.Move( x - x_org, 0 );
 }
 
-basegfx::B2DPoint SalGraphics::mirror( const basegfx::B2DPoint& i_rPoint, 
const OutputDevice* i_pOutDev ) const
-{
-    const basegfx::B2DHomMatrix& rMirror(getMirror(i_pOutDev));
-
-    if(rMirror.isIdentity())
-    {
-        return i_rPoint;
-    }
-    else
-    {
-        return rMirror * i_rPoint;
-    }
-}
-
 basegfx::B2DPolyPolygon SalGraphics::mirror( const basegfx::B2DPolyPolygon& 
i_rPoly, const OutputDevice* i_pOutDev ) const
 {
     const basegfx::B2DHomMatrix& rMirror(getMirror(i_pOutDev));
@@ -351,12 +337,12 @@ const basegfx::B2DHomMatrix& SalGraphics::getMirror( 
const OutputDevice* i_pOutD
                 // Original code was:
                 //      aRet.setX( w-1-i_rPoint.getX() );
                 // -mirror X -> scale(-1.0, 1.0)
-                // -translate X -> translate(w-1, 0); but already mirrored, so 
use translate(1-w, 0)
+                // -translate X -> translate(w-1, 0)
                 // Checked this one, works as expected.
                 const_cast<SalGraphics*>(this)->m_aLastMirror = 
basegfx::utils::createScaleTranslateB2DHomMatrix(
                     -1.0,
                     1.0,
-                    1-w,
+                    w-1,
                     0.0);
             }
         }
@@ -369,16 +355,6 @@ const basegfx::B2DHomMatrix& SalGraphics::getMirror( const 
OutputDevice* i_pOutD
     return m_aLastMirror;
 }
 
-basegfx::B2DHomMatrix SalGraphics::mirror( const basegfx::B2DHomMatrix& 
i_rMatrix, const OutputDevice *pOutDev ) const
-{
-    // add mirroring transformation to i_rMatrix
-    const basegfx::B2DHomMatrix& rMirror(getMirror(pOutDev));
-
-    // Apply mirror to given matrix by multiply from left ('after' i_rMatrix).
-    // Identity checks and fast-paths are in the operator
-    return rMirror * i_rMatrix;
-}
-
 bool SalGraphics::SetClipRegion( const vcl::Region& i_rClip, const 
OutputDevice *pOutDev )
 {
     if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && 
pOutDev->IsRTLEnabled()) )
@@ -468,6 +444,16 @@ void SalGraphics::DrawPolyPolygon( sal_uInt32 nPoly, const 
sal_uInt32* pPoints,
         drawPolyPolygon( nPoly, pPoints, pPtAry );
 }
 
+namespace
+{
+    basegfx::B2DHomMatrix createTranslateToMirroredBounds(const 
basegfx::B2DRange &rBoundingBox, const basegfx::B2DHomMatrix& rMirror)
+    {
+        basegfx::B2DRange aRTLBoundingBox(rBoundingBox);
+        aRTLBoundingBox *= rMirror;
+        return 
basegfx::utils::createTranslateB2DHomMatrix(aRTLBoundingBox.getMinX() - 
rBoundingBox.getMinX(), 0);
+    }
+}
+
 bool SalGraphics::DrawPolyPolygon(
     const basegfx::B2DHomMatrix& rObjectToDevice,
     const basegfx::B2DPolyPolygon& i_rPolyPolygon,
@@ -478,33 +464,16 @@ bool SalGraphics::DrawPolyPolygon(
     {
         // mirroring set
         const basegfx::B2DHomMatrix& rMirror(getMirror(i_pOutDev));
-
         if(!rMirror.isIdentity())
         {
-            if(rObjectToDevice.isIdentity())
-            {
-                // There is no ObjectToDevice transformation set. We can just
-                // use rMirror, that would be the result of the linear 
combination
-                return drawPolyPolygon(
-                    rMirror,
-                    i_rPolyPolygon,
-                    i_fTransparency);
-            }
-            else
-            {
-                // Create the linear combination
-                basegfx::B2DHomMatrix aLinearCombination(rObjectToDevice);
-                basegfx::B2DHomMatrix aObjectToDeviceInv(rObjectToDevice);
-
-                aLinearCombination = rMirror * aLinearCombination;
-                aObjectToDeviceInv.invert();
-                aLinearCombination = aObjectToDeviceInv * aLinearCombination;
-
-                return drawPolyPolygon(
-                    aLinearCombination,
-                    i_rPolyPolygon,
-                    i_fTransparency);
-            }
+            basegfx::B2DRange aBoundingBox(i_rPolyPolygon.getB2DRange());
+            aBoundingBox *= rObjectToDevice;
+            auto aTranslateToMirroredBounds = 
createTranslateToMirroredBounds(aBoundingBox, rMirror);
+
+            return drawPolyPolygon(
+                aTranslateToMirroredBounds * rObjectToDevice,
+                i_rPolyPolygon,
+                i_fTransparency);
         }
     }
 
@@ -584,58 +553,22 @@ bool SalGraphics::DrawPolyLine(
     {
         // mirroring set
         const basegfx::B2DHomMatrix& rMirror(getMirror(i_pOutDev));
-
         if(!rMirror.isIdentity())
         {
-            // If we really have a mirroring to apply, we *could*
-            // use the ::mirror call to modify the B2DPolygon (and
-            // prepare the LineWidth scaling), but we also
-            // can add that mirroring to rObjectToDevice transformation
-            // by using linear combination of transformations and stay
-            // on having the transformation
-            if(rObjectToDevice.isIdentity())
-            {
-                // There is no ObjectToDevice transformation set. We can just
-                // use rMirror, that would be the result of the linear 
combination
-                return drawPolyLine(
-                    rMirror,
-                    i_rPolygon,
-                    i_fTransparency,
-                    i_rLineWidth,
-                    i_pStroke, // MM01
-                    i_eLineJoin,
-                    i_eLineCap,
-                    i_fMiterMinimumAngle,
-                    bPixelSnapHairline);
-            }
-            else
-            {
-                // To create the linear combination, we need to
-                // - multiply with rObjectToDevice to get to device-coordinates
-                //   (what is a simple copy)
-                // - apply rMirror (multiply from left)
-                // - multiply with inverse of rObjectToDevice to get back from
-                //   device-coordinates to object-coordinates
-                // this only makes sense to do when we *have* an ObjectToDevice
-                // transformation, so optimize that
-                basegfx::B2DHomMatrix aLinearCombination(rObjectToDevice);
-                basegfx::B2DHomMatrix aObjectToDeviceInv(rObjectToDevice);
-
-                aLinearCombination = rMirror * aLinearCombination;
-                aObjectToDeviceInv.invert();
-                aLinearCombination = aObjectToDeviceInv * aLinearCombination;
-
-                return drawPolyLine(
-                    aLinearCombination,
-                    i_rPolygon,
-                    i_fTransparency,
-                    i_rLineWidth,
-                    i_pStroke, // MM01
-                    i_eLineJoin,
-                    i_eLineCap,
-                    i_fMiterMinimumAngle,
-                    bPixelSnapHairline);
-            }
+            basegfx::B2DRange aBoundingBox(i_rPolygon.getB2DRange());
+            aBoundingBox *= rObjectToDevice;
+            auto aTranslateToMirroredBounds = 
createTranslateToMirroredBounds(aBoundingBox, rMirror);
+
+            return drawPolyLine(
+                aTranslateToMirroredBounds * rObjectToDevice,
+                i_rPolygon,
+                i_fTransparency,
+                i_rLineWidth,
+                i_pStroke, // MM01
+                i_eLineJoin,
+                i_eLineCap,
+                i_fMiterMinimumAngle,
+                bPixelSnapHairline);
         }
     }
 
@@ -925,16 +858,23 @@ bool SalGraphics::DrawTransformedBitmap(
 {
     if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && 
pOutDev->IsRTLEnabled()) )
     {
-        mirror(rNull, pOutDev);
-        mirror(rX, pOutDev);
-        mirror(rY, pOutDev);
+        // mirroring set
+        const basegfx::B2DHomMatrix& rMirror(getMirror(pOutDev));
+        if (!rMirror.isIdentity())
+        {
+            basegfx::B2DPolygon aPoints({rNull, rX, rY});
+            basegfx::B2DRange aBoundingBox(aPoints.getB2DRange());
+            auto aTranslateToMirroredBounds = 
createTranslateToMirroredBounds(aBoundingBox, rMirror);
 
-        return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
pAlphaBitmap);
-    }
-    else
-    {
-        return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
pAlphaBitmap);
+            basegfx::B2DPoint aNull = aTranslateToMirroredBounds * rNull;
+            basegfx::B2DPoint aX = aTranslateToMirroredBounds * rX;
+            basegfx::B2DPoint aY = aTranslateToMirroredBounds * rY;
+
+            return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, 
pAlphaBitmap);
+        }
     }
+
+    return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap);
 }
 
 bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight,
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to