summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorAndras Timar <andras.timar@collabora.com>2015-05-26 19:35:08 +0200
committerAndras Timar <andras.timar@collabora.com>2015-05-28 09:05:22 +0200
commit0fa10fa7ea7026de7d998776201747afda0ca6b2 (patch)
treeae0e3b1caa2b22fe46c32c70f15decd95af18f5a /oox
parentdabe4ad3bf21b6b6c9eadbd7e78262a1f59af771 (diff)
tdf#90338 tdf#84254 DrawingML export fix
Change-Id: I610d8099f057a2a34a1f9573d8ac16b5b8da9fc7 Reviewed-on: https://gerrit.libreoffice.org/15918 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Andras Timar <andras.timar@collabora.com> (cherry picked from commit 481c185e327cb83ffcb29657d5a354eae2c4a5f3)
Diffstat (limited to 'oox')
-rw-r--r--oox/source/export/drawingml.cxx206
-rw-r--r--oox/source/export/shapes.cxx17
2 files changed, 213 insertions, 10 deletions
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 832914f7ca9c..0600f60a65f1 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -43,6 +43,10 @@
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
@@ -2198,6 +2202,208 @@ void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool b
mpFS->endElementNS( XML_a, XML_prstGeom );
}
+void DrawingML::WriteCustomGeometry( Reference< XShape > rXShape )
+{
+ uno::Reference< beans::XPropertySet > aXPropSet;
+ uno::Any aAny( rXShape->queryInterface(cppu::UnoType<beans::XPropertySet>::get()));
+
+ if ( ! (aAny >>= aXPropSet) )
+ return;
+
+ try
+ {
+ aAny = aXPropSet->getPropertyValue( "CustomShapeGeometry" );
+ if ( !aAny.hasValue() )
+ return;
+ }
+ catch( const ::uno::Exception& )
+ {
+ return;
+ }
+
+
+ mpFS->startElementNS( XML_a, XML_custGeom, FSEND );
+ mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_gdLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_ahLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_rect,
+ XML_l, "l",
+ XML_t, "t",
+ XML_r, "r",
+ XML_b, "b",
+ FSEND );
+
+ mpFS->startElementNS( XML_a, XML_pathLst, FSEND );
+
+ uno::Sequence< beans::PropertyValue > const * pGeometrySeq =
+ static_cast<uno::Sequence< beans::PropertyValue > const *>(aAny.getValue());
+
+ if ( pGeometrySeq )
+ {
+ for( int i = 0; i < pGeometrySeq->getLength(); ++i )
+ {
+ const beans::PropertyValue& rProp = (*pGeometrySeq)[ i ];
+ if ( rProp.Name == "Path" )
+ {
+ uno::Sequence<beans::PropertyValue> aPathProp;
+ rProp.Value >>= aPathProp;
+
+ uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
+ uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
+ uno::Sequence<awt::Size> aPathSize;
+ bool bHasSubViewSize = false;
+ for (int j = 0; j < aPathProp.getLength(); ++j )
+ {
+ const beans::PropertyValue& rPathProp = aPathProp[j];
+ if (rPathProp.Name == "Coordinates")
+ rPathProp.Value >>= aPairs;
+ else if (rPathProp.Name == "Segments")
+ rPathProp.Value >>= aSegments;
+ else if (rPathProp.Name == "SubViewSize")
+ {
+ rPathProp.Value >>= aPathSize;
+ bHasSubViewSize = true;
+ }
+ }
+
+ if ( bHasSubViewSize )
+ {
+ mpFS->startElementNS( XML_a, XML_path,
+ XML_w, I64S( aPathSize[0].Width ),
+ XML_h, I64S( aPathSize[0].Height ),
+ FSEND );
+ }
+ else
+ {
+ sal_Int32 nXMin = aPairs[0].First.Value.get<sal_Int32>();
+ sal_Int32 nXMax = nXMin;
+ sal_Int32 nYMin = aPairs[0].Second.Value.get<sal_Int32>();
+ sal_Int32 nYMax = nYMin;
+
+ for ( int j = 0; j < aPairs.getLength(); ++j )
+ {
+ if ( aPairs[j].First.Value.get<sal_Int32>() < nXMin )
+ nXMin = aPairs[j].First.Value.get<sal_Int32>();
+ if ( aPairs[j].Second.Value.get<sal_Int32>() < nYMin )
+ nYMin = aPairs[j].Second.Value.get<sal_Int32>();
+ if ( aPairs[j].First.Value.get<sal_Int32>() > nXMax )
+ nXMax = aPairs[j].First.Value.get<sal_Int32>();
+ if ( aPairs[j].Second.Value.get<sal_Int32>() > nYMax )
+ nYMax = aPairs[j].Second.Value.get<sal_Int32>();
+ }
+ mpFS->startElementNS( XML_a, XML_path,
+ XML_w, I64S( nXMax - nXMin ),
+ XML_h, I64S( nYMax - nYMin ),
+ FSEND );
+ }
+
+
+ int nPairIndex = 0;
+ for( int j = 0; j < aSegments.getLength(); ++j )
+ {
+ if ( aSegments[ j ].Command == drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
+ {
+ mpFS->singleElementNS( XML_a, XML_close, FSEND );
+ }
+ for ( int k = 0; k < aSegments[j].Count; ++k )
+ {
+ switch( aSegments[ j ].Command )
+ {
+ case drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
+ {
+ mpFS->startElementNS( XML_a, XML_moveTo, FSEND );
+
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( aPairs[nPairIndex].First.Value.get<sal_Int32>() ),
+ XML_y, I64S( aPairs[nPairIndex].Second.Value.get<sal_Int32>() ),
+ FSEND );
+
+ mpFS->endElementNS( XML_a, XML_moveTo );
+ nPairIndex++;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::LINETO :
+ {
+ mpFS->startElementNS( XML_a, XML_lnTo, FSEND );
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( aPairs[nPairIndex].First.Value.get<sal_Int32>() ),
+ XML_y, I64S( aPairs[nPairIndex].Second.Value.get<sal_Int32>() ),
+ FSEND );
+ mpFS->endElementNS( XML_a, XML_lnTo );
+ nPairIndex++;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
+ {
+ mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
+ for( sal_uInt8 l = 0; l <= 2; ++l )
+ {
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( aPairs[nPairIndex+l].First.Value.get<sal_Int32>() ),
+ XML_y, I64S( aPairs[nPairIndex+l].Second.Value.get<sal_Int32>() ),
+ FSEND );
+
+ }
+ mpFS->endElementNS( XML_a, XML_cubicBezTo );
+ nPairIndex += 3;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+ case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+ {
+ nPairIndex += 3;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
+ case drawing::EnhancedCustomShapeSegmentCommand::ARC :
+ case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+ case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+ {
+ nPairIndex += 4;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+ case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+ {
+ nPairIndex++;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
+ {
+ mpFS->startElementNS( XML_a, XML_quadBezTo, FSEND );
+ for( sal_uInt8 l = 0; l < 2; ++l )
+ {
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( aPairs[nPairIndex+l].First.Value.get<sal_Int32>() ),
+ XML_y, I64S( aPairs[nPairIndex+l].Second.Value.get<sal_Int32>() ),
+ FSEND );
+
+ }
+ mpFS->endElementNS( XML_a, XML_quadBezTo );
+ nPairIndex += 2;
+ break;
+ }
+ case drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
+ {
+ nPairIndex += 2;
+ break;
+ }
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+ mpFS->endElementNS( XML_a, XML_path );
+ }
+ }
+ }
+
+ mpFS->endElementNS( XML_a, XML_pathLst );
+
+ mpFS->endElementNS( XML_a, XML_custGeom );
+}
+
void DrawingML::WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon )
{
if( rPolyPolygon.Count() < 1 )
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 1dce98ced58c..e2a5e75eb42a 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -291,6 +291,7 @@ static bool lcl_IsOnBlacklist(OUString& rShapeType)
static
#endif
const std::initializer_list<OUStringLiteral> vBlacklist = {
+ OUStringLiteral("ellipse"),
OUStringLiteral("ring"),
OUStringLiteral("can"),
OUStringLiteral("cube"),
@@ -478,17 +479,13 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
else if( bHasHandles )
bCustGeom = true;
- if (bCustGeom && pShape)
+ if (bHasHandles && bCustGeom && pShape)
{
- basegfx::B2DPolyPolygon aB2DPolyPolygon = pShape->GetLineGeometry(true);
- tools::PolyPolygon aPolyPolygon;
- for( sal_uInt32 i = 0; i < aB2DPolyPolygon.count(); ++i )
- {
- basegfx::B2DPolygon aB2DPolygon = aB2DPolyPolygon.getB2DPolygon(i);
- aPolyPolygon.Insert( Polygon( aB2DPolygon ), POLYPOLY_APPEND );
- }
-
- WritePolyPolygon( aPolyPolygon );
+ WritePolyPolygon( tools::PolyPolygon( pShape->GetLineGeometry(true) ) );
+ }
+ else if (bCustGeom && pShape)
+ {
+ WriteCustomGeometry( xShape );
}
else // preset geometry
{