summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2018-07-20 17:21:43 +0200
committerSzymon Kłos <szymon.klos@collabora.com>2018-08-02 17:16:08 +0200
commitbf3420110cdd21490bc8d49a471340e747585159 (patch)
tree7ab84ace33c8dc6f5c1872c50d9c5b0e58636ee2
parent587d2c036bbd250c9186c927ab7097d64742c5bb (diff)
tdf#116350 Import preset text geometry (text effects)
"Font effect" implementation, instead of normal text, content is converted to "fontwork". Change-Id: I5d02c7faedb66a4b919e64ae1b830bffb69984c1 Reviewed-on: https://gerrit.libreoffice.org/58358 Tested-by: Jenkins Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
-rw-r--r--oox/Library_oox.mk1
-rw-r--r--oox/inc/drawingml/presetgeometrynames.hxx23
-rw-r--r--oox/inc/drawingml/textbodycontext.hxx2
-rw-r--r--oox/inc/drawingml/textbodyproperties.hxx1
-rw-r--r--oox/inc/drawingml/textbodypropertiescontext.hxx5
-rw-r--r--oox/source/drawingml/presetgeometrynames.cxx108
-rw-r--r--oox/source/drawingml/shape.cxx184
-rw-r--r--oox/source/drawingml/shapecontext.cxx4
-rw-r--r--oox/source/drawingml/textbodycontext.cxx12
-rw-r--r--oox/source/drawingml/textbodyproperties.cxx1
-rw-r--r--oox/source/drawingml/textbodypropertiescontext.cxx32
-rw-r--r--oox/source/ppt/pptshapecontext.cxx2
-rw-r--r--sd/qa/unit/data/pptx/tdf116350-texteffects.pptxbin0 -> 38359 bytes
-rw-r--r--sd/qa/unit/export-tests-ooxml2.cxx50
14 files changed, 420 insertions, 5 deletions
diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk
index a21157be131f..e917a9b866d3 100644
--- a/oox/Library_oox.mk
+++ b/oox/Library_oox.mk
@@ -159,6 +159,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\
oox/source/drawingml/linepropertiescontext \
oox/source/drawingml/lineproperties \
oox/source/drawingml/objectdefaultcontext \
+ oox/source/drawingml/presetgeometrynames \
oox/source/drawingml/scene3dcontext \
oox/source/drawingml/shapecontext \
oox/source/drawingml/shape \
diff --git a/oox/inc/drawingml/presetgeometrynames.hxx b/oox/inc/drawingml/presetgeometrynames.hxx
new file mode 100644
index 000000000000..51721e41febd
--- /dev/null
+++ b/oox/inc/drawingml/presetgeometrynames.hxx
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_OOX_DRAWINGML_PRESETGEOMETRYNAMES_HXX
+#define INCLUDED_OOX_DRAWINGML_PRESETGEOMETRYNAMES_HXX
+
+#include <rtl/ustring.hxx>
+#include <oox/dllapi.h>
+
+namespace PresetGeometryTypeNames
+{
+OOX_DLLPUBLIC OUString GetFontworkType(const OUString& rMsoType);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/oox/inc/drawingml/textbodycontext.hxx b/oox/inc/drawingml/textbodycontext.hxx
index a3439105493a..39ae7b8a1b59 100644
--- a/oox/inc/drawingml/textbodycontext.hxx
+++ b/oox/inc/drawingml/textbodycontext.hxx
@@ -32,11 +32,13 @@ class TextBodyContext final : public ::oox::core::ContextHandler2
{
public:
TextBodyContext( ::oox::core::ContextHandler2Helper const & rParent, TextBody& rTextBody );
+ TextBodyContext( ::oox::core::ContextHandler2Helper const & rParent, ShapePtr pShapePtr );
virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override;
private:
TextBody& mrTextBody;
+ ShapePtr mpShapePtr;
};
// CT_RegularTextRun
diff --git a/oox/inc/drawingml/textbodyproperties.hxx b/oox/inc/drawingml/textbodyproperties.hxx
index bcb75546a688..62ee3190ae58 100644
--- a/oox/inc/drawingml/textbodyproperties.hxx
+++ b/oox/inc/drawingml/textbodyproperties.hxx
@@ -41,6 +41,7 @@ struct TextBodyProperties
boost::optional< sal_Int32 > moTextOffLower;
boost::optional< sal_Int32 > moTextOffRight;
css::drawing::TextVerticalAdjust meVA;
+ OUString msPrst;
explicit TextBodyProperties();
diff --git a/oox/inc/drawingml/textbodypropertiescontext.hxx b/oox/inc/drawingml/textbodypropertiescontext.hxx
index 0ec5fe455185..b6305866e014 100644
--- a/oox/inc/drawingml/textbodypropertiescontext.hxx
+++ b/oox/inc/drawingml/textbodypropertiescontext.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_OOX_DRAWINGML_TEXTBODYPROPERTIESCONTEXT_HXX
#include <oox/core/contexthandler2.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
namespace oox { namespace drawingml {
@@ -33,10 +34,14 @@ public:
const ::oox::AttributeList& rAttributes,
TextBodyProperties& rTextBodyProp );
+ TextBodyPropertiesContext( ::oox::core::ContextHandler2Helper const & rParent,
+ const ::oox::AttributeList& rAttributes, ShapePtr pShapePtr );
+
virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override;
private:
TextBodyProperties& mrTextBodyProp;
+ ShapePtr mpShapePtr;
};
} }
diff --git a/oox/source/drawingml/presetgeometrynames.cxx b/oox/source/drawingml/presetgeometrynames.cxx
new file mode 100644
index 000000000000..4939cfcf0a3f
--- /dev/null
+++ b/oox/source/drawingml/presetgeometrynames.cxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <osl/mutex.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <unordered_map>
+#include <cstring>
+#include <drawingml/presetgeometrynames.hxx>
+#include <memory>
+
+namespace
+{
+typedef std::unordered_map<const char*, const char*, rtl::CStringHash, rtl::CStringEqual>
+ PresetGeometryHashMap;
+
+static PresetGeometryHashMap* pHashMap = nullptr;
+::osl::Mutex& getHashMapMutex()
+{
+ static osl::Mutex s_aHashMapProtection;
+ return s_aHashMapProtection;
+}
+
+struct PresetGeometryName
+{
+ const char* pMsoName;
+ const char* pFontworkType;
+};
+
+static const PresetGeometryName pPresetGeometryNameArray[]
+ = { { "textNoShape", "" },
+ { "textPlain", "fontwork-plain-text" },
+ { "textStop", "fontwork-stop" },
+ { "textTriangle", "fontwork-triangle-up" },
+ { "textTriangleInverted", "fontwork-triangle-down" },
+ { "textChevron", "fontwork-chevron-up" },
+ { "textChevronInverted", "fontwork-chevron-down" },
+ { "textRingInside", "mso-spt142" },
+ { "textRingOutside", "mso-spt143" },
+ { "textArchUp", "fontwork-arch-up-curve" },
+ { "textArchDown", "fontwork-arch-down-curve" },
+ { "textCircle", "fontwork-circle-curve" },
+ { "textButton", "fontwork-open-circle-curve" },
+ { "textArchUpPour", "fontwork-arch-up-pour" },
+ { "textArchDownPour", "fontwork-arch-down-pour" },
+ { "textCirclePour", "fontwork-circle-pour" },
+ { "textButtonPour", "fontwork-open-circle-pour" },
+ { "textCurveUp", "fontwork-curve-up" },
+ { "textCurveDown", "fontwork-curve-down" },
+ { "textCanUp", "mso-spt174" },
+ { "textCanDown", "mso-spt175" },
+ { "textWave1", "fontwork-wave" },
+ { "textWave2", "mso-spt157" },
+ { "textDoubleWave1", "mso-spt158" },
+ { "textWave4", "mso-spt159" },
+ { "textInflate", "fontwork-inflate" },
+ { "textDeflate", "fontwork-inflate" },
+ { "textInflateBottom", "mso-spt162" },
+ { "textDeflateBottom", "mso-spt163" },
+ { "textInflateTop", "mso-spt163" },
+ { "textDeflateTop", "mso-spt165" },
+ { "textDeflateInflate", "mso-spt166" },
+ { "textDeflateInflateDeflate", "mso-spt167" },
+ { "textFadeRight", "fontwork-fade-right" },
+ { "textFadeLeft", "fontwork-fade-left" },
+ { "textFadeUp", "fontwork-fade-up" },
+ { "textFadeDown", "fontwork-fade-down" },
+ { "textSlantUp", "fontwork-slant-up" },
+ { "textSlantDown", "fontwork-slant-down" },
+ { "textCascadeUp", "fontwork-fade-up-and-right" },
+ { "textCascadeDown", "fontwork-fade-up-and-left" } };
+}
+
+OUString PresetGeometryTypeNames::GetFontworkType(const OUString& rMsoType)
+{
+ if (!pHashMap)
+ { // init hash map
+ ::osl::MutexGuard aGuard(getHashMapMutex());
+ if (!pHashMap)
+ {
+ PresetGeometryHashMap* pH = new PresetGeometryHashMap;
+ const PresetGeometryName* pPtr = pPresetGeometryNameArray;
+ const PresetGeometryName* pEnd = pPtr + SAL_N_ELEMENTS(pPresetGeometryNameArray);
+ for (; pPtr < pEnd; pPtr++)
+ (*pH)[pPtr->pMsoName] = pPtr->pFontworkType;
+ pHashMap = pH;
+ }
+ }
+ const char* pRetValue = "";
+ int i, nLen = rMsoType.getLength();
+ std::unique_ptr<char[]> pBuf(new char[nLen + 1]);
+ for (i = 0; i < nLen; i++)
+ pBuf[i] = static_cast<char>(rMsoType[i]);
+ pBuf[i] = 0;
+ PresetGeometryHashMap::const_iterator aHashIter(pHashMap->find(pBuf.get()));
+ if (aHashIter != pHashMap->end())
+ pRetValue = (*aHashIter).second;
+
+ return OUString(pRetValue, strlen(pRetValue), RTL_TEXTENCODING_ASCII_US);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index d2966435779d..7ee3ef544f01 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -24,6 +24,7 @@
#include <drawingml/graphicproperties.hxx>
#include <drawingml/scene3dcontext.hxx>
#include <drawingml/lineproperties.hxx>
+#include <drawingml/presetgeometrynames.hxx>
#include "effectproperties.hxx"
#include <oox/drawingml/shapepropertymap.hxx>
#include <drawingml/textbody.hxx>
@@ -56,6 +57,7 @@
#include <editeng/unoprnms.hxx>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
@@ -67,6 +69,8 @@
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/drawing/GraphicExportFilter.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
@@ -88,6 +92,7 @@
#include <vcl/graphicfilter.hxx>
#include <vcl/svapp.hxx>
#include <sal/log.hxx>
+#include <svx/unoshape.hxx>
#include <vcl/wmf.hxx>
@@ -395,6 +400,172 @@ void Shape::addChildren(
}
}
+static inline void lcl_resetPropertyValue( std::vector<beans::PropertyValue>& rPropVec, const OUString& rName )
+{
+ auto aIterator = std::find_if( rPropVec.begin(), rPropVec.end(),
+ [rName]( const beans::PropertyValue& rValue ) { return rValue.Name == rName; } );
+
+ if (aIterator != rPropVec.end())
+ rPropVec.erase( aIterator );
+}
+
+static inline void lcl_setPropertyValue( std::vector<beans::PropertyValue>& rPropVec,
+ const OUString& rName,
+ const beans::PropertyValue& rPropertyValue )
+{
+ auto aIterator = std::find_if(
+ rPropVec.begin(), rPropVec.end(),
+ [rName]( const beans::PropertyValue& rValue ) { return rValue.Name == rName; } );
+
+ if (aIterator != rPropVec.end())
+ rPropVec.erase( aIterator );
+
+ rPropVec.push_back( rPropertyValue );
+}
+
+static inline SdrTextHorzAdjust lcl_convertAdjust( ParagraphAdjust eAdjust )
+{
+ if (eAdjust == ParagraphAdjust_LEFT)
+ return SDRTEXTHORZADJUST_LEFT;
+ else if (eAdjust == ParagraphAdjust_RIGHT)
+ return SDRTEXTHORZADJUST_RIGHT;
+ else if (eAdjust == ParagraphAdjust_CENTER)
+ return SDRTEXTHORZADJUST_CENTER;
+ return SDRTEXTHORZADJUST_LEFT;
+}
+
+static inline void lcl_createPresetShape( uno::Reference<drawing::XShape>& xShape,
+ const OUString& rClass,
+ const CustomShapePropertiesPtr pCustomShapePropertiesPtr,
+ const TextBodyPtr pTextBody,
+ const GraphicHelper& rGraphicHelper )
+{
+ if (!xShape.is() || !pCustomShapePropertiesPtr || !pTextBody)
+ return;
+
+ uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter( xShape,
+ uno::UNO_QUERY );
+
+ if (!xDefaulter.is() || rClass.isEmpty())
+ return;
+
+ Reference<XPropertySet> xSet( xShape, UNO_QUERY );
+ if (!xSet.is())
+ return;
+
+ auto aGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList();
+ Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment(
+ aGdList.size() ? aGdList.size() : 1 );
+
+ int nIndex = 0;
+ for (auto& aEntry : aGdList)
+ {
+ double fAngle = NormAngle360( aEntry.maFormula.toDouble() / -600.0 );
+ fAngle = 360.0 - fAngle / 100.0;
+
+ aAdjustment[nIndex].Value <<= fAngle;
+ aAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE;
+ }
+
+ if (!aGdList.size())
+ {
+ // Default angle
+ double fAngle = 0;
+ if (rClass == "fontwork-arch-up-curve")
+ fAngle = 180;
+
+ aAdjustment[0].Value <<= fAngle;
+ aAdjustment[0].State = css::beans::PropertyState_DIRECT_VALUE;
+ }
+
+ // Set properties
+ xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::makeAny( false ) );
+ xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWWIDTH, uno::makeAny( false ) );
+ xSet->setPropertyValue( UNO_NAME_FILLSTYLE, uno::makeAny( drawing::FillStyle_SOLID ) );
+
+ const TextParagraphVector& rParagraphs = pTextBody->getParagraphs();
+ if (rParagraphs.size() && rParagraphs[0]->getRuns().size())
+ {
+ std::shared_ptr<TextParagraph> pParagraph = rParagraphs[0];
+ std::shared_ptr<TextRun> pRun = pParagraph->getRuns()[0];
+ TextCharacterProperties& pProperties = pRun->getTextCharacterProperties();
+
+ if (pProperties.moBold.has() && pProperties.moBold.get())
+ {
+ xSet->setPropertyValue( UNO_NAME_CHAR_WEIGHT, uno::makeAny( css::awt::FontWeight::BOLD ) );
+ }
+ if (pProperties.moItalic.has() && pProperties.moItalic.get())
+ {
+ xSet->setPropertyValue( UNO_NAME_CHAR_POSTURE, uno::makeAny( css::awt::FontSlant::FontSlant_ITALIC ) );
+ }
+ if (pProperties.moHeight.has())
+ {
+ sal_Int32 nHeight = pProperties.moHeight.get() / 100;
+ xSet->setPropertyValue( UNO_NAME_CHAR_HEIGHT, uno::makeAny( nHeight ) );
+ }
+ if (pProperties.maFillProperties.maFillColor.isUsed())
+ {
+ const sal_Int32 aFillColor = static_cast<sal_Int32>(
+ pProperties.maFillProperties.maFillColor.getColor( rGraphicHelper ).GetRGBColor() );
+ xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::makeAny( aFillColor ) );
+ }
+ else
+ {
+ // Set default color
+ xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::makeAny( COL_BLACK ) );
+ }
+ {
+ ParagraphAdjust eAdjust = ParagraphAdjust_LEFT;
+ if (pParagraph->getProperties().getParaAdjust())
+ eAdjust = pParagraph->getProperties().getParaAdjust().get();
+ xSet->setPropertyValue( "ParaAdjust", uno::makeAny( eAdjust ) );
+ SvxShape* pShape = SvxShape::getImplementation( xShape );
+ SdrTextHorzAdjust eHorzAdjust = lcl_convertAdjust( eAdjust );
+ pShape->GetSdrObject()->SetMergedItem( SdrTextHorzAdjustItem( eHorzAdjust ) );
+ }
+ }
+
+ // Apply preset shape
+ xDefaulter->createCustomShapeDefaults( rClass );
+
+ auto aGeomPropSeq = xSet->getPropertyValue( "CustomShapeGeometry" )
+ .get<uno::Sequence<beans::PropertyValue>>();
+ auto aGeomPropVec
+ = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(
+ aGeomPropSeq );
+
+ // Reset old properties
+ const OUString sCoordinateSize( "CoordinateSize" );
+ const OUString sEquations( "Equations" );
+ const OUString sPath( "Path" );
+ const OUString sTextPath( "TextPath" );
+ const OUString sAdjustmentValues( "AdjustmentValues" );
+
+ lcl_resetPropertyValue( aGeomPropVec, sCoordinateSize );
+ lcl_resetPropertyValue( aGeomPropVec, sEquations );
+ lcl_resetPropertyValue( aGeomPropVec, sPath );
+
+ // Apply geometry properties
+ uno::Sequence<beans::PropertyValue> aPropertyValues(
+ comphelper::InitPropertySequence(
+ { { sTextPath, uno::makeAny( true ) },
+ { "TextPathMode",
+ uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) },
+ { "ScaleX", uno::Any( false ) } } ) );
+
+ lcl_setPropertyValue( aGeomPropVec, sTextPath,
+ comphelper::makePropertyValue( sTextPath, aPropertyValues ) );
+
+ if ( rClass == "fontwork-arch-up-curve" || rClass == "fontwork-circle-curve"
+ || rClass == "fontwork-arch-down-curve" || rClass == "fontwork-open-circle-curve" )
+ lcl_setPropertyValue( aGeomPropVec, sAdjustmentValues,
+ comphelper::makePropertyValue( sAdjustmentValues, aAdjustment ) );
+
+ xSet->setPropertyValue(
+ "CustomShapeGeometry",
+ uno::makeAny(comphelper::containerToSequence(aGeomPropVec)));
+}
+
Reference< XShape > const & Shape::createAndInsert(
::oox::core::XmlFilterBase& rFilterBase,
const OUString& rServiceName,
@@ -1121,6 +1292,19 @@ Reference< XShape > const & Shape::createAndInsert(
SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
mpCustomShapePropertiesPtr->pushToPropSet( xSet, mxShape, maSize );
+
+ if (mpTextBody)
+ {
+ bool bIsPresetShape = !mpTextBody->getTextProperties().msPrst.isEmpty();
+ if (bIsPresetShape)
+ {
+ OUString sClass;
+ const OUString sPresetType = mpTextBody->getTextProperties().msPrst;
+ sClass = PresetGeometryTypeNames::GetFontworkType( sPresetType );
+
+ lcl_createPresetShape( mxShape, sClass, mpCustomShapePropertiesPtr, mpTextBody, rGraphicHelper );
+ }
+ }
}
else if( getTextBody() )
getTextBody()->getTextProperties().pushVertSimulation();
diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx
index 22fa1671be31..62e81dba5f58 100644
--- a/oox/source/drawingml/shapecontext.cxx
+++ b/oox/source/drawingml/shapecontext.cxx
@@ -97,7 +97,7 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 aElementToken, const
{
if (!mpShapePtr->getTextBody())
mpShapePtr->setTextBody( std::make_shared<TextBody>() );
- return new TextBodyContext( *this, *mpShapePtr->getTextBody() );
+ return new TextBodyContext( *this, mpShapePtr );
}
case XML_txXfrm:
{
@@ -111,7 +111,7 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 aElementToken, const
case XML_bodyPr:
if (!mpShapePtr->getTextBody())
mpShapePtr->setTextBody( std::make_shared<TextBody>() );
- return new TextBodyPropertiesContext( *this, rAttribs, mpShapePtr->getTextBody()->getTextProperties() );
+ return new TextBodyPropertiesContext( *this, rAttribs, mpShapePtr );
break;
case XML_txbx:
break;
diff --git a/oox/source/drawingml/textbodycontext.cxx b/oox/source/drawingml/textbodycontext.cxx
index fdf3d62f5a6c..6279b129cf02 100644
--- a/oox/source/drawingml/textbodycontext.cxx
+++ b/oox/source/drawingml/textbodycontext.cxx
@@ -25,6 +25,7 @@
#include <drawingml/textliststylecontext.hxx>
#include <drawingml/textfield.hxx>
#include <drawingml/textfieldcontext.hxx>
+#include <oox/drawingml/shape.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
@@ -163,12 +164,21 @@ TextBodyContext::TextBodyContext( ContextHandler2Helper const & rParent, TextBod
{
}
+TextBodyContext::TextBodyContext( ContextHandler2Helper const & rParent, ShapePtr pShapePtr )
+: TextBodyContext( rParent, *pShapePtr->getTextBody() )
+{
+ mpShapePtr = pShapePtr;
+}
+
ContextHandlerRef TextBodyContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
{
switch( aElementToken )
{
case A_TOKEN( bodyPr ): // CT_TextBodyPropertyBag
- return new TextBodyPropertiesContext( *this, rAttribs, mrTextBody.getTextProperties() );
+ if ( mpShapePtr )
+ return new TextBodyPropertiesContext( *this, rAttribs, mpShapePtr );
+ else
+ return new TextBodyPropertiesContext( *this, rAttribs, mrTextBody.getTextProperties() );
case A_TOKEN( lstStyle ): // CT_TextListStyle
return new TextListStyleContext( *this, mrTextBody.getTextListStyle() );
case A_TOKEN( p ): // CT_TextParagraph
diff --git a/oox/source/drawingml/textbodyproperties.cxx b/oox/source/drawingml/textbodyproperties.cxx
index 71f8c8c3f1bd..5998c429b494 100644
--- a/oox/source/drawingml/textbodyproperties.cxx
+++ b/oox/source/drawingml/textbodyproperties.cxx
@@ -33,6 +33,7 @@ namespace drawingml {
TextBodyProperties::TextBodyProperties()
: mbAnchorCtr(false)
, meVA( TextVerticalAdjust_TOP )
+ , msPrst()
{
}
diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx
index 944ada853ef1..6de4a0764cbd 100644
--- a/oox/source/drawingml/textbodypropertiescontext.cxx
+++ b/oox/source/drawingml/textbodypropertiescontext.cxx
@@ -22,13 +22,22 @@
#include <com/sun/star/text/WritingMode.hpp>
#include <com/sun/star/drawing/TextFitToSizeType.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
#include <drawingml/textbodyproperties.hxx>
+#include <drawingml/textbody.hxx>
+#include <drawingml/customshapegeometry.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <oox/helper/attributelist.hxx>
#include <oox/helper/propertymap.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
+#include <svx/EnhancedCustomShapeGeometry.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
using namespace ::oox::core;
using namespace ::com::sun::star;
@@ -41,9 +50,17 @@ namespace oox { namespace drawingml {
// CT_TextBodyProperties
TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper const & rParent,
+ const AttributeList& rAttribs, ShapePtr pShapePtr )
+: TextBodyPropertiesContext( rParent, rAttribs, pShapePtr->getTextBody()->getTextProperties() )
+{
+ mpShapePtr = pShapePtr;
+}
+
+TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper const & rParent,
const AttributeList& rAttribs, TextBodyProperties& rTextBodyProp )
: ContextHandler2( rParent )
, mrTextBodyProp( rTextBodyProp )
+, mpShapePtr( nullptr )
{
// ST_TextWrappingType
sal_Int32 nWrappingType = rAttribs.getToken( XML_wrap, XML_square );
@@ -111,12 +128,25 @@ TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper cons
mrTextBodyProp.maPropertyMap.setProperty( PROP_TextFitToSize, drawing::TextFitToSizeType_NONE);
}
-ContextHandlerRef TextBodyPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/)
+ContextHandlerRef TextBodyPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
{
switch( aElementToken )
{
// Sequence
case A_TOKEN( prstTxWarp ): // CT_PresetTextShape
+ if( mpShapePtr )
+ {
+ const OptValue<OUString> sPrst = rAttribs.getString( XML_prst );
+ if( sPrst.has() )
+ {
+ mrTextBodyProp.msPrst = sPrst.get();
+ if( mrTextBodyProp.msPrst != "textNoShape" )
+ return new PresetTextShapeContext( *this, rAttribs,
+ *( mpShapePtr->getCustomShapeProperties() ) );
+ }
+ }
+ break;
+
case A_TOKEN( prot ): // CT_TextProtectionProperty
break;
diff --git a/oox/source/ppt/pptshapecontext.cxx b/oox/source/ppt/pptshapecontext.cxx
index c6807575d49a..0699923610b1 100644
--- a/oox/source/ppt/pptshapecontext.cxx
+++ b/oox/source/ppt/pptshapecontext.cxx
@@ -175,7 +175,7 @@ ContextHandlerRef PPTShapeContext::onCreateContext( sal_Int32 aElementToken, con
oox::drawingml::TextBodyPtr xTextBody( new oox::drawingml::TextBody( mpShapePtr->getTextBody() ) );
xTextBody->getTextProperties().maPropertyMap.setProperty( PROP_FontIndependentLineSpacing, true );
mpShapePtr->setTextBody( xTextBody );
- return new oox::drawingml::TextBodyContext( *this, *xTextBody );
+ return new oox::drawingml::TextBodyContext( *this, mpShapePtr );
}
case PPT_TOKEN( txXfrm ):
{
diff --git a/sd/qa/unit/data/pptx/tdf116350-texteffects.pptx b/sd/qa/unit/data/pptx/tdf116350-texteffects.pptx
new file mode 100644
index 000000000000..52a3fe000a9b
--- /dev/null
+++ b/sd/qa/unit/data/pptx/tdf116350-texteffects.pptx
Binary files differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 3f9ff8fffbc5..01873908cfdb 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -10,6 +10,7 @@
#include "sdmodeltestbase.hxx"
#include <Outliner.hxx>
#include <comphelper/propertysequence.hxx>
+#include <comphelper/sequence.hxx>
#include <svl/stritem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/outlobj.hxx>
@@ -151,6 +152,7 @@ public:
void testTdf118835();
void testTdf118768();
void testTdf118836();
+ void testTdf116350TextEffects();
CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
@@ -223,6 +225,7 @@ public:
CPPUNIT_TEST(testTdf118835);
CPPUNIT_TEST(testTdf118768);
CPPUNIT_TEST(testTdf118836);
+ CPPUNIT_TEST(testTdf116350TextEffects);
CPPUNIT_TEST_SUITE_END();
@@ -1788,6 +1791,53 @@ void SdOOXMLExportTest2::testTdf118836()
xDocShRef->DoClose();
}
+static inline double getAdjustmentValue( uno::Reference<beans::XPropertySet>& xSet )
+{
+ auto aGeomPropSeq = xSet->getPropertyValue( "CustomShapeGeometry" )
+ .get<uno::Sequence<beans::PropertyValue>>();
+ auto aGeomPropVec
+ = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(
+ aGeomPropSeq );
+
+ const OUString sName = "AdjustmentValues";
+ auto aIterator = std::find_if(
+ aGeomPropVec.begin(), aGeomPropVec.end(),
+ [sName]( const beans::PropertyValue& rValue ) { return rValue.Name == sName; } );
+
+ if (aIterator != aGeomPropVec.end())
+ {
+ uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment;
+ double fResult;
+ aIterator->Value >>= aAdjustment;
+ aAdjustment[0].Value >>= fResult;
+ return fResult;
+ }
+
+ return -1.0;
+}
+
+void SdOOXMLExportTest2::testTdf116350TextEffects()
+{
+ ::sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "sd/qa/unit/data/pptx/tdf116350-texteffects.pptx" ), PPTX );
+
+ // Default angle for ArchUp
+ uno::Reference<beans::XPropertySet> xShape0( getShapeFromPage( 0, 0, xDocShRef ) );
+ double fAdjust = getAdjustmentValue( xShape0 );
+ CPPUNIT_ASSERT_EQUAL( 180.0, fAdjust );
+
+ // Default angle for ArchDown
+ uno::Reference<beans::XPropertySet> xShape14( getShapeFromPage( 14, 0, xDocShRef ) );
+ fAdjust = getAdjustmentValue( xShape14 );
+ CPPUNIT_ASSERT_EQUAL( 0.0, fAdjust );
+
+ // Angle directly set
+ uno::Reference<beans::XPropertySet> xShape1( getShapeFromPage( 1, 0, xDocShRef ) );
+ fAdjust = getAdjustmentValue( xShape1 );
+ CPPUNIT_ASSERT_EQUAL( 213.25, fAdjust );
+
+ xDocShRef->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
CPPUNIT_PLUGIN_IMPLEMENT();