Kaydet (Commit) 6cf41d04 authored tarafından Eilidh McAdam's avatar Eilidh McAdam Kaydeden (comit) Miklos Vajna

Add VML path parsing to .docx import filter.

Change-Id: Ibb90ff437f6de1cab98b64deeccfa38e0e30756b
Reviewed-on: https://gerrit.libreoffice.org/648Reviewed-by: 's avatarMiklos Vajna <vmiklos@suse.cz>
Tested-by: 's avatarMiklos Vajna <vmiklos@suse.cz>
üst 8aae567d
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "oox/helper/helper.hxx" #include "oox/helper/helper.hxx"
#include "oox/dllapi.h" #include "oox/dllapi.h"
#include <com/sun/star/awt/Point.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
namespace oox { namespace oox {
class GraphicHelper; class GraphicHelper;
...@@ -135,6 +137,23 @@ public: ...@@ -135,6 +137,23 @@ public:
sal_Int32 nDefaultRgb, sal_Int32 nDefaultRgb,
sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ); 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: private:
ConversionHelper(); ConversionHelper();
~ConversionHelper(); ~ConversionHelper();
......
...@@ -42,6 +42,10 @@ using ::oox::drawingml::LineProperties; ...@@ -42,6 +42,10 @@ using ::oox::drawingml::LineProperties;
using ::oox::drawingml::ShapePropertyMap; using ::oox::drawingml::ShapePropertyMap;
using ::rtl::OStringBuffer; using ::rtl::OStringBuffer;
using ::rtl::OUString; 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 ...@@ -264,6 +268,125 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
return aDmlColor; 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 { namespace {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment