Based on Caolan's comments, here's another attempt at doing things right.

I'm unable to test right now (some symlink problem)... please don't push
right away :)

Marc-André Laverdière
Software Security Scientist
Innovation Labs, Tata Consultancy Services
Hyderabad, India

On 09/27/2011 06:25 PM, Caolán McNamara wrote:
> On Fri, 2011-09-23 at 16:36 +0530, Marc-André Laverdière wrote:
>> Hello everybody.
>>
>> Here is a patch from the "I have no idea what I'm doing" department.
> 
> 0001 looks good to me anyway, pushed now, sorry for the delay.
> 
> 0002 looks a bit more dubious, broad stroke fine, but isn't it the case
> that....
> 
> +template <class T, class Drawer>
> +void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const sal_Bool
> skipFirst)
> +{
> +    sal_uInt16 nPoints ...
> 
> i.e. new code here has a 16bit value read from disk, while the old code
> appears to be a 32bit value. I know it gets casted to 16bits, but it
> would affect how much gets read from the stream.
> 
> ...
> 
> EnhWMFReader::ReadEnhWMF
> 
> ...  sal_uInt32 nPoints ...
> 
>    case EMR_POLYBEZIER :
> -  {
> -      pWMF->SeekRel( 16 );
> -      *pWMF >> nPoints;
> 
>> P.S. I am not sure how to really test this... I just ran make -sr :)
> 
> yeah, that'll run the basic sanity wmf loader tests anyway. If you grab
> some .wmf's and just open them in draw that's another test-scenario,
> e.g. libwmf might have a selection if we don't have any already.
> 
> C.
> 
> _______________________________________________
> LibreOffice mailing list
> LibreOffice@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/libreoffice
> 
>From 57f80dbbc70ede3c86108fbc1abeb4bf265ea332 Mon Sep 17 00:00:00 2001
From: Marc-Andre Laverdiere <marc-an...@atc.tcs.com>
Date: Tue, 20 Sep 2011 12:25:01 +0530
Subject: [PATCH] Refactoring drawing of polygons and polypolygons in
 enhwmf.cxx

---
 svtools/source/filter/wmf/enhwmf.cxx |  216 +++++++++++++---------------------
 svtools/source/filter/wmf/winmtf.hxx |    9 ++-
 2 files changed, 90 insertions(+), 135 deletions(-)

diff --git a/svtools/source/filter/wmf/enhwmf.cxx 
b/svtools/source/filter/wmf/enhwmf.cxx
index 1c83212..8ea6136 100644
--- a/svtools/source/filter/wmf/enhwmf.cxx
+++ b/svtools/source/filter/wmf/enhwmf.cxx
@@ -31,7 +31,7 @@
 
 #include "winmtf.hxx"
 #include <osl/endian.h>
-#include <vector>
+#include <boost/bind.hpp>
 
 using namespace std;
 //=========================== GDI-Array ===================================
@@ -310,20 +310,43 @@ void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, 
sal_Bool& bHaveDC)
 
 /**
  * Reads polygons from the stream.
+ * The <class T> parameter is for the type of the points (sal_uInt32 or 
sal_uInt16).
+ * The <class Drawer> parameter is a boost binding for the method that will 
draw the polygon.
+ * skipFirst: if the first point read is the 0th point or the 1st point in the 
array.
+ * */
+template <class T, class Drawer>
+void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const sal_Bool skipFirst)
+{
+    sal_uInt32 nPoints(0), nStartIndex(0);
+    pWMF->SeekRel( 16 );
+    *pWMF >> nPoints;
+    if (skipFirst)
+    {
+        nPoints ++;
+        nStartIndex ++;
+    }
+
+    Polygon aPolygon = ReadPolygon<T>(nStartIndex, nPoints);
+    drawer(pOut, aPolygon, skipFirst, bRecordPath);
+}
+
+
+/**
+ * Reads polygons from the stream.
  * The <class T> parameter is for the type of the points
  * nStartIndex: which is the starting index in the polygon of the first point 
read
  * nPoints: number of points
  * pWMF: the stream containings the polygons
  * */
 template <class T>
-Polygon EnhWMFReader::ReadPolygon(sal_uInt16 nStartIndex, sal_uInt16 nPoints)
+Polygon EnhWMFReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints)
 {
     Polygon aPolygon(nPoints);
     for (sal_uInt16 i = nStartIndex ; i < nPoints && pWMF->good(); i++ )
     {
         T nX, nY;
         *pWMF >> nX >> nY;
-        if (pWMF->good())
+        if (!pWMF->good())
             break;
         aPolygon[ i ] = Point( nX, nY );
     }
@@ -331,6 +354,45 @@ Polygon EnhWMFReader::ReadPolygon(sal_uInt16 nStartIndex, 
sal_uInt16 nPoints)
     return aPolygon;
 }
 
