summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/source/export/drawingml.cxx27
-rw-r--r--oox/source/export/shapes.cxx211
2 files changed, 237 insertions, 1 deletions
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 5f66ab5c2874..b93962ec2e63 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2189,6 +2189,33 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin
}
+void DrawingML::WritePresetShape( const char* pShape , std::vector< std::pair<sal_Int32,sal_Int32>> & rAvList )
+{
+ mpFS->startElementNS( XML_a, XML_prstGeom,
+ XML_prst, pShape,
+ FSEND );
+ if ( !rAvList.empty() )
+ {
+
+ mpFS->startElementNS( XML_a, XML_avLst, FSEND );
+ for(auto iter = rAvList.begin() ; iter != rAvList.end() ; ++iter)
+ {
+ OString sName = OString("adj") + ( ( iter->first > 0 ) ? OString::number(iter->first) : OString("") );
+ OString sFmla = OString("val ") + OString::number( iter->second );
+
+ mpFS->singleElementNS( XML_a, XML_gd,
+ XML_name, sName.getStr(),
+ XML_fmla, sFmla.getStr(),
+ FSEND );
+ }
+ mpFS->endElementNS( XML_a, XML_avLst );
+ }
+ else
+ mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
+
+ mpFS->endElementNS( XML_a, XML_prstGeom );
+}
+
void DrawingML::WritePresetShape( const char* pShape )
{
mpFS->startElementNS( XML_a, XML_prstGeom,
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 8d63d2cdfb06..d61635991cd6 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -52,6 +52,8 @@
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/embed/XEmbedPersist.hpp>
@@ -550,6 +552,9 @@ static bool lcl_IsOnBlacklist(OUString& rShapeType)
OUStringLiteral("col-60da8460"),
OUStringLiteral("col-502ad400"),
OUStringLiteral("quad-bevel"),
+ OUStringLiteral("round-rectangular-callout"),
+ OUStringLiteral("rectangular-callout"),
+ OUStringLiteral("round-callout"),
OUStringLiteral("cloud-callout"),
OUStringLiteral("line-callout-1"),
OUStringLiteral("line-callout-2"),
@@ -607,6 +612,83 @@ static bool lcl_IsOnWhitelist(OUString& rShapeType)
return std::find(vWhitelist.begin(), vWhitelist.end(), rShapeType) != vWhitelist.end();
}
+bool lcl_GetHandlePosition( sal_Int32 &nValue, const EnhancedCustomShapeParameter &rParam, Sequence< EnhancedCustomShapeAdjustmentValue > &rSeq)
+{
+ bool bAdj = false;
+ if ( rParam.Value.getValueTypeClass() == TypeClass_DOUBLE )
+ {
+ double fValue(0.0);
+ if ( rParam.Value >>= fValue )
+ nValue = (sal_Int32)fValue;
+ }
+ else
+ rParam.Value >>= nValue;
+
+ if ( rParam.Type == EnhancedCustomShapeParameterType::ADJUSTMENT)
+ {
+ bAdj = true;
+ sal_Int32 nIdx = nValue;
+ if ( nIdx < rSeq.getLength() )
+ {
+ if ( rSeq[ nIdx ] .Value.getValueTypeClass() == TypeClass_DOUBLE )
+ {
+ double fValue(0.0);
+ rSeq[ nIdx ].Value >>= fValue;
+ nValue = fValue;
+
+ }
+ else
+ {
+ rSeq[ nIdx ].Value >>= nValue;
+ }
+ }
+ }
+ return bAdj;
+}
+
+void lcl_AnalyzeHandles( const uno::Sequence<beans::PropertyValues> & rHandles,
+ std::vector< std::pair< sal_Int32, sal_Int32> > &rHandlePositionList,
+ Sequence< EnhancedCustomShapeAdjustmentValue > &rSeq)
+{
+ sal_uInt16 k, j;
+ sal_uInt16 nHandles = rHandles.getLength();
+ for ( k = 0; k < nHandles ; k++ )
+ {
+ const OUString sSwitched( "Switched" );
+ const OUString sPosition( "Position" );
+ sal_Int32 nXPosition = 0;
+ sal_Int32 nYPosition = 0;
+ bool bSwitched = false;
+ bool bPosition = false;
+ EnhancedCustomShapeParameterPair aPosition;
+ EnhancedCustomShapeParameterPair aPolar;
+ const Sequence< PropertyValue >& rPropSeq = rHandles[ k ];
+ for ( j = 0; j < rPropSeq.getLength(); j++ )
+ {
+ const PropertyValue& rPropVal = rPropSeq[ j ];
+ if ( rPropVal.Name.equals( sPosition ) )
+ {
+ if ( rPropVal.Value >>= aPosition )
+ bPosition = true;
+ }
+ else if ( rPropVal.Name.equals( sSwitched ) )
+ {
+ rPropVal.Value >>= bSwitched ;
+ }
+ }
+ if ( bPosition )
+ {
+ lcl_GetHandlePosition( nXPosition, aPosition.First , rSeq );
+ lcl_GetHandlePosition( nYPosition, aPosition.Second, rSeq );
+ rHandlePositionList.push_back( std::pair<sal_Int32, sal_Int32> ( nXPosition, nYPosition ) );
+ }
+ }
+}
+
+void lcl_AppendAdjustmentValue( std::vector< std::pair< sal_Int32, sal_Int32> > &rAvList, sal_Int32 nAdjIdx, sal_Int32 nValue )
+{
+ rAvList.push_back( std::pair<sal_Int32, sal_Int32> ( nAdjIdx , nValue ) );
+}
ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
{
@@ -615,6 +697,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
bool bPredefinedHandlesUsed = true;
bool bHasHandles = false;
+
OUString sShapeType;
sal_uInt32 nMirrorFlags = 0;
MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
@@ -624,6 +707,8 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
SAL_INFO("oox.shape", "custom shape type: " << sShapeType << " ==> " << sPresetShape);
Sequence< PropertyValue > aGeometrySeq;
sal_Int32 nAdjustmentValuesIndex = -1;
+ awt::Rectangle aViewBox;
+ uno::Sequence<beans::PropertyValues> aHandles;
bool bFlipH = false;
bool bFlipV = false;
@@ -646,7 +731,6 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
nAdjustmentValuesIndex = i;
else if ( rProp.Name == "Handles" )
{
- uno::Sequence<beans::PropertyValues> aHandles;
rProp.Value >>= aHandles;
if ( aHandles.getLength() )
bHasHandles = true;
@@ -658,6 +742,8 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
{
rProp.Value >>= m_presetWarp;
}
+ else if ( rProp.Name == "ViewBox" )
+ rProp.Value >>= aViewBox;
}
}
}
@@ -716,6 +802,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
// but our WritePolyPolygon()/WriteCustomGeometry() functions are incomplete, therefore we use a blacklist
// we use a whitelist for shapes where mapping to MSO preset shape is not optimal
bool bCustGeom = true;
+ bool bOnBlacklist = false;
if( sShapeType == "ooxml-non-primitive" )
bCustGeom = true;
else if( sShapeType.startsWith("ooxml") )
@@ -723,7 +810,10 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
else if( lcl_IsOnWhitelist(sShapeType) )
bCustGeom = true;
else if( lcl_IsOnBlacklist(sShapeType) )
+ {
bCustGeom = false;
+ bOnBlacklist = true;
+ }
else if( bHasHandles )
bCustGeom = true;
@@ -746,6 +836,125 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV );
WriteCustomGeometry( xShape );
}
+ else if (bOnBlacklist && bHasHandles && nAdjustmentValuesIndex !=-1 && !sShapeType.startsWith("mso-spt"))
+ {
+ WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV );
+ Sequence< EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
+ std::vector< std::pair< sal_Int32, sal_Int32> > aHandlePositionList;
+ std::vector< std::pair< sal_Int32, sal_Int32> > aAvList;
+ aGeometrySeq[ nAdjustmentValuesIndex ].Value >>= aAdjustmentSeq ;
+
+ lcl_AnalyzeHandles( aHandles, aHandlePositionList, aAdjustmentSeq );
+
+ sal_Int32 nXPosition = 0;
+ sal_Int32 nYPosition = 0;
+ if ( !aHandlePositionList.empty() )
+ {
+ nXPosition = aHandlePositionList[0].first ;
+ nYPosition = aHandlePositionList[0].second ;
+ }
+ switch( eShapeType )
+ {
+ case mso_sptBorderCallout1:
+ {
+ sal_Int32 adj3 = double(nYPosition)/aViewBox.Height *100000;
+ sal_Int32 adj4 = double(nXPosition)/aViewBox.Width *100000;
+ lcl_AppendAdjustmentValue( aAvList, 1, 18750 );
+ lcl_AppendAdjustmentValue( aAvList, 2, -8333 );
+ lcl_AppendAdjustmentValue( aAvList, 3, adj3 );
+ lcl_AppendAdjustmentValue( aAvList, 4, adj4 );
+ break;
+ }
+ case mso_sptBorderCallout2:
+ {
+ sal_Int32 adj5 = double(nYPosition)/aViewBox.Height *100000;
+ sal_Int32 adj6 = double(nXPosition)/aViewBox.Width *100000;
+ sal_Int32 adj3 = 18750;
+ sal_Int32 adj4 = -16667;
+ lcl_AppendAdjustmentValue( aAvList, 1, 18750 );
+ lcl_AppendAdjustmentValue( aAvList, 2, -8333 );
+ if ( aHandlePositionList.size() > 1 )
+ {
+ nXPosition = aHandlePositionList[1].first ;
+ nYPosition = aHandlePositionList[1].second ;
+ adj3 = double(nYPosition)/aViewBox.Height *100000;
+ adj4 = double(nXPosition)/aViewBox.Width *100000;
+ }
+ lcl_AppendAdjustmentValue( aAvList, 3, adj3 );
+ lcl_AppendAdjustmentValue( aAvList, 4, adj4 );
+ lcl_AppendAdjustmentValue( aAvList, 5, adj5 );
+ lcl_AppendAdjustmentValue( aAvList, 6, adj6 );
+ break;
+ }
+ case mso_sptWedgeRectCallout:
+ case mso_sptWedgeRRectCallout:
+ case mso_sptWedgeEllipseCallout:
+ case mso_sptCloudCallout:
+ {
+ sal_Int32 adj1 = (double(nXPosition)/aViewBox.Width -0.5) *100000;
+ sal_Int32 adj2 = (double(nYPosition)/aViewBox.Height -0.5) *100000;
+ lcl_AppendAdjustmentValue( aAvList, 1, adj1 );
+ lcl_AppendAdjustmentValue( aAvList, 2, adj2 );
+ if ( eShapeType == mso_sptWedgeRRectCallout)
+ {
+ lcl_AppendAdjustmentValue( aAvList, 3, 16667);
+ }
+
+ break;
+ }
+ case mso_sptFoldedCorner:
+ {
+ sal_Int32 adj = double( aViewBox.Width - nXPosition) / std::min( aViewBox.Width,aViewBox.Height ) * 100000;
+ lcl_AppendAdjustmentValue( aAvList, 0, adj );
+ break;
+ }
+ case mso_sptNoSmoking:
+ {
+ sal_Int32 adj = double( nXPosition )/7200 *50000 ;
+ lcl_AppendAdjustmentValue( aAvList, 0, adj );
+ break;
+ }
+ case mso_sptDonut:
+ case mso_sptSun:
+ case mso_sptMoon:
+ case mso_sptHorizontalScroll:
+ case mso_sptBevel:
+ case mso_sptBracketPair:
+ {
+ sal_Int32 adj = double( nXPosition )/aViewBox.Width*100000 ;
+ lcl_AppendAdjustmentValue( aAvList, 0, adj );
+ break;
+ }
+ case mso_sptCan:
+ case mso_sptCube:
+ case mso_sptBracePair:
+ case mso_sptVerticalScroll:
+ {
+ sal_Int32 adj = double( nYPosition )/aViewBox.Height *100000 ;
+ lcl_AppendAdjustmentValue( aAvList, 0, adj );
+ break;
+ }
+ case mso_sptSmileyFace:
+ {
+ sal_Int32 adj = double( nYPosition )/aViewBox.Height *100000 - 76458.0;
+ lcl_AppendAdjustmentValue( aAvList, 0, adj );
+ break;
+ }
+ // case mso_sptNil:
+ // case mso_sptBentConnector3:
+ // case mso_sptBorderCallout3:
+ default:
+ {
+ if (!strcmp( sPresetShape, "frame" ))
+ {
+ sal_Int32 adj1 = double( nYPosition )/aViewBox.Height *100000 ;
+ lcl_AppendAdjustmentValue( aAvList, 1, adj1 );
+ }
+ break;
+ }
+ }
+ WritePresetShape( sPresetShape , aAvList );
+ }
else // preset geometry
{
WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV );