diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-06-10 15:34:44 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-06-10 17:53:02 +0100 |
commit | b04e1e79e64cb7bb3106fd08a019c27b09bdd5c6 (patch) | |
tree | 4e692bdb31e889df82c967a7a1731401816a6678 /oox/source | |
parent | 6cca91f7ada91701443225061a5dd0ae81a98b8e (diff) |
Prop_pSegmentInfo is totally misunderstood apparently
digging into the crash on export of kde216114-1.odt
reveals various horrors
Change-Id: I0d24fe303d561a00a08098b306d10fd8273af928
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/export/vmlexport.cxx | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index 9e8e6d29de20..7161a2f106c9 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -474,27 +474,56 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect for ( ; nSegments; --nSegments ) { sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt ); - switch ( nSeg ) + + // The segment type is stored in the upper 3 bits + // and segment count is stored in the lower 13 + // bits. + unsigned char nSegmentType = (nSeg & 0xE000) >> 13; + unsigned short nSegmentCount = nSeg & 0x03FF; + + switch (nSegmentType) { - case 0x4000: // moveto + case msopathMoveTo: + { + sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize ); + sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize ); + if (nX >= 0 && nY >= 0 ) + aPath.append( "m" ).append( nX ).append( "," ).append( nY ); + break; + } + case msopathClientEscape: + break; + case msopathEscape: + { + // If the segment type is msopathEscape, the lower 13 bits are + // divided in a 5 bit escape code and 8 bit + // vertex count (not segment count!) + unsigned char nEscapeCode = (nSegmentCount & 0x1F00) >> 8; + unsigned char nVertexCount = nSegmentCount & 0x00FF; + pVerticesIt += nVertexCount; + + switch (nEscapeCode) { - sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize ); - sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize ); - if (nX >= 0 && nY >= 0 ) - aPath.append( "m" ).append( nX ).append( "," ).append( nY ); + case 0xa: // nofill + aPath.append( "nf" ); + break; + case 0xb: // nostroke + aPath.append( "ns" ); + break; } + break; - case 0xb300: - case 0xac00: - break; - case 0x0001: // lineto + } + case msopathLineTo: + for (unsigned short i = 0; i < nSegmentCount; ++i) { sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize ); sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize ); aPath.append( "l" ).append( nX ).append( "," ).append( nY ); } break; - case 0x2001: // curveto + case msopathCurveTo: + for (unsigned short i = 0; i < nSegmentCount; ++i) { sal_Int32 nX1 = impl_GetPointComponent( pVerticesIt, nPointSize ); sal_Int32 nY1 = impl_GetPointComponent( pVerticesIt, nPointSize ); @@ -507,35 +536,17 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect .append( nX3 ).append( "," ).append( nY3 ); } break; - case 0xaa00: // nofill - aPath.append( "nf" ); - break; - case 0xab00: // nostroke - aPath.append( "ns" ); - break; - case 0x6001: // close + case msopathClose: aPath.append( "x" ); break; - case 0x8000: // end + case msopathEnd: aPath.append( "e" ); break; default: - // See EscherPropertyContainer::CreateCustomShapeProperties, by default nSeg is simply the number of points. - // FIXME: we miss out a significant amount of complexity from - // the above method here, and do some rather odd things to match. - int nElems = !nPointSize ? 0 : aVertices.nPropSize / (nPointSize * 2); - if (nSeg > nElems) - { - SAL_WARN("oox", "Busted escher export " << nSeg << "vs . " << nElems << " truncating point stream"); - nSeg = nElems; - } - for (int i = 0; i < nSeg; ++i) - { - sal_Int32 nX = impl_GetPointComponent(pVerticesIt, nPointSize); - sal_Int32 nY = impl_GetPointComponent(pVerticesIt, nPointSize); - if (nX >= 0 && nY >= 0 ) - aPath.append("l").append(nX).append(",").append(nY); - } + SAL_WARN("oox", "Totally b0rked\n"); + break; + case msopathInvalid: + SAL_WARN("oox", "Invalid - should never be found"); break; } } |