Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/1886

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/86/1886/1

fdo#56886 EMF: Fixes some scaling problems of clipped regions, Twips

If a Metafile's scaling is incompletely defined, there are some arbitrary values used.
Why was this bug not there in aoo 3.3? Maybe because they didn't use the EMF Part of that WMF?
This Patch also adds an (untested) TWIPS scaling, which was missing

Change-Id: I7c0139853961eb338476a9e3a5e08d3f87225f2e
Signed-off-by: Lennard Wasserthal <Wasserthal@nefkom.net>
---
M svtools/source/filter/wmf/enhwmf.cxx
M svtools/source/filter/wmf/winmtf.cxx
M svtools/source/filter/wmf/winmtf.hxx
3 files changed, 107 insertions(+), 15 deletions(-)



diff --git a/svtools/source/filter/wmf/enhwmf.cxx b/svtools/source/filter/wmf/enhwmf.cxx
index f8b9884..541d68d 100644
--- a/svtools/source/filter/wmf/enhwmf.cxx
+++ b/svtools/source/filter/wmf/enhwmf.cxx
@@ -485,8 +485,8 @@
                     EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n",(unsigned int) id));
                 }
             }
-        } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
-
+        }
+        else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
         switch( nRecType )
         {
             case EMR_POLYBEZIERTO :
@@ -518,14 +518,14 @@
             case EMR_SETWINDOWEXTEX :
             {                                                       // #75383#
                 *pWMF >> nW >> nH;
-                pOut->SetWinExt( Size( nW, nH ) );
+                pOut->SetWinExt( Size( nW, nH ), true);
             }
             break;
 
             case EMR_SETWINDOWORGEX :
             {
                 *pWMF >> nX32 >> nY32;
-                pOut->SetWinOrg( Point( nX32, nY32 ) );
+                pOut->SetWinOrg( Point( nX32, nY32 ), true);
             }
             break;
 
@@ -917,7 +917,7 @@
                 PolyPolygon aPolyPoly;
                 if ( cbRgnData )
                     ImplReadRegion( aPolyPoly, *pWMF, nRecSize );
-                pOut->SetClipPath( aPolyPoly, iMode, sal_False );
+                pOut->SetClipPath( aPolyPoly, iMode, sal_True );
             }
             break;
 
@@ -1352,7 +1352,7 @@
         return sal_False;
 
     // bound size
-    Rectangle rclBounds;    // rectangle in logical units 1/100th mm
+    Rectangle rclBounds;    // rectangle in logical units
     *pWMF >> nLeft >> nTop >> nRight >> nBottom;
     rclBounds.Left() = nLeft;
     rclBounds.Top() = nTop;
@@ -1360,7 +1360,7 @@
     rclBounds.Bottom() = nBottom;
 
     // picture frame size
-    Rectangle rclFrame;     // rectangle in device units
+    Rectangle rclFrame;     // rectangle in device units 1/100th mm
     *pWMF >> nLeft >> nTop >> nRight >> nBottom;
     rclFrame.Left() = nLeft;
     rclFrame.Top() = nTop;
diff --git a/svtools/source/filter/wmf/winmtf.cxx b/svtools/source/filter/wmf/winmtf.cxx
index 63b0996..59b1636 100644
--- a/svtools/source/filter/wmf/winmtf.cxx
+++ b/svtools/source/filter/wmf/winmtf.cxx
@@ -352,6 +352,20 @@
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 
+Point WinMtfOutput::ImplScale( const Point& rPt)//Hack to set varying defaults for incompletely 
defined files.
+{
+        if (mbIsMapDevSet && mbIsMapWinSet)
+        {
+            return 
Point((rPt.X())*mnWinExtX/mnDevWidth-mrclFrame.Left(),(rPt.Y())*mnWinExtY/mnDevHeight-mrclFrame.Top());
+        }
+        else
+        {
+            return Point((rPt.X())*32-mrclFrame.Left(),(rPt.Y())*32-mrclFrame.Top());
+        }
+}
+
+//-----------------------------------------------------------------------------------
+
 Point WinMtfOutput::ImplMap( const Point& rPt )
 {
     if ( mnWinExtX && mnWinExtY )
@@ -395,6 +409,16 @@
                     fY2  = mnWinOrgY-fY2;
                     fX2 *= 2.540;
                     fY2 *= 2.540;
+                    fX2 += mnDevOrgX;
+                    fY2 += mnDevOrgY;
+                }
+                break;
+                case MM_TWIPS:
+                {
+                    fX2 -= mnWinOrgX;
+                    fY2  = mnWinOrgY-fY2;
+                    fX2 *= 1.7639;
+                    fY2 *= 1.7639;
                     fX2 += mnDevOrgX;
                     fY2 += mnDevOrgY;
                 }
