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

Jan Holesovsky kendy at collabora.com
Tue Nov 26 02:06:04 PST 2013


 vcl/source/filter/wmf/enhwmf.cxx |   14 +--
 vcl/source/filter/wmf/winmtf.cxx |  146 ++++++++++++++++++++++++++-------------
 vcl/source/filter/wmf/winmtf.hxx |   20 ++++-
 vcl/source/filter/wmf/winwmf.cxx |    1 
 4 files changed, 123 insertions(+), 58 deletions(-)

New commits:
commit a39079ec9c3a017c912e45126ae980ff56127099
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Mon Nov 25 16:21:12 2013 +0100

    fdo#61272: Do the mapping correctly both for WMF and EMF.
    
    Turns out that for the WMF, we already had everything set up correctly, we
    were just overwriting the right settings with default data again :-) - fix
    that.
    
    Includes the following commits:
    
    * Revert "wmf-mm-text-1.diff: Fix WMF rendering, n#417818"
    * Revert "wmf-mm-text.diff: Fix WMF rendering, n#417818"
    * fdo#56886 EMF: Fixes some scaling problems of clipped regions, Twips
    
    Change-Id: I14b0c12b10f58eb7031f9da712dee76344c75159
    Reviewed-on: https://gerrit.libreoffice.org/6802
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
index f8b9884..541d68d 100644
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ b/vcl/source/filter/wmf/enhwmf.cxx
@@ -485,8 +485,8 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
                     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 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
             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 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
                 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 @@ sal_Bool EnhWMFReader::ReadHeader()
         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 @@ sal_Bool EnhWMFReader::ReadHeader()
     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/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index 63b0996..fc972e8 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -352,6 +352,20 @@ Color WinMtf::ReadColor()
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 
+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())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Left(),(rPt.Y())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Top());
+        }
+}
+
+//-----------------------------------------------------------------------------------
+
 Point WinMtfOutput::ImplMap( const Point& rPt )
 {
     if ( mnWinExtX && mnWinExtY )
@@ -366,35 +380,32 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
         {
             switch( mnMapMode )
             {
-                case MM_TEXT:
+                case MM_LOENGLISH :
+                {
                     fX2 -= mnWinOrgX;
-                    fY2 -= mnWinOrgY;
-                    if( mnDevWidth != 1 || mnDevHeight != 1 ) {
-                        fX2 *= 2540.0/mnUnitsPerInch;
-                        fY2 *= 2540.0/mnUnitsPerInch;
-                    }
+                    fY2  = mnWinOrgY-fY2;
+                    fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
+                    fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
                     fX2 += mnDevOrgX;
                     fY2 += mnDevOrgY;
-                    fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
-                    fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
-
-                    break;
-                case MM_LOENGLISH :
+                }
+                break;
+                case MM_HIENGLISH :
                 {
                     fX2 -= mnWinOrgX;
                     fY2  = mnWinOrgY-fY2;
-                    fX2 *= 25.40;
-                    fY2 *= 25.40;
+                    fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
+                    fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
                     fX2 += mnDevOrgX;
                     fY2 += mnDevOrgY;
                 }
                 break;
-                case MM_HIENGLISH :
+                case MM_TWIPS:
                 {
                     fX2 -= mnWinOrgX;
                     fY2  = mnWinOrgY-fY2;
-                    fX2 *= 2.540;
-                    fY2 *= 2.540;
+                    fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+                    fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
                     fX2 += mnDevOrgX;
                     fY2 += mnDevOrgY;
                 }
@@ -409,7 +420,7 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
                     fY2 += mnDevOrgY;
                 }
                 break;
-                case MM_HIMETRIC :
+                case MM_HIMETRIC : //in hundredth of a millimeter
                 {
                     fX2 -= mnWinOrgX;
                     fY2  = mnWinOrgY-fY2;
@@ -454,25 +465,16 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
         {
             switch( mnMapMode )
             {
-                case MM_TEXT:
-                if( mnDevWidth != 1 && mnDevHeight != 1 ) {
-                    fWidth *= 2540.0/mnUnitsPerInch;
-                    fHeight*= 2540.0/mnUnitsPerInch;
-                } else {
-                    fWidth *= (double)mnMillX * 100 / (double)mnPixX;
-                    fHeight *= (double)mnMillY * 100 / (double)mnPixY;
-                }
-                break;
                 case MM_LOENGLISH :
                 {
-                    fWidth *= 25.40;
-                    fHeight*=-25.40;
+                    fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
+                    fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
                 }
                 break;
                 case MM_HIENGLISH :
                 {
-                    fWidth *= 2.540;
-                    fHeight*=-2.540;
+                    fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
+                    fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
                 }
                 break;
                 case MM_LOMETRIC :
@@ -481,11 +483,17 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
                     fHeight*=-10;
                 }
                 break;
-                case MM_HIMETRIC :
+                case MM_HIMETRIC : //in hundredth of millimeters
                 {
                     fHeight *= -1;
                 }
                 break;
+                case MM_TWIPS:
+                {
+                    fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+                    fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+                }
+                break;
                 default :
                 {
                     fWidth /= mnWinExtX;
@@ -543,6 +551,27 @@ Polygon& WinMtfOutput::ImplMap( Polygon& 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;
+}
+
+//-----------------------------------------------------------------------------------
+
 PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
 {
     sal_uInt16 nPolys = rPolyPolygon.Count();
@@ -838,6 +867,10 @@ void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
 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 ) );
 }
 
@@ -861,7 +894,10 @@ void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClip
 {
     mbClipNeedsUpdate=true;
     if ( bIsMapped )
-        aClipPath.setClipPath( rPolyPolygon, nClippingMode );
+    {
+        PolyPolygon aPP( rPolyPolygon );
+        aClipPath.setClipPath( ImplScale( aPP ), nClippingMode );
+    }
     else
     {
         PolyPolygon aPP( rPolyPolygon );
@@ -891,7 +927,6 @@ WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
     mbComplexClip       ( false ),
     mnGfxMode           ( GM_COMPATIBLE ),
     mnMapMode           ( MM_TEXT ),
-    mnUnitsPerInch ( 96 ),
     mnDevOrgX           ( 0 ),
     mnDevOrgY           ( 0 ),
     mnDevWidth          ( 1 ),
@@ -906,6 +941,8 @@ WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
     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 +1153,6 @@ void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
 void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
 {
     UpdateClipRegion();
-
     Point aDest( ImplMap( rPoint ) );
     if ( bRecordPath )
         aPathObj.AddPoint( aDest );
@@ -1896,7 +1932,7 @@ void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetDevExt( const Size& rSize )
+void WinMtfOutput::SetDevExt( const Size& rSize ,sal_Bool regular)
 {
     if ( rSize.Width() && rSize.Height() )
     {
@@ -1909,6 +1945,10 @@ void WinMtfOutput::SetDevExt( const Size& rSize )
                 mnDevHeight = rSize.Height();
             }
         }
+        if (regular)
+        {
+            mbIsMapDevSet=sal_True;
+        }
     }
 }
 
@@ -1922,10 +1962,15 @@ void WinMtfOutput::ScaleDevExt( double fX, double fY )
 
 //-----------------------------------------------------------------------------------
 
-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 +1983,21 @@ void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetWinExt( const Size& rSize )
+void WinMtfOutput::SetDevByWin() //mnWinExt...-stuff has to be assigned before.
 {
+    if (!mbIsMapDevSet)
+    {
+        if ((mnMapMode == MM_ISOTROPIC) ) //TODO: WHAT ABOUT ANISOTROPIC???
+        {
+            SetDevExt(Size((mnWinExtX+mnWinOrgX)>>MS_FIXPOINT_BITCOUNT_28_4,-((mnWinExtY-mnWinOrgY)>>MS_FIXPOINT_BITCOUNT_28_4)),sal_False);
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------------
 
+void WinMtfOutput::SetWinExt( const Size& rSize, sal_Bool bIsEMF )
+{
     if( rSize.Width() && rSize.Height() )
     {
         switch( mnMapMode )
@@ -1950,6 +2007,11 @@ void WinMtfOutput::SetWinExt( const Size& rSize )
             {
                 mnWinExtX = rSize.Width();
                 mnWinExtY = rSize.Height();
+                if (bIsEMF)
+                {
+                    SetDevByWin();
+                }
+                mbIsMapWinSet=sal_True;
             }
         }
     }
@@ -1998,7 +2060,7 @@ void WinMtfOutput::SetRefMill( const Size& rSize )
 void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
 {
     mnMapMode = nMapMode;
-    if ( nMapMode == MM_TEXT )
+    if ( nMapMode == MM_TEXT && !mbIsMapWinSet )
     {
         mnWinExtX = mnDevWidth;
         mnWinExtY = mnDevHeight;
@@ -2012,14 +2074,6 @@ void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
 
 //-----------------------------------------------------------------------------------
 
-void WinMtfOutput::SetUnitsPerInch( sal_uInt16 nUnitsPerInch )
-{
-    if( nUnitsPerInch != 0 )
-    mnUnitsPerInch = nUnitsPerInch;
-}
-
-//-----------------------------------------------------------------------------------
-
 void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
 {
     maXForm.eM11 = rXForm.eM11;
diff --git a/vcl/source/filter/wmf/winmtf.hxx b/vcl/source/filter/wmf/winmtf.hxx
index bc368e6e..dd80833 100644
--- a/vcl/source/filter/wmf/winmtf.hxx
+++ b/vcl/source/filter/wmf/winmtf.hxx
@@ -278,6 +278,13 @@ struct WMF_EXTERNALHEADER;
 
 #define PRIVATE_ESCAPE_UNICODE  2
 
+//Scalar constants
+
+#define UNDOCUMENTED_WIN_RCL_RELATION 32
+#define MS_FIXPOINT_BITCOUNT_28_4 4
+#define HUNDREDTH_MILLIMETERS_PER_MILLIINCH 2.54
+#define MILLIINCH_PER_TWIPS   1.44
+
 //============================ WMFReader ==================================
 
 #ifdef WIN_MTF_ASSERT
@@ -617,13 +624,14 @@ class WinMtfOutput
 
     sal_uInt32          mnGfxMode;
     sal_uInt32          mnMapMode;
-    sal_uInt16          mnUnitsPerInch;
 
     XForm               maXForm;
     sal_Int32           mnDevOrgX, mnDevOrgY;
     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 +644,14 @@ class WinMtfOutput
     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 +659,15 @@ class WinMtfOutput
 
 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 );
diff --git a/vcl/source/filter/wmf/winwmf.cxx b/vcl/source/filter/wmf/winwmf.cxx
index 0d6276a..0178e3d 100644
--- a/vcl/source/filter/wmf/winwmf.cxx
+++ b/vcl/source/filter/wmf/winwmf.cxx
@@ -1096,7 +1096,6 @@ sal_Bool WMFReader::ReadHeader()
         }
     }
 
-    pOut->SetUnitsPerInch( nUnitsPerInch );
     pOut->SetWinOrg( aPlaceableBound.TopLeft() );
     Size aWMFSize( labs( aPlaceableBound.GetWidth() ), labs( aPlaceableBound.GetHeight() ) );
     pOut->SetWinExt( aWMFSize );


More information about the Libreoffice-commits mailing list