oox/inc/oox/vml/vmlformatting.hxx | 19 +++++ oox/source/vml/vmlformatting.cxx | 123 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+)
New commits: commit 6cf41d047a65c40d34745f497482f88d5ec93acb Author: Eilidh McAdam <[email protected]> Date: Wed Sep 19 09:51:08 2012 +0100 Add VML path parsing to .docx import filter. Change-Id: Ibb90ff437f6de1cab98b64deeccfa38e0e30756b Reviewed-on: https://gerrit.libreoffice.org/648 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Miklos Vajna <[email protected]> diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx index 33f4662..1cbb319 100644 --- a/oox/inc/oox/vml/vmlformatting.hxx +++ b/oox/inc/oox/vml/vmlformatting.hxx @@ -22,6 +22,8 @@ #include "oox/helper/helper.hxx" #include "oox/dllapi.h" +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> namespace oox { class GraphicHelper; @@ -135,6 +137,23 @@ public: sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ); + /** Converts VML path string into point and flag vectors. + + @param rPoints The point vector to fill with coordinates. + + @param rFlags The flag vector to fill. PolygonFlags_NORMAL indicates + a corresponding plain shape coordinate in rPoints and + PolygonFlags_CONTROL indicates a bezier curve control point. + + @param rPath The VML path string. + + @param rGraphicHelper See above. + */ + static void decodeVmlPath( + ::std::vector< ::std::vector< ::com::sun::star::awt::Point > >& rPoints, + ::std::vector< ::std::vector< ::com::sun::star::drawing::PolygonFlags > >& rFlags, + const OUString& rPath ); + private: ConversionHelper(); ~ConversionHelper(); diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index cf0e5d3..0d56bc3 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -42,6 +42,10 @@ using ::oox::drawingml::LineProperties; using ::oox::drawingml::ShapePropertyMap; using ::rtl::OStringBuffer; using ::rtl::OUString; +using ::com::sun::star::awt::Point; +using ::com::sun::star::drawing::PolygonFlags; +using ::com::sun::star::drawing::PolygonFlags_NORMAL; +using ::com::sun::star::drawing::PolygonFlags_CONTROL; // ============================================================================ @@ -264,6 +268,125 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r return aDmlColor; } +/*static*/ void ConversionHelper::decodeVmlPath( ::std::vector< ::std::vector< Point > >& rPointLists, ::std::vector< ::std::vector< PolygonFlags > >& rFlagLists, const OUString& rPath ) +{ + ::std::vector< sal_Int32 > aCoordList; + Point aCurrentPoint; + sal_Int32 nTokenStart = 0; + sal_Int32 nTokenLen = 0; + enum VML_State { START, MOVE_REL, MOVE_ABS, BEZIER_REL, BEZIER_ABS, + LINE_REL, LINE_ABS, CLOSE, END }; + VML_State state = START; + + rPointLists.push_back( ::std::vector< Point>() ); + rFlagLists.push_back( ::std::vector< PolygonFlags >() ); + + for ( sal_Int32 i = 0; i < rPath.getLength(); i++ ) + { + // Keep track of current integer token + if ( ( rPath[ i ] >= '0' && rPath[ i ] <= '9' ) || rPath[ i ] == '-' ) + nTokenLen++; + else if ( rPath[ i ] != ' ' ) + { + // Store coordinate from current token + if ( state != START ) + { + bool isX = aCoordList.size() % 2 == 0; + if ( nTokenLen > 0 ) + //aCoordList.push_back(decodeMeasureToHmm( rGraphicHelper, rPath.copy(nTokenStart, nTokenLen), 0, isX, true )); + aCoordList.push_back( rPath.copy( nTokenStart, nTokenLen ).toInt32() ); + else + aCoordList.push_back( 0 ); + nTokenLen = 0; + } + + // Upon finding the next command code, deal with stored + // coordinates for previous command + if ( rPath[ i ] != ',' ) + { + switch ( state ) + { + case MOVE_REL: + rPointLists.back().push_back( Point( aCoordList[ 0 ], aCoordList[ 1 ] ) ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case MOVE_ABS: + rPointLists.back().push_back( Point( aCoordList[ 0 ], aCoordList[ 1 ] ) ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case BEZIER_REL: + rPointLists.back().push_back( Point( aCurrentPoint.X + aCoordList[ 0 ], + aCurrentPoint.Y + aCoordList[ 1 ] ) ); + rPointLists.back().push_back( Point( aCurrentPoint.X + aCoordList[ 2 ], + aCurrentPoint.Y + aCoordList[ 3 ] ) ); + rPointLists.back().push_back( Point( aCurrentPoint.X + aCoordList[ 4 ], + aCurrentPoint.Y + aCoordList[ 5 ] ) ); + rFlagLists.back().push_back( PolygonFlags_CONTROL ); + rFlagLists.back().push_back( PolygonFlags_CONTROL ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case BEZIER_ABS: + rPointLists.back().push_back( Point( aCoordList[ 0 ], aCoordList[ 1 ] ) ); + rPointLists.back().push_back( Point( aCoordList[ 2 ], aCoordList[ 3 ] ) ); + rPointLists.back().push_back( Point( aCoordList[ 4 ], aCoordList[ 5 ] ) ); + rFlagLists.back().push_back( PolygonFlags_CONTROL ); + rFlagLists.back().push_back( PolygonFlags_CONTROL ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case LINE_REL: + rPointLists.back().push_back( Point( aCurrentPoint.X + aCoordList[ 0 ], + aCurrentPoint.Y + aCoordList[ 1 ] ) ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case LINE_ABS: + rPointLists.back().push_back( Point( aCoordList[ 0 ], aCoordList[ 1 ] ) ); + rFlagLists.back().push_back( PolygonFlags_NORMAL ); + aCurrentPoint = rPointLists.back().back(); + break; + + case CLOSE: + rPointLists.back().push_back( rPointLists.back()[ 0 ] ); + rFlagLists.back().push_back( rFlagLists.back()[ 0 ] ); + aCurrentPoint = rPointLists.back().back(); + break; + + case END: + rPointLists.push_back( ::std::vector< Point >() ); + rFlagLists.push_back( ::std::vector< PolygonFlags >() ); + break; + } + + aCoordList.clear(); + } + + // Move on to current command state + switch ( rPath[ i ] ) + { + case 't': state = MOVE_REL; nTokenLen = 0; break; + case 'm': state = MOVE_ABS; nTokenLen = 0; break; + case 'v': state = BEZIER_REL; nTokenLen = 0; break; + case 'c': state = BEZIER_ABS; nTokenLen = 0; break; + case 'r': state = LINE_REL; nTokenLen = 0; break; + case 'l': state = LINE_ABS; nTokenLen = 0; break; + case 'x': state = CLOSE; nTokenLen = 0; break; + case 'e': state = END; break; + } + + nTokenStart = i+1; + } + } +} + // ============================================================================ namespace { _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