@@ -486,6 +510,12 @@
                     fHeight *= -1;
                 }
                 break;
+                case MM_TWIPS:
+                {
+                    fWidth *= 1.7639;
+                    fHeight*=-1.7639;
+                }
+                break;
                 default :
                 {
                     fWidth /= mnWinExtX;
@@ -539,6 +569,27 @@
         rPolygon[ i ] = ImplMap( rPolygon[ i ] );
     }
     return rPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+Polygon& WinMtfOutput::ImplScale( Polygon& rPolygon )
+{
+    sal_uInt16 nPoints = rPolygon.GetSize();
+    for ( sal_uInt16 i = 0; i < nPoints; i++ )
+    {
+        rPolygon[ i ] = ImplScale( rPolygon[ i ] );
+    }
+    return rPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+PolyPolygon& WinMtfOutput::ImplScale( PolyPolygon& rPolyPolygon )
+{
+    sal_uInt16 nPolys = rPolyPolygon.Count();
+    for ( sal_uInt16 i = 0; i < nPolys; ImplScale( rPolyPolygon[ i++ ] ) ) ;
+    return rPolyPolygon;
 }
 
 //-----------------------------------------------------------------------------------
@@ -838,6 +889,10 @@
 void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
 {
     mbClipNeedsUpdate=true;
+    if ((rRect.Left()-rRect.Right()==0) && (rRect.Top()-rRect.Bottom()==0))
+    {
+        return; // empty rectangles cause trouble
+    }
     aClipPath.intersectClipRect( ImplMap( rRect ) );
 }
 
@@ -859,9 +914,13 @@
 
 void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool 
bIsMapped )
 {
+    PolyPolygon xPolyPolygon(rPolyPolygon);
     mbClipNeedsUpdate=true;
     if ( bIsMapped )
-        aClipPath.setClipPath( rPolyPolygon, nClippingMode );
+    {
+        PolyPolygon aPP( rPolyPolygon );
+        aClipPath.setClipPath( ImplScale( aPP ), nClippingMode );
+    }
     else
     {
         PolyPolygon aPP( rPolyPolygon );
@@ -906,6 +965,8 @@
     mnMillY             ( 1 ),
     mpGDIMetaFile       ( &rGDIMetaFile )
 {
+    mbIsMapWinSet = sal_False;
+    mbIsMapDevSet = sal_False;
     mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );      // The original 
clipregion has to be on top
                                                                             // of the stack so it 
can always be restored
                                                                             // this is necessary 
to be able to support
@@ -1116,7 +1177,6 @@
 void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
 {
     UpdateClipRegion();
-
     Point aDest( ImplMap( rPoint ) );
     if ( bRecordPath )
         aPathObj.AddPoint( aDest );
@@ -1896,7 +1956,7 @@
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetDevExt( const Size& rSize )
+void WinMtfOutput::SetDevExt( const Size& rSize ,sal_Bool regular)
 {
     if ( rSize.Width() && rSize.Height() )
     {
@@ -1908,6 +1968,10 @@
                 mnDevWidth = rSize.Width();
                 mnDevHeight = rSize.Height();
             }
+        }
+        if (regular)
+        {
+            mbIsMapDevSet=sal_True;
         }
     }
 }
@@ -1922,10 +1986,15 @@
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetWinOrg( const Point& rPoint )
+void WinMtfOutput::SetWinOrg( const Point& rPoint , sal_Bool bIsEMF)
 {
     mnWinOrgX = rPoint.X();
     mnWinOrgY = rPoint.Y();
+    if (bIsEMF)
+    {
+        SetDevByWin();
+    }
+    mbIsMapWinSet=sal_True;
 }
 
 //-----------------------------------------------------------------------------------
@@ -1938,9 +2007,21 @@
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetWinExt( const Size& rSize )
+void WinMtfOutput::SetDevByWin() //mnWinExt...-stuff has to be assigned before.
 {
+    if (!mbIsMapDevSet)
+    {
+        if ((mnMapMode == MM_ISOTROPIC) ) //TODO: HOW ABOUT ANISOTROPIC???
+        {
+            SetDevExt(Size((mnWinExtX+mnWinOrgX)>>4,-((mnWinExtY-mnWinOrgY)>>4)),sal_False);
+        }
+    }
+}
 
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetWinExt( const Size& rSize, sal_Bool bIsEMF )
+{
     if( rSize.Width() && rSize.Height() )
     {
         switch( mnMapMode )
@@ -1950,6 +2031,11 @@
             {
                 mnWinExtX = rSize.Width();
                 mnWinExtY = rSize.Height();
+                if (bIsEMF)
+                {
+                    SetDevByWin();
+                }
+                mbIsMapWinSet=sal_True;
             }
         }
     }
diff --git a/svtools/source/filter/wmf/winmtf.hxx b/svtools/source/filter/wmf/winmtf.hxx
index bc368e6..c5dad43 100644
--- a/svtools/source/filter/wmf/winmtf.hxx
+++ b/svtools/source/filter/wmf/winmtf.hxx
@@ -624,6 +624,8 @@
     sal_Int32           mnDevWidth, mnDevHeight;
     sal_Int32           mnWinOrgX, mnWinOrgY;       // aktuelles Window-Origin
     sal_Int32           mnWinExtX, mnWinExtY;       // aktuelles Window-Extent
+    sal_Bool            mbIsMapWinSet;
+    sal_Bool            mbIsMapDevSet;
 
     sal_Int32           mnPixX, mnPixY;             // Reference Device in pixel
     sal_Int32           mnMillX, mnMillY;           // Reference Device in Mill
@@ -636,11 +638,14 @@
     void                UpdateFillStyle();
 
     Point               ImplMap( const Point& rPt );
+    Point               ImplScale( const Point& rPt );
     Size                ImplMap( const Size& rSz );
     Rectangle           ImplMap( const Rectangle& rRectangle );
     void                ImplMap( Font& rFont );
     Polygon&            ImplMap( Polygon& rPolygon );
     PolyPolygon&        ImplMap( PolyPolygon& rPolyPolygon );
+    Polygon&            ImplScale( Polygon& rPolygon );
+    PolyPolygon&        ImplScale( PolyPolygon& rPolyPolygon );
     void                ImplResizeObjectArry( sal_uInt32 nNewEntry );
     void                ImplSetNonPersistentLineColorTransparenz();
     void                ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly );
@@ -648,14 +653,15 @@
 
 public:
 
+    void                SetDevByWin(); //Hack to set varying defaults for incompletely defined 
files.
     void                SetDevOrg( const Point& rPoint );
     void                SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd );
-    void                SetDevExt( const Size& rSize );
+    void                SetDevExt( const Size& rSize ,sal_Bool regular = true);
     void                ScaleDevExt( double fX, double fY );
 
-    void                SetWinOrg( const Point& rPoint );
+    void                SetWinOrg( const Point& rPoint , sal_Bool bIsEMF = false);
     void                SetWinOrgOffset( sal_Int32 nX, sal_Int32 nY );
-    void                SetWinExt( const Size& rSize );
+    void                SetWinExt( const Size& rSize , sal_Bool bIsEMF = false);
     void                ScaleWinExt( double fX, double fY );
 
     void                SetrclBounds( const Rectangle& rRect );

-- 
To view, visit https://gerrit.libreoffice.org/1886
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7c0139853961eb338476a9e3a5e08d3f87225f2e
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Lennard Wasserthal <Wasserthal@nefkom.net>

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.