+/**
+ * Reads a polyline from the WMF file and draws it
+ * The <class T> parameter refers to the type of the points. (e.g. sal_uInt16 
or sal_uInt32)
+ * */
+template <class T>
+void EnhWMFReader::ReadAndDrawPolyLine()
+{
+    sal_uInt32  nPoints;
+    sal_Int32   i, nPoly(0), nGesPoints(0);
+    pWMF->SeekRel( 0x10 );
+    // Number of Polygons:
+    *pWMF >> nPoly >> nGesPoints;
+
+    // taking the amount of points of each polygon, retrieving the total 
number of points
+    if ( pWMF->good() &&
+         ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / 
sizeof(sal_uInt16) ) &&
+         ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( 
nEndPos - pWMF->Tell() )
+       )
+    {
+        sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
+        for ( i = 0; i < nPoly && pWMF->good(); i++ )
+        {
+            *pWMF >> nPoints;
+            pnPoints[ i ] = (sal_uInt16)nPoints;
+        }
+        // Get polygon points:
+        for ( i = 0; ( i < nPoly ) && pWMF->good(); i++ )
+        {
+            Polygon aPolygon = ReadPolygon<T>(0, pnPoints[i]);
+            pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath );
+        }
+        delete[] pnPoints;
+    }
+}
+
+/**
+ * Reads a poly polygon from the WMF file and draws it.
+ * The <class T> parameter refers to the type of the points. (e.g. sal_uInt16 
or sal_uInt32)
+ * */
 template <class T>
 void EnhWMFReader::ReadAndDrawPolyPolygon()
 {
@@ -444,90 +506,29 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
         switch( nRecType )
         {
             case EMR_POLYBEZIERTO :
-                bFlag = sal_True;
+                
ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, 
_2, _3, _4), sal_True);
+            break;
             case EMR_POLYBEZIER :
-            {
-                pWMF->SeekRel( 16 );
-                *pWMF >> nPoints;
-                sal_uInt16 i = 0;
-                if ( bFlag )
-                {
-                    i++;
-                    nPoints++;
-                }
-                Polygon aPoly = ReadPolygon<sal_Int32>(i, nPoints);
-                pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath );
-            }
+                
ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, 
_2, _3, _4), sal_False);
             break;
 
             case EMR_POLYGON :
-            {
-                pWMF->SeekRel( 16 );
-                *pWMF >> nPoints;
-                Polygon aPoly = ReadPolygon<sal_Int32>(0, nPoints);
-                pOut->DrawPolygon( aPoly, bRecordPath );
-            }
+                
ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolygon, _1, _2, 
_3, _4), sal_False);
             break;
 
             case EMR_POLYLINETO :
-                bFlag = sal_True;
+                
ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, 
_3, _4), sal_True);
+            break;
             case EMR_POLYLINE :
-            {
-                pWMF->SeekRel( 0x10 );
-                *pWMF >> nPoints;
-                sal_uInt16 i = 0;
-                if ( bFlag )
-                {
-                    i++;
-                    nPoints++;
-                }
-                Polygon aPolygon = ReadPolygon<sal_Int32>(i, nPoints);
-                pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath );
-            }
+                
ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, 
_3, _4), sal_False);
             break;
 
             case EMR_POLYPOLYLINE :
-            {
-                sal_Int32   i, nPoly(0);
-                pWMF->SeekRel( 0x10 );
-
-                // Number of Polygons:
-                *pWMF >> nPoly >> i;
-
-                // taking the amount of points of each polygon, retrieving the 
total number of points
-                if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / 
sizeof(sal_uInt16) )
-                {
-                    if ( ( static_cast< sal_uInt32 >( nPoly ) * 
sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) )
-                    {
-                        sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
-
-                        for ( i = 0; i < nPoly; i++ )
-                        {
-                            *pWMF >> nPoints;
-                            pnPoints[ i ] = (sal_uInt16)nPoints;
-                        }
-
-                        // Get polygon points:
-                        for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ )
-                        {
-                            Polygon aPoly( pnPoints[ i ] );
-                            for( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ )
-                            {
-                                *pWMF >> nX32 >> nY32;
-                                aPoly[ k ] = Point( nX32, nY32 );
-                            }
-                            pOut->DrawPolyLine( aPoly, sal_False, bRecordPath 
);
-                        }
-                        delete[] pnPoints;
-                    }
-                }
-            }
+                ReadAndDrawPolyLine<sal_uInt32>();
             break;
 
             case EMR_POLYPOLYGON :
-            {
                 ReadAndDrawPolyPolygon<sal_uInt32>();
-            }
             break;
 
             case EMR_SETWINDOWEXTEX :
@@ -1192,82 +1193,29 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
             break;
 
             case EMR_POLYBEZIERTO16 :
-                bFlag = sal_True;
+                
ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, 
_2, _3, _4), sal_True);
+                break;
             case EMR_POLYBEZIER16 :
-            {
-                pWMF->SeekRel( 16 );
-                *pWMF >> nPoints;
-                sal_uInt16 i = 0;
-                if ( bFlag )
-                {
-                    i++;
-                    nPoints++;
-                }
-                Polygon aPoly = ReadPolygon<sal_Int16>(i, nPoints);
-                pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath );  // Line( 
aPoly, bFlag );
-            }
+                
ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, 
_2, _3, _4), sal_False);
             break;
 
             case EMR_POLYGON16 :
-            {
-                pWMF->SeekRel( 16 );
-                *pWMF >> nPoints;
-                Polygon aPoly = ReadPolygon<sal_Int16>(0, nPoints);
-                pOut->DrawPolygon( aPoly, bRecordPath );
-            }
+                
ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolygon, _1, _2, 
_3, _4), sal_False);
             break;
 
             case EMR_POLYLINETO16 :
-                bFlag = sal_True;
+                
ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, 
_3, _4), sal_True);
+                break;
             case EMR_POLYLINE16 :
-            {
-                pWMF->SeekRel( 16 );
-                *pWMF >> nPoints;
-                sal_uInt16 i = 0;
-                if ( bFlag )
-                {
-                    i++;
-                    nPoints++;
-                }
-                Polygon aPoly = ReadPolygon<sal_Int16>(i, nPoints);
-                pOut->DrawPolyLine( aPoly, bFlag, bRecordPath );
-            }
+                
ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, 
_3, _4), sal_False);
             break;
 
             case EMR_POLYPOLYLINE16 :
-            {
-                sal_Int32   i, nPoly(0), nGesPoints(0);
-                pWMF->SeekRel( 0x10 );
-                // Number of Polygons:
-                *pWMF >> nPoly >> nGesPoints;
-
-                // taking the amount of points of each polygon, retrieving the 
total number of points
-                if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / 
sizeof(sal_uInt16) )
-                {
-                    if ( ( static_cast< sal_uInt32 >( nPoly ) * 
sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) )
-                    {
-                        sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
-                        for ( i = 0; i < nPoly; i++ )
-                        {
-                            *pWMF >> nPoints;
-                            pnPoints[ i ] = (sal_uInt16)nPoints;
-                        }
-                        // Get polygon points:
-                        for ( i = 0; ( i < nPoly ) && pWMF->good(); i++ )
-                        {
-                            Polygon aPolygon = ReadPolygon<sal_Int16>(0, 
pnPoints[i]);
-                            pOut->DrawPolyLine( aPolygon, sal_False, 
bRecordPath );
-                        }
-                        delete[] pnPoints;
-                    }
-                }
-            }
-            break;
+                ReadAndDrawPolyLine<sal_uInt16>();
+                break;
 
             case EMR_POLYPOLYGON16 :
-            {
                 ReadAndDrawPolyPolygon<sal_uInt16>();
-            }
             break;
 
             case EMR_FILLRGN :
diff --git a/svtools/source/filter/wmf/winmtf.hxx 
b/svtools/source/filter/wmf/winmtf.hxx
index af0d960..693190c 100644
--- a/svtools/source/filter/wmf/winmtf.hxx
+++ b/svtools/source/filter/wmf/winmtf.hxx
@@ -738,6 +738,11 @@ public:
                             const Point& rEndAngle
                         );
     void                DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath = 
sal_False );
+    void                DrawPolygon( Polygon& rPolygon, sal_Bool bDrawTo, 
sal_Bool bRecordPath)
+                        { //only for the template compatibility
+                            bDrawTo = bDrawTo; //to avoid complaints about 
unused parameter
+                            DrawPolygon(rPolygon, bRecordPath);
+                        }
     void                DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool 
bRecordPath = sal_False );
     void                DrawPolyLine(
                             Polygon& rPolygon,
@@ -837,7 +842,9 @@ public:
     void            ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC);
 private:
     template <class T> void ReadAndDrawPolyPolygon();
-    template <class T> Polygon ReadPolygon(sal_uInt16 nStartIndex, sal_uInt16 
nPoints);
+    template <class T> void ReadAndDrawPolyLine();
+    template <class T> Polygon ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 
nPoints);
+    template <class T, class Drawer> void ReadAndDrawPolygon(Drawer drawer, 
const sal_Bool skipFirst);
 };
 
 //============================ WMFReader ==================================
-- 
1.7.6.4

_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to