diff options
author | Eilidh McAdam <eilidh@lanedo.com> | 2012-09-19 09:51:08 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-09-19 14:03:03 +0000 |
commit | 6cf41d047a65c40d34745f497482f88d5ec93acb (patch) | |
tree | 96ffefc29fa20d86b76cae6d60d057386aa00435 /oox | |
parent | 8aae567dc66c271fe3211f2847b48afbf02473b5 (diff) |
Add VML path parsing to .docx import filter.
Change-Id: Ibb90ff437f6de1cab98b64deeccfa38e0e30756b
Reviewed-on: https://gerrit.libreoffice.org/648
Reviewed-by: Miklos Vajna <vmiklos@suse.cz>
Tested-by: Miklos Vajna <vmiklos@suse.cz>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/inc/oox/vml/vmlformatting.hxx | 19 | ||||
-rw-r--r-- | oox/source/vml/vmlformatting.cxx | 123 |
2 files changed, 142 insertions, 0 deletions
diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx index 33f466223b65..1cbb3193d7f0 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 cf0e5d327cd6..0d56bc373e29 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 { |