summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorEilidh McAdam <eilidh@lanedo.com>2012-09-19 09:51:08 +0100
committerMiklos Vajna <vmiklos@suse.cz>2012-09-19 14:03:03 +0000
commit6cf41d047a65c40d34745f497482f88d5ec93acb (patch)
tree96ffefc29fa20d86b76cae6d60d057386aa00435 /oox
parent8aae567dc66c271fe3211f2847b48afbf02473b5 (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.hxx19
-rw-r--r--oox/source/vml/vmlformatting.cxx123
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 {