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