[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - vcl/inc vcl/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Mon Jul 20 11:07:24 UTC 2020


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

New commits:
commit 582419f5ce2e0e7ca58df035b082c866f76efafa
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Jul 17 17:04:27 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon Jul 20 13:06:52 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/+/98966
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at 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,


More information about the Libreoffice-commits mailing list