summaryrefslogtreecommitdiff
path: root/oox/source/drawingml
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/drawingml')
-rw-r--r--oox/source/drawingml/presetgeometrynames.cxx108
-rw-r--r--oox/source/drawingml/shape.cxx185
-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
6 files changed, 338 insertions, 4 deletions
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 3aac4273fc4c..2a28ea06d0ec 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>
@@ -87,6 +91,8 @@
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+#include <svx/unoshape.hxx>
#include <vcl/wmf.hxx>
@@ -394,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,
@@ -1127,6 +1299,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 21cc6b329ed3..3abe2dee0adf 100644
--- a/oox/source/drawingml/shapecontext.cxx
+++ b/oox/source/drawingml/shapecontext.cxx
@@ -96,7 +96,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:
{
@@ -112,7 +112,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 ea985f6b78a0..84cf4d4b071b 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>
@@ -161,12 +162,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;