summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oox/source/vml/vmlformatting.cxx107
1 files changed, 96 insertions, 11 deletions
diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx
index 05940f941281..b3cac88b5c04 100644
--- a/oox/source/vml/vmlformatting.cxx
+++ b/oox/source/vml/vmlformatting.cxx
@@ -273,8 +273,9 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
sal_Int32 nTokenStart = 0;
sal_Int32 nTokenLen = 0;
sal_Int32 nParamCount = 0;
+ bool bCommand = false;
enum VML_State { START, MOVE_REL, MOVE_ABS, BEZIER_REL, BEZIER_ABS,
- LINE_REL, LINE_ABS, CLOSE, END };
+ LINE_REL, LINE_ABS, CLOSE, END, UNSUPPORTED };
VML_State state = START;
rPointLists.push_back( ::std::vector< Point>() );
@@ -288,7 +289,7 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
else if ( rPath[ i ] != ' ' )
{
// Store coordinate from current token
- if ( state != START )
+ if ( state != START && state != UNSUPPORTED )
{
if ( nTokenLen > 0 )
aCoordList.push_back( rPath.copy( nTokenStart, nTokenLen ).toInt32() );
@@ -374,25 +375,109 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
break;
case START:
+ case UNSUPPORTED:
break;
}
aCoordList.clear();
}
- // Move on to current command state
+ // Allow two-char commands to peek ahead to the next character
+ char nextChar = '\0';
+ if (i+1 < rPath.getLength())
+ nextChar = rPath[i+1];
+
+ // Move to relevant state upon finding a command
+ bCommand = true;
switch ( rPath[ i ] )
{
- case 't': state = MOVE_REL; nTokenLen = 0; nParamCount = 2 * 2; break;
- case 'm': state = MOVE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break;
- case 'v': state = BEZIER_REL; nTokenLen = 0; nParamCount = 2 * 6; break;
- case 'c': state = BEZIER_ABS; nTokenLen = 0; nParamCount = 2 * 6; break;
- case 'r': state = LINE_REL; nTokenLen = 0; nParamCount = 2 * 2; break;
- case 'l': state = LINE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break;
- case 'x': state = CLOSE; nTokenLen = 0; break;
- case 'e': state = END; break;
+ // Single-character commands
+ case 't': // rmoveto
+ state = MOVE_REL; nParamCount = 2 * 2; break;
+ case 'm': // moveto
+ state = MOVE_ABS; nParamCount = 2 * 2; break;
+ case 'v': // rcurveto
+ state = BEZIER_REL; nParamCount = 2 * 6; break;
+ case 'c': // curveto
+ state = BEZIER_ABS; nParamCount = 2 * 6; break;
+ case 'r': // rlineto
+ state = LINE_REL; nParamCount = 2 * 2; break;
+ case 'l': // lineto
+ state = LINE_ABS; nParamCount = 2 * 2; break;
+ case 'x': // close
+ state = CLOSE; break;
+ case 'e': // end
+ state = END; break;
+
+ // Two-character commands
+ case 'n':
+ {
+ switch ( nextChar )
+ {
+ case 'f': // nf - nofill
+ case 's': // ns - nostroke
+ state = UNSUPPORTED; i++; break;
+ }
+ break;
+ }
+ case 'a': // Elliptical curves
+ {
+ switch ( nextChar )
+ {
+ case 'e': // ae - angleellipseto
+ case 'l': // al - angleellipse
+ state = UNSUPPORTED; i++; break;
+ case 't': // at - arcto
+ case 'r': // ar - arc
+ state = UNSUPPORTED; i++; break;
+ }
+ break;
+ }
+ case 'w': // Clockwise elliptical arcs
+ {
+ switch ( nextChar )
+ {
+ case 'a': // wa - clockwisearcto
+ case 'r': // wr - clockwisearc
+ state = UNSUPPORTED; i++; break;
+ }
+ break;
+ }
+ case 'q':
+ {
+ switch ( nextChar )
+ {
+ case 'x': // qx - ellipticalquadrantx
+ case 'y': // qy - ellipticalquadranty
+ state = UNSUPPORTED; i++; break;
+ case 'b': // qb - quadraticbezier
+ state = UNSUPPORTED; i++; break;
+ }
+ break;
+ }
+ case 'h': // behaviour extensions
+ {
+ switch ( nextChar )
+ {
+ case 'a': // ha - AutoLine
+ case 'b': // hb - AutoCurve
+ case 'c': // hc - CornerLine
+ case 'd': // hd - CornerCurve
+ case 'e': // he - SmoothLine
+ case 'f': // hf - SmoothCurve
+ case 'g': // hg - SymmetricLine
+ case 'h': // hh - SymmetricCurve
+ case 'i': // hi - Freeform
+ state = UNSUPPORTED; i++; break;
+ }
+ break;
+ }
+ default:
+ bCommand = false;
+ break;
}
+ if (bCommand) nTokenLen = 0;
nTokenStart = i+1;
}
}