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-andre@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
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.