summaryrefslogtreecommitdiffstats
path: root/oox/source/shape
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /oox/source/shape
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'oox/source/shape')
-rw-r--r--oox/source/shape/LockedCanvasContext.cxx62
-rw-r--r--oox/source/shape/LockedCanvasContext.hxx40
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx629
-rw-r--r--oox/source/shape/ShapeContextHandler.hxx164
-rw-r--r--oox/source/shape/ShapeDrawingFragmentHandler.cxx48
-rw-r--r--oox/source/shape/ShapeDrawingFragmentHandler.hxx35
-rw-r--r--oox/source/shape/ShapeFilterBase.cxx145
-rw-r--r--oox/source/shape/WpgContext.cxx78
-rw-r--r--oox/source/shape/WpgContext.hxx40
-rw-r--r--oox/source/shape/WpsContext.cxx238
-rw-r--r--oox/source/shape/WpsContext.hxx56
11 files changed, 1535 insertions, 0 deletions
diff --git a/oox/source/shape/LockedCanvasContext.cxx b/oox/source/shape/LockedCanvasContext.cxx
new file mode 100644
index 000000000..0a56a42ed
--- /dev/null
+++ b/oox/source/shape/LockedCanvasContext.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "LockedCanvasContext.hxx"
+#include <sal/log.hxx>
+#include <oox/drawingml/shape.hxx>
+#include <oox/drawingml/shapecontext.hxx>
+#include <oox/drawingml/shapegroupcontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace com::sun::star;
+
+namespace oox::shape
+{
+LockedCanvasContext::LockedCanvasContext(FragmentHandler2 const& rParent)
+ : FragmentHandler2(rParent)
+{
+}
+
+LockedCanvasContext::~LockedCanvasContext() = default;
+
+::oox::core::ContextHandlerRef
+LockedCanvasContext::onCreateContext(sal_Int32 nElementToken,
+ const ::oox::AttributeList& /*rAttribs*/)
+{
+ switch (getBaseToken(nElementToken))
+ {
+ case XML_lockedCanvas:
+ case XML_nvGrpSpPr:
+ case XML_grpSpPr:
+ break;
+ case XML_sp:
+ {
+ oox::drawingml::ShapePtr pMasterShape;
+ mpShape = std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.CustomShape");
+ mpShape->setLockedCanvas(true);
+ return new oox::drawingml::ShapeContext(*this, pMasterShape, mpShape);
+ }
+ case XML_grpSp:
+ {
+ oox::drawingml::ShapePtr pMasterShape;
+ mpShape = std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape");
+ mpShape->setLockedCanvas(true);
+ return new oox::drawingml::ShapeGroupContext(*this, pMasterShape, mpShape);
+ }
+ default:
+ SAL_WARN("oox", "LockedCanvasContext::createFastChildContext: unhandled element:"
+ << getBaseToken(nElementToken));
+ break;
+ }
+ return nullptr;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/LockedCanvasContext.hxx b/oox/source/shape/LockedCanvasContext.hxx
new file mode 100644
index 000000000..68c8e27fa
--- /dev/null
+++ b/oox/source/shape/LockedCanvasContext.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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_SOURCE_SHAPE_LOCKEDCANVASCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_SHAPE_LOCKEDCANVASCONTEXT_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+
+namespace oox
+{
+namespace shape
+{
+/// Locked canvas is kind of a container for drawingml shapes: it can even contain group shapes.
+class LockedCanvasContext final : public oox::core::FragmentHandler2
+{
+public:
+ explicit LockedCanvasContext(oox::core::FragmentHandler2 const& rParent);
+ ~LockedCanvasContext() override;
+
+ oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElementToken,
+ const ::oox::AttributeList& rAttribs) override;
+
+ const oox::drawingml::ShapePtr& getShape() const { return mpShape; }
+
+private:
+ oox::drawingml::ShapePtr mpShape;
+};
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
new file mode 100644
index 000000000..44fc0af6c
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -0,0 +1,629 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
+
+#include "ShapeContextHandler.hxx"
+#include "ShapeDrawingFragmentHandler.hxx"
+#include "LockedCanvasContext.hxx"
+#include "WpsContext.hxx"
+#include "WpgContext.hxx"
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <oox/vml/vmldrawingfragment.hxx>
+#include <oox/vml/vmlshape.hxx>
+#include <oox/vml/vmlshapecontainer.hxx>
+#include <oox/shape/ShapeFilterBase.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/drawingml/theme.hxx>
+#include <oox/drawingml/themefragmenthandler.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+
+namespace oox::shape {
+using namespace core;
+using namespace drawingml;
+
+ShapeContextHandler::ShapeContextHandler(uno::Reference< uno::XComponentContext > const & context) :
+ mnStartToken(0)
+{
+ try
+ {
+ mxFilterBase.set( new ShapeFilterBase(context) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+ShapeContextHandler::~ShapeContextHandler()
+{
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const & ShapeContextHandler::getLockedCanvasContext(sal_Int32 nElement)
+{
+ if (!mxLockedCanvasContext.is())
+ {
+ FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
+
+ switch (nElement & 0xffff)
+ {
+ case XML_lockedCanvas:
+ mxLockedCanvasContext.set(static_cast<oox::core::ContextHandler*>(new LockedCanvasContext(*rFragmentHandler)));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return mxLockedCanvasContext;
+}
+
+/*
+ * This method creates new ChartGraphicDataContext Object.
+ */
+uno::Reference<xml::sax::XFastContextHandler> const & ShapeContextHandler::getChartShapeContext(sal_Int32 nElement)
+{
+ if (!mxChartShapeContext.is())
+ {
+ switch (nElement & 0xffff)
+ {
+ case XML_chart:
+ {
+ std::unique_ptr<ContextHandler2Helper> pFragmentHandler(
+ new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
+ mpShape = std::make_shared<Shape>("com.sun.star.drawing.OLE2Shape" );
+ mxChartShapeContext.set(new ChartGraphicDataContext(*pFragmentHandler, mpShape, true));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return mxChartShapeContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const & ShapeContextHandler::getWpsContext(sal_Int32 nStartElement, sal_Int32 nElement)
+{
+ if (!mxWpsContext.is())
+ {
+ FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
+ ShapePtr pMasterShape;
+
+ uno::Reference<drawing::XShape> xShape;
+ // No element happens in case of pretty-printed XML, bodyPr is the case when we are called again after <wps:txbx>.
+ if (!nElement || nElement == WPS_TOKEN(bodyPr))
+ // Assume that this is just a continuation of the previous shape.
+ xShape = mxSavedShape;
+
+ switch (getBaseToken(nStartElement))
+ {
+ case XML_wsp:
+ mxWpsContext.set(new WpsContext(
+ *rFragmentHandler,
+ xShape,
+ pMasterShape,
+ std::make_shared<oox::drawingml::Shape>(
+ "com.sun.star.drawing.CustomShape")));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return mxWpsContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const & ShapeContextHandler::getWpgContext(sal_Int32 nElement)
+{
+ if (!mxWpgContext.is())
+ {
+ FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
+
+ switch (getBaseToken(nElement))
+ {
+ case XML_wgp:
+ mxWpgContext.set(static_cast<oox::core::ContextHandler*>(new WpgContext(*rFragmentHandler)));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return mxWpgContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const &
+ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
+{
+ if (! mxGraphicShapeContext.is())
+ {
+ auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxFilterBase, msRelationFragmentPath);
+ ShapePtr pMasterShape;
+
+ switch (Element & 0xffff)
+ {
+ case XML_graphic:
+ mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
+ mxGraphicShapeContext.set
+ (new GraphicalObjectFrameContext(*pFragmentHandler, pMasterShape, mpShape, true));
+ break;
+ case XML_pic:
+ mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
+ mxGraphicShapeContext.set
+ (new GraphicShapeContext(*pFragmentHandler, pMasterShape, mpShape));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return mxGraphicShapeContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const &
+ShapeContextHandler::getDrawingShapeContext()
+{
+ if (!mxDrawingFragmentHandler.is())
+ {
+ mpDrawing = std::make_shared<oox::vml::Drawing>( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD );
+ mxDrawingFragmentHandler.set
+ (static_cast<ContextHandler *>
+ (new oox::vml::DrawingFragment
+ ( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
+ }
+ else
+ {
+ // Reset the handler if fragment path has changed
+ OUString sHandlerFragmentPath = dynamic_cast<ContextHandler&>(*mxDrawingFragmentHandler).getFragmentPath();
+ if ( msRelationFragmentPath != sHandlerFragmentPath )
+ {
+ mxDrawingFragmentHandler.clear();
+ mxDrawingFragmentHandler.set
+ (static_cast<ContextHandler *>
+ (new oox::vml::DrawingFragment
+ ( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
+ }
+ }
+ return mxDrawingFragmentHandler;
+}
+
+uno::Reference<xml::sax::XFastContextHandler> const &
+ShapeContextHandler::getDiagramShapeContext()
+{
+ if (!mxDiagramShapeContext.is())
+ {
+ auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxFilterBase, msRelationFragmentPath);
+ mpShape = std::make_shared<Shape>();
+ mxDiagramShapeContext.set(new DiagramGraphicDataContext(*pFragmentHandler, mpShape));
+ }
+
+ return mxDiagramShapeContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler>
+ShapeContextHandler::getContextHandler(sal_Int32 nElement)
+{
+ uno::Reference<xml::sax::XFastContextHandler> xResult;
+
+ switch (getNamespace( mnStartToken ))
+ {
+ case NMSP_doc:
+ case NMSP_vml:
+ xResult.set(getDrawingShapeContext());
+ break;
+ case NMSP_dmlDiagram:
+ xResult.set(getDiagramShapeContext());
+ break;
+ case NMSP_dmlLockedCanvas:
+ xResult.set(getLockedCanvasContext(mnStartToken));
+ break;
+ case NMSP_dmlChart:
+ xResult.set(getChartShapeContext(mnStartToken));
+ break;
+ case NMSP_wps:
+ xResult.set(getWpsContext(mnStartToken, nElement));
+ break;
+ case NMSP_wpg:
+ xResult.set(getWpgContext(mnStartToken));
+ break;
+ default:
+ xResult.set(getGraphicShapeContext(mnStartToken));
+ break;
+ }
+
+ return xResult;
+}
+
+// css::xml::sax::XFastContextHandler:
+void SAL_CALL ShapeContextHandler::startFastElement
+(::sal_Int32 Element,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+{
+ mxFilterBase->filter(maMediaDescriptor);
+
+ mpThemePtr = std::make_shared<Theme>();
+
+ if (Element == DGM_TOKEN(relIds) || Element == LC_TOKEN(lockedCanvas) || Element == C_TOKEN(chart) ||
+ Element == WPS_TOKEN(wsp) || Element == WPG_TOKEN(wgp) || Element == OOX_TOKEN(dmlPicture, pic))
+ {
+ // Parse the theme relation, if available; the diagram won't have colors without it.
+ if (!msRelationFragmentPath.isEmpty())
+ {
+ // Get Target for Type = "officeDocument" from _rels/.rels file
+ // aOfficeDocumentFragmentPath is pointing to "word/document.xml" for docx & to "ppt/presentation.xml" for pptx
+ FragmentHandlerRef rFragmentHandlerRef(new ShapeFragmentHandler(*mxFilterBase, "/"));
+ OUString aOfficeDocumentFragmentPath = rFragmentHandlerRef->getFragmentPathFromFirstTypeFromOfficeDoc( "officeDocument" );
+
+ // Get the theme DO NOT use msRelationFragmentPath for getting theme as for a document there is a single theme in document.xml.rels
+ // and the same is used by header and footer as well.
+ FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxFilterBase, aOfficeDocumentFragmentPath));
+ OUString aThemeFragmentPath = rFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( "theme" );
+
+ if(!aThemeFragmentPath.isEmpty())
+ {
+ uno::Reference<xml::sax::XFastSAXSerializable> xDoc(mxFilterBase->importFragment(aThemeFragmentPath), uno::UNO_QUERY_THROW);
+ mxFilterBase->importFragment(new ThemeFragmentHandler(*mxFilterBase, aThemeFragmentPath, *mpThemePtr ), xDoc);
+ ShapeFilterBase* pShapeFilterBase(dynamic_cast<ShapeFilterBase*>(mxFilterBase.get()));
+ if (pShapeFilterBase)
+ pShapeFilterBase->setCurrentTheme(mpThemePtr);
+ }
+ }
+
+ createFastChildContext(Element, Attribs);
+ }
+
+ // Entering VML block (startFastElement() is called for the outermost tag),
+ // handle possible recursion.
+ if ( getContextHandler() == getDrawingShapeContext() )
+ mpDrawing->getShapes().pushMark();
+
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->startFastElement(Element, Attribs);
+}
+
+void SAL_CALL ShapeContextHandler::startUnknownElement
+(const OUString & Namespace, const OUString & Name,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+{
+ if ( getContextHandler() == getDrawingShapeContext() )
+ mpDrawing->getShapes().pushMark();
+
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->startUnknownElement(Namespace, Name, Attribs);
+}
+
+void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->endFastElement(Element);
+ // In case a textbox is sent, and later we get additional properties for
+ // the textbox, then the wps context is not cleared, so do that here.
+ if (Element != (NMSP_wps | XML_wsp))
+ return;
+
+ uno::Reference<lang::XServiceInfo> xServiceInfo(mxSavedShape, uno::UNO_QUERY);
+ bool bTextFrame = xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.text.TextFrame");
+ bool bTextBox = false;
+ if (!bTextFrame)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(mxSavedShape, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ xPropertySet->getPropertyValue("TextBox") >>= bTextBox;
+ }
+ if (bTextFrame || bTextBox)
+ mxWpsContext.clear();
+ mxSavedShape.clear();
+}
+
+void SAL_CALL ShapeContextHandler::endUnknownElement
+(const OUString & Namespace,
+ const OUString & Name)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->endUnknownElement(Namespace, Name);
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ShapeContextHandler::createFastChildContext
+(::sal_Int32 Element,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xResult;
+ uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler(Element));
+
+ if (xContextHandler.is())
+ xResult.set(xContextHandler->createFastChildContext
+ (Element, Attribs));
+
+ return xResult;
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ShapeContextHandler::createUnknownChildContext
+(const OUString & Namespace,
+ const OUString & Name,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ return xContextHandler->createUnknownChildContext
+ (Namespace, Name, Attribs);
+
+ return uno::Reference< xml::sax::XFastContextHandler >();
+}
+
+void SAL_CALL ShapeContextHandler::characters(const OUString & aChars)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->characters(aChars);
+}
+
+// css::xml::sax::XFastShapeContextHandler:
+uno::Reference< drawing::XShape > SAL_CALL
+ShapeContextHandler::getShape()
+{
+ uno::Reference< drawing::XShape > xResult;
+ uno::Reference< drawing::XShapes > xShapes = mxDrawPage;
+
+ if (mxFilterBase.is() && xShapes.is())
+ {
+ if ( getContextHandler() == getDrawingShapeContext() )
+ {
+ mpDrawing->finalizeFragmentImport();
+ if( std::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() )
+ xResult = pShape->convertAndInsert( xShapes );
+ // Only now remove the recursion mark, because getShape() is called in writerfilter
+ // after endFastElement().
+ mpDrawing->getShapes().popMark();
+ }
+ else if (mxDiagramShapeContext.is())
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ if (mpShape->getExtDrawings().empty())
+ {
+ mpShape->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, mpShape->getFillProperties() );
+ xResult = mpShape->getXShape();
+ }
+ else
+ {
+ // Prerendered diagram output is available, then use that, and throw away the original result.
+ for (auto const& extDrawing : mpShape->getExtDrawings())
+ {
+ DiagramGraphicDataContext* pDiagramGraphicDataContext = dynamic_cast<DiagramGraphicDataContext*>(mxDiagramShapeContext.get());
+ if (!pDiagramGraphicDataContext)
+ break;
+ OUString aFragmentPath(pDiagramGraphicDataContext->getFragmentPathFromRelId(extDrawing));
+ oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
+ pShapePtr->setDiagramType();
+ mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr));
+ pShapePtr->setDiagramDoms(mpShape->getDiagramDoms());
+ pShapePtr->keepDiagramDrawing(*mxFilterBase, aFragmentPath);
+
+ if (!mpShape->getChildren().empty())
+ {
+ // first child is diagram background - we want to keep it, as drawingML fallback doesn't contain it
+ auto& aChildren = pShapePtr->getChildren();
+ ShapePtr pBackground = mpShape->getChildren().front();
+ aChildren.insert(aChildren.begin(), pBackground);
+ }
+
+ pShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() );
+ xResult = pShapePtr->getXShape();
+ }
+ mpShape.reset();
+ }
+ mxDiagramShapeContext.clear();
+ }
+ else if (mxLockedCanvasContext.is())
+ {
+ ShapePtr pShape = dynamic_cast<LockedCanvasContext&>(*mxLockedCanvasContext).getShape();
+ if (pShape)
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ pShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
+ xResult = pShape->getXShape();
+ mxLockedCanvasContext.clear();
+ }
+ }
+ //NMSP_dmlChart == getNamespace( mnStartToken ) check is introduced to make sure that
+ //mnStartToken is set as NMSP_dmlChart in setStartToken.
+ //Only in case it is set then only the below block of code for ChartShapeContext should be executed.
+ else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( mnStartToken )))
+ {
+ ChartGraphicDataContext* pChartGraphicDataContext = dynamic_cast<ChartGraphicDataContext*>(mxChartShapeContext.get());
+ if (pChartGraphicDataContext)
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ oox::drawingml::ShapePtr xShapePtr( pChartGraphicDataContext->getShape());
+ // See SwXTextDocument::createInstance(), ODF import uses the same hack.
+ xShapePtr->setServiceName("com.sun.star.drawing.temporaryForXMLImportOLE2Shape");
+ xShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, xShapePtr->getFillProperties() );
+ xResult = xShapePtr->getXShape();
+ }
+ mxChartShapeContext.clear();
+ }
+ else if (mxWpsContext.is())
+ {
+ ShapePtr pShape = dynamic_cast<WpsContext&>(*mxWpsContext).getShape();
+ if (pShape)
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ pShape->setPosition(maPosition);
+ pShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
+ xResult = pShape->getXShape();
+ mxSavedShape = xResult;
+ mxWpsContext.clear();
+ }
+ }
+ else if (mxWpgContext.is())
+ {
+ ShapePtr pShape = dynamic_cast<WpgContext&>(*mxWpgContext).getShape();
+ if (pShape)
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ pShape->setPosition(maPosition);
+ pShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
+ xResult = pShape->getXShape();
+ mxSavedShape = xResult;
+ mxWpgContext.clear();
+ }
+ }
+ else if (mpShape.get() != nullptr)
+ {
+ basegfx::B2DHomMatrix aTransformation;
+
+ if (maPosition.X != 0 || maPosition.Y != 0)
+ {
+ // We got a position from writerfilter/, store that in the shape, otherwise the
+ // position won't be set.
+ mpShape->setWps(true);
+ mpShape->setPosition(maPosition);
+ }
+
+ mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aTransformation, mpShape->getFillProperties() );
+ xResult.set(mpShape->getXShape());
+ mxGraphicShapeContext.clear( );
+ }
+ }
+
+ return xResult;
+}
+
+css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
+ShapeContextHandler::getDrawPage()
+{
+ return mxDrawPage;
+}
+
+void SAL_CALL ShapeContextHandler::setDrawPage
+(const css::uno::Reference< css::drawing::XDrawPage > & the_value)
+{
+ mxDrawPage = the_value;
+}
+
+css::uno::Reference< css::frame::XModel > SAL_CALL
+ShapeContextHandler::getModel()
+{
+ if( !mxFilterBase.is() )
+ throw uno::RuntimeException();
+ return mxFilterBase->getModel();
+}
+
+void SAL_CALL ShapeContextHandler::setModel
+(const css::uno::Reference< css::frame::XModel > & the_value)
+{
+ if( !mxFilterBase.is() )
+ throw uno::RuntimeException();
+ uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
+ mxFilterBase->setTargetDocument(xComp);
+}
+
+OUString SAL_CALL ShapeContextHandler::getRelationFragmentPath()
+{
+ return msRelationFragmentPath;
+}
+
+void SAL_CALL ShapeContextHandler::setRelationFragmentPath(const OUString & the_value)
+{
+ msRelationFragmentPath = the_value;
+}
+
+::sal_Int32 SAL_CALL ShapeContextHandler::getStartToken()
+{
+ return mnStartToken;
+}
+
+void SAL_CALL ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken )
+{
+ mnStartToken = _starttoken;
+}
+
+awt::Point SAL_CALL ShapeContextHandler::getPosition()
+{
+ return maPosition;
+}
+
+void SAL_CALL ShapeContextHandler::setPosition(const awt::Point& rPosition)
+{
+ maPosition = rPosition;
+}
+
+void SAL_CALL ShapeContextHandler::setDocumentProperties(const uno::Reference<document::XDocumentProperties>& xDocProps)
+{
+ mxDocumentProperties = xDocProps;
+ mxFilterBase->checkDocumentProperties(mxDocumentProperties);
+}
+
+uno::Reference<document::XDocumentProperties> SAL_CALL ShapeContextHandler::getDocumentProperties()
+{
+ return mxDocumentProperties;
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ShapeContextHandler::getMediaDescriptor()
+{
+ return maMediaDescriptor;
+}
+
+void SAL_CALL ShapeContextHandler::setMediaDescriptor(const uno::Sequence<beans::PropertyValue>& rMediaDescriptor)
+{
+ maMediaDescriptor = rMediaDescriptor;
+}
+
+OUString ShapeContextHandler::getImplementationName()
+{
+ return "com.sun.star.comp.oox.ShapeContextHandler";
+}
+
+uno::Sequence< OUString > ShapeContextHandler::getSupportedServiceNames()
+{
+ return { "com.sun.star.xml.sax.FastShapeContextHandler" };
+}
+
+sal_Bool SAL_CALL ShapeContextHandler::supportsService(const OUString & ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_oox_ShapeContextHandler_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new oox::shape::ShapeContextHandler(pCtx));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeContextHandler.hxx b/oox/source/shape/ShapeContextHandler.hxx
new file mode 100644
index 000000000..abda9c94a
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.hxx
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_OOX_SOURCE_SHAPE_SHAPECONTEXTHANDLER_HXX
+#define INCLUDED_OOX_SOURCE_SHAPE_SHAPECONTEXTHANDLER_HXX
+
+#include <memory>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/xml/sax/XFastShapeContextHandler.hpp>
+#include <oox/drawingml/graphicshapecontext.hxx>
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+namespace oox::shape {
+
+class ShapeFragmentHandler : public core::FragmentHandler2
+{
+public:
+ typedef std::shared_ptr<ShapeFragmentHandler> Pointer_t;
+
+ explicit ShapeFragmentHandler(core::XmlFilterBase& rFilter,
+ const OUString& rFragmentPath )
+ : FragmentHandler2(rFilter, rFragmentPath)
+ {
+ }
+};
+
+class ShapeContextHandler:
+ public ::cppu::WeakImplHelper< css::xml::sax::XFastShapeContextHandler,
+ css::lang::XServiceInfo >
+{
+public:
+ explicit ShapeContextHandler
+ (css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ virtual ~ShapeContextHandler() override;
+
+ // css::lang::XServiceInfo:
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService
+ (const OUString & ServiceName) override;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL
+ getSupportedServiceNames() override;
+
+ // css::xml::sax::XFastContextHandler:
+ virtual void SAL_CALL startFastElement
+ (::sal_Int32 Element,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs) override;
+
+ virtual void SAL_CALL startUnknownElement
+ (const OUString & Namespace,
+ const OUString & Name,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs) override;
+
+ virtual void SAL_CALL endFastElement(::sal_Int32 Element) override;
+
+ virtual void SAL_CALL endUnknownElement
+ (const OUString & Namespace,
+ const OUString & Name) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext
+ (::sal_Int32 Element,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createUnknownChildContext
+ (const OUString & Namespace,
+ const OUString & Name,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs) override;
+
+ virtual void SAL_CALL characters(const OUString & aChars) override;
+
+ // css::xml::sax::XFastShapeContextHandler:
+ virtual css::uno::Reference< css::drawing::XShape > SAL_CALL getShape() override;
+
+ virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL getDrawPage() override;
+
+ virtual void SAL_CALL setDrawPage
+ (const css::uno::Reference< css::drawing::XDrawPage > & the_value) override;
+
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override;
+
+ virtual void SAL_CALL setModel
+ (const css::uno::Reference< css::frame::XModel > & the_value) override;
+
+ virtual OUString SAL_CALL getRelationFragmentPath() override;
+ virtual void SAL_CALL setRelationFragmentPath
+ (const OUString & the_value) override;
+
+ virtual ::sal_Int32 SAL_CALL getStartToken() override;
+ virtual void SAL_CALL setStartToken( ::sal_Int32 _starttoken ) override;
+
+ virtual css::awt::Point SAL_CALL getPosition() override;
+ virtual void SAL_CALL setPosition(const css::awt::Point& rPosition) override;
+
+ virtual void SAL_CALL setDocumentProperties(const css::uno::Reference<css::document::XDocumentProperties>& xDocProps) override;
+ virtual css::uno::Reference<css::document::XDocumentProperties> SAL_CALL getDocumentProperties() override;
+ virtual css::uno::Sequence<css::beans::PropertyValue> SAL_CALL getMediaDescriptor() override;
+ virtual void SAL_CALL setMediaDescriptor(const css::uno::Sequence<css::beans::PropertyValue>& rMediaDescriptor) override;
+
+private:
+ ShapeContextHandler(ShapeContextHandler const &) = delete;
+ void operator =(ShapeContextHandler const &) = delete;
+
+ ::sal_uInt32 mnStartToken;
+ css::awt::Point maPosition;
+
+ drawingml::ShapePtr mpShape;
+ std::shared_ptr< vml::Drawing > mpDrawing;
+
+ typedef std::shared_ptr<drawingml::GraphicShapeContext>
+ GraphicShapeContextPtr;
+ css::uno::Reference<XFastContextHandler> mxDrawingFragmentHandler;
+ css::uno::Reference<XFastContextHandler> mxGraphicShapeContext;
+ css::uno::Reference<XFastContextHandler> mxDiagramShapeContext;
+ css::uno::Reference<XFastContextHandler> mxLockedCanvasContext;
+ css::uno::Reference<XFastContextHandler> mxWpsContext;
+ css::uno::Reference<css::drawing::XShape> mxSavedShape;
+ css::uno::Reference<XFastContextHandler> mxWpgContext;
+ css::uno::Reference<XFastContextHandler> mxChartShapeContext;
+ css::uno::Reference<css::document::XDocumentProperties> mxDocumentProperties;
+ css::uno::Sequence<css::beans::PropertyValue> maMediaDescriptor;
+
+ ::rtl::Reference< core::XmlFilterBase > mxFilterBase;
+ drawingml::ThemePtr mpThemePtr;
+ css::uno::Reference<css::drawing::XDrawPage> mxDrawPage;
+ OUString msRelationFragmentPath;
+
+ css::uno::Reference<XFastContextHandler> const & getGraphicShapeContext(::sal_Int32 Element);
+ css::uno::Reference<XFastContextHandler> const & getChartShapeContext(::sal_Int32 Element);
+ css::uno::Reference<XFastContextHandler> const & getDrawingShapeContext();
+ css::uno::Reference<XFastContextHandler> const & getDiagramShapeContext();
+ css::uno::Reference<XFastContextHandler> const & getLockedCanvasContext(sal_Int32 nElement);
+ css::uno::Reference<XFastContextHandler> const & getWpsContext(sal_Int32 nStartElement, sal_Int32 nElement);
+ css::uno::Reference<XFastContextHandler> const & getWpgContext(sal_Int32 nElement);
+ css::uno::Reference<XFastContextHandler> getContextHandler(sal_Int32 nElement = 0);
+};
+
+}
+
+#endif // INCLUDED_OOX_SOURCE_SHAPE_SHAPECONTEXTHANDLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeDrawingFragmentHandler.cxx b/oox/source/shape/ShapeDrawingFragmentHandler.cxx
new file mode 100644
index 000000000..3c65844f2
--- /dev/null
+++ b/oox/source/shape/ShapeDrawingFragmentHandler.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "ShapeDrawingFragmentHandler.hxx"
+
+#include <oox/drawingml/shapegroupcontext.hxx>
+#include <oox/token/namespaces.hxx>
+
+using namespace com::sun::star;
+
+namespace oox::shape {
+
+ShapeDrawingFragmentHandler::ShapeDrawingFragmentHandler(oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, oox::drawingml::ShapePtr const & pGroupShapePtr)
+ : FragmentHandler2(rFilter, rFragmentPath)
+ , mpGroupShapePtr(pGroupShapePtr)
+{
+}
+
+ShapeDrawingFragmentHandler::~ShapeDrawingFragmentHandler() throw()
+{
+}
+
+void SAL_CALL ShapeDrawingFragmentHandler::endDocument()
+{
+}
+
+::oox::core::ContextHandlerRef ShapeDrawingFragmentHandler::onCreateContext(sal_Int32 Element, const AttributeList& /*Attribs*/ )
+{
+ switch( Element )
+ {
+ case DSP_TOKEN( spTree ):
+ return new oox::drawingml::ShapeGroupContext(*this, oox::drawingml::ShapePtr(nullptr), mpGroupShapePtr);
+ default:
+ break;
+ }
+
+ return this;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeDrawingFragmentHandler.hxx b/oox/source/shape/ShapeDrawingFragmentHandler.hxx
new file mode 100644
index 000000000..53ce4d129
--- /dev/null
+++ b/oox/source/shape/ShapeDrawingFragmentHandler.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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_SOURCE_SHAPE_SHAPEDRAWINGFRAGMENTHANDLER_HXX
+#define INCLUDED_OOX_SOURCE_SHAPE_SHAPEDRAWINGFRAGMENTHANDLER_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+
+namespace oox::shape {
+
+/// Generic (i.e. not specific to PPTX) handler for the prerendered diagram parsing.
+class ShapeDrawingFragmentHandler : public oox::core::FragmentHandler2
+{
+public:
+ ShapeDrawingFragmentHandler(oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, oox::drawingml::ShapePtr const & pGroupShapePtr);
+ virtual ~ShapeDrawingFragmentHandler() throw() override;
+ virtual void SAL_CALL endDocument() override;
+ virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 Element, const AttributeList& rAttribs ) override;
+
+private:
+ oox::drawingml::ShapePtr mpGroupShapePtr;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx
new file mode 100644
index 000000000..6505b91a1
--- /dev/null
+++ b/oox/source/shape/ShapeFilterBase.cxx
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/shape/ShapeFilterBase.hxx>
+#include <oox/drawingml/chart/chartconverter.hxx>
+#include <oox/drawingml/themefragmenthandler.hxx>
+#include <oox/helper/graphichelper.hxx>
+#include <oox/ole/vbaproject.hxx>
+#include <oox/drawingml/theme.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
+
+namespace oox::shape {
+
+using namespace ::com::sun::star;
+
+ShapeFilterBase::ShapeFilterBase( const uno::Reference< uno::XComponentContext >& rxContext ) :
+ XmlFilterBase( rxContext ),
+ mxChartConv( std::make_shared<::oox::drawingml::chart::ChartConverter>() )
+{
+}
+
+ShapeFilterBase::~ShapeFilterBase()
+{
+}
+
+const ::oox::drawingml::Theme* ShapeFilterBase::getCurrentTheme() const
+{
+ return mpTheme.get();
+}
+
+void ShapeFilterBase::setCurrentTheme(const ::oox::drawingml::ThemePtr& pTheme)
+{
+ mpTheme = pTheme;
+}
+
+::oox::vml::Drawing* ShapeFilterBase::getVmlDrawing()
+{
+ return nullptr;
+}
+
+::oox::drawingml::table::TableStyleListPtr ShapeFilterBase::getTableStyles()
+{
+ return ::oox::drawingml::table::TableStyleListPtr();
+}
+
+::oox::drawingml::chart::ChartConverter* ShapeFilterBase::getChartConverter()
+{
+ return mxChartConv.get();
+}
+
+::oox::ole::VbaProject* ShapeFilterBase::implCreateVbaProject() const
+{
+ return new ::oox::ole::VbaProject( getComponentContext(), getModel(), "Writer" );
+}
+
+OUString ShapeFilterBase::getImplementationName()
+{
+ return OUString();
+}
+
+namespace {
+
+/// Graphic helper for shapes, that can manage color schemes.
+class ShapeGraphicHelper : public GraphicHelper
+{
+public:
+ explicit ShapeGraphicHelper( const ShapeFilterBase& rFilter );
+ virtual ::Color getSchemeColor( sal_Int32 nToken ) const override;
+private:
+ const ShapeFilterBase& mrFilter;
+};
+
+}
+
+ShapeGraphicHelper::ShapeGraphicHelper( const ShapeFilterBase& rFilter ) :
+ GraphicHelper( rFilter.getComponentContext(), rFilter.getTargetFrame(), rFilter.getStorage() ),
+ mrFilter( rFilter )
+{
+}
+
+::Color ShapeGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
+{
+ return mrFilter.getSchemeColor( nToken );
+}
+
+GraphicHelper* ShapeFilterBase::implCreateGraphicHelper() const
+{
+ return new ShapeGraphicHelper( *this );
+}
+
+::Color ShapeFilterBase::getSchemeColor( sal_Int32 nToken ) const
+{
+ ::Color nColor;
+
+ if (mpTheme)
+ mpTheme->getClrScheme().getColor( nToken, nColor );
+
+ return nColor;
+}
+
+void ShapeFilterBase::importTheme()
+{
+ drawingml::ThemePtr pTheme = std::make_shared<drawingml::Theme>();
+ uno::Reference<beans::XPropertySet> xPropSet(getModel(), uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ xPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ if (rProp.Name == "OOXTheme")
+ {
+ uno::Reference<xml::sax::XFastSAXSerializable> xDoc;
+ if (rProp.Value >>= xDoc)
+ {
+ rtl::Reference<core::FragmentHandler> xFragmentHandler(
+ new drawingml::ThemeFragmentHandler(*this, OUString(), *pTheme));
+ importFragment(xFragmentHandler, xDoc);
+ setCurrentTheme(pTheme);
+ }
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/WpgContext.cxx b/oox/source/shape/WpgContext.cxx
new file mode 100644
index 000000000..7896f8a4c
--- /dev/null
+++ b/oox/source/shape/WpgContext.cxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "WpgContext.hxx"
+#include <sal/log.hxx>
+#include <drawingml/shapepropertiescontext.hxx>
+#include <oox/drawingml/shapegroupcontext.hxx>
+#include <oox/drawingml/graphicshapecontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace com::sun::star;
+
+namespace oox::shape
+{
+WpgContext::WpgContext(FragmentHandler2 const& rParent)
+ : FragmentHandler2(rParent)
+{
+ mpShape = std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape");
+ mpShape->setWps(true);
+}
+
+WpgContext::~WpgContext() = default;
+
+oox::core::ContextHandlerRef WpgContext::onCreateContext(sal_Int32 nElementToken,
+ const oox::AttributeList& /*rAttribs*/)
+{
+ switch (getBaseToken(nElementToken))
+ {
+ case XML_wgp:
+ case XML_cNvGrpSpPr:
+ case XML_grpSpPr:
+ return new oox::drawingml::ShapePropertiesContext(*this, *mpShape);
+ case XML_wsp:
+ {
+ // Don't set default character height, Writer has its own way to set
+ // the default, and if we don't set it here, editeng properly inherits
+ // it.
+ oox::drawingml::ShapePtr pShape = std::make_shared<oox::drawingml::Shape>(
+ "com.sun.star.drawing.CustomShape", /*bDefaultHeight=*/false);
+ return new oox::drawingml::ShapeContext(*this, mpShape, pShape);
+ // return new oox::shape::WpsContext(*this, uno::Reference<drawing::XShape>(),
+ // mpShape, pShape);
+ }
+ case XML_pic:
+ return new oox::drawingml::GraphicShapeContext(
+ *this, mpShape,
+ std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GraphicObjectShape"));
+ case XML_grpSp:
+ {
+ return new oox::drawingml::ShapeGroupContext(
+ *this, mpShape,
+ std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape"));
+ }
+ case XML_graphicFrame:
+ {
+ auto pShape = std::make_shared<oox::drawingml::Shape>(
+ "com.sun.star.drawing.GraphicObjectShape");
+ pShape->setWps(true);
+ return new oox::drawingml::GraphicalObjectFrameContext(*this, mpShape, pShape,
+ /*bEmbedShapesInChart=*/true);
+ }
+ default:
+ SAL_WARN("oox", "WpgContext::createFastChildContext: unhandled element: "
+ << getBaseToken(nElementToken));
+ break;
+ }
+ return nullptr;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/WpgContext.hxx b/oox/source/shape/WpgContext.hxx
new file mode 100644
index 000000000..1b85cd4ec
--- /dev/null
+++ b/oox/source/shape/WpgContext.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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_SOURCE_SHAPE_WPGCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_SHAPE_WPGCONTEXT_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+
+namespace oox
+{
+namespace shape
+{
+/// Wpg is the drawingML equivalent of v:group.
+class WpgContext final : public oox::core::FragmentHandler2
+{
+public:
+ explicit WpgContext(oox::core::FragmentHandler2 const& rParent);
+ ~WpgContext() override;
+
+ oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElementToken,
+ const oox::AttributeList& rAttribs) override;
+
+ const oox::drawingml::ShapePtr& getShape() const { return mpShape; }
+
+private:
+ oox::drawingml::ShapePtr mpShape;
+};
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/WpsContext.cxx b/oox/source/shape/WpsContext.cxx
new file mode 100644
index 000000000..f78c38ff9
--- /dev/null
+++ b/oox/source/shape/WpsContext.cxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "WpsContext.hxx"
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <drawingml/customshapeproperties.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <svx/svdtrans.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/drawingml/shape.hxx>
+
+#include <optional>
+
+using namespace com::sun::star;
+
+namespace oox::shape
+{
+WpsContext::WpsContext(ContextHandler2Helper const& rParent, uno::Reference<drawing::XShape> xShape,
+ const drawingml::ShapePtr& pMasterShapePtr,
+ const drawingml::ShapePtr& pShapePtr)
+ : ShapeContext(rParent, pMasterShapePtr, pShapePtr)
+ , mxShape(std::move(xShape))
+{
+ mpShapePtr->setWps(true);
+}
+
+WpsContext::~WpsContext() = default;
+
+oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken,
+ const oox::AttributeList& rAttribs)
+{
+ switch (getBaseToken(nElementToken))
+ {
+ case XML_wsp:
+ case XML_cNvCnPr:
+ break;
+ case XML_bodyPr:
+ if (mxShape.is())
+ {
+ uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
+ sal_Int32 nVert = rAttribs.getToken(XML_vert, XML_horz);
+ if (nVert == XML_eaVert)
+ {
+ xPropertySet->setPropertyValue("TextWritingMode",
+ uno::makeAny(text::WritingMode_TB_RL));
+ }
+ else if (nVert != XML_horz)
+ {
+ // Get the existing rotation of the shape.
+ drawing::HomogenMatrix3 aMatrix;
+ xPropertySet->getPropertyValue("Transformation") >>= aMatrix;
+ basegfx::B2DHomMatrix aTransformation;
+ aTransformation.set(0, 0, aMatrix.Line1.Column1);
+ aTransformation.set(0, 1, aMatrix.Line1.Column2);
+ aTransformation.set(0, 2, aMatrix.Line1.Column3);
+ aTransformation.set(1, 0, aMatrix.Line1.Column1);
+ aTransformation.set(1, 1, aMatrix.Line2.Column2);
+ aTransformation.set(1, 2, aMatrix.Line3.Column3);
+ aTransformation.set(2, 0, aMatrix.Line1.Column1);
+ aTransformation.set(2, 1, aMatrix.Line2.Column2);
+ aTransformation.set(2, 2, aMatrix.Line3.Column3);
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate = 0;
+ double fShearX = 0;
+ aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // If the text is not rotated the way the shape wants it already, set the angle.
+ const sal_Int32 nRotation = nVert == XML_vert270 ? -270 : -90;
+ if (static_cast<long>(basegfx::rad2deg(fRotate))
+ != NormAngle36000(static_cast<long>(nRotation) * 100) / 100)
+ {
+ comphelper::SequenceAsHashMap aCustomShapeGeometry(
+ xPropertySet->getPropertyValue("CustomShapeGeometry"));
+ aCustomShapeGeometry["TextPreRotateAngle"] <<= nRotation;
+ xPropertySet->setPropertyValue(
+ "CustomShapeGeometry",
+ uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
+ }
+ }
+
+ if (xServiceInfo.is())
+ {
+ // Handle inset attributes for Writer textframes.
+ sal_Int32 aInsets[] = { XML_lIns, XML_tIns, XML_rIns, XML_bIns };
+ std::optional<sal_Int32> oInsets[4];
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(aInsets); ++i)
+ {
+ OptValue<OUString> oValue = rAttribs.getString(aInsets[i]);
+ if (oValue.has())
+ oInsets[i] = oox::drawingml::GetCoordinate(oValue.get());
+ else
+ // Defaults from the spec: left/right: 91440 EMU, top/bottom: 45720 EMU
+ oInsets[i]
+ = (aInsets[i] == XML_lIns || aInsets[i] == XML_rIns) ? 254 : 127;
+ }
+ const OUString aShapeProps[]
+ = { OUString("TextLeftDistance"), OUString("TextUpperDistance"),
+ OUString("TextRightDistance"), OUString("TextLowerDistance") };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(aShapeProps); ++i)
+ if (oInsets[i])
+ xPropertySet->setPropertyValue(aShapeProps[i],
+ uno::makeAny(*oInsets[i]));
+ }
+
+ // Handle text vertical adjustment inside a text frame
+ if (rAttribs.hasAttribute(XML_anchor))
+ {
+ drawing::TextVerticalAdjust eAdjust
+ = drawingml::GetTextVerticalAdjust(rAttribs.getToken(XML_anchor, XML_t));
+ xPropertySet->setPropertyValue("TextVerticalAdjust", uno::makeAny(eAdjust));
+ }
+
+ // Apply character color of the shape to the shape's textbox.
+ uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
+ uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
+ xTextCursor->gotoStart(false);
+ xTextCursor->gotoEnd(true);
+ const uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor,
+ uno::UNO_QUERY);
+ const beans::PropertyState ePropertyState
+ = xPropertyState->getPropertyState("CharColor");
+ if (ePropertyState == beans::PropertyState_DEFAULT_VALUE)
+ {
+ uno::Reference<beans::XPropertySet> xTextBoxPropertySet(xTextCursor,
+ uno::UNO_QUERY);
+ uno::Any xCharColor = xPropertySet->getPropertyValue("CharColor");
+ Color aColor = COL_AUTO;
+ if (xCharColor >>= aColor)
+ {
+ if (aColor != COL_AUTO)
+ xTextBoxPropertySet->setPropertyValue("CharColor", xCharColor);
+ }
+ }
+ return this;
+ }
+ break;
+ case XML_noAutofit:
+ case XML_spAutoFit:
+ {
+ uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
+ // We can't use oox::drawingml::TextBodyPropertiesContext here, as this
+ // is a child context of bodyPr, so the shape is already sent: we need
+ // to alter the XShape directly.
+ uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
+ xPropertySet->setPropertyValue(
+ "FrameIsAutomaticHeight",
+ uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
+ else
+ xPropertySet->setPropertyValue(
+ "TextAutoGrowHeight",
+ uno::makeAny(getBaseToken(nElementToken) == XML_spAutoFit));
+ }
+ }
+ break;
+ case XML_prstTxWarp:
+ if (rAttribs.hasAttribute(XML_prst))
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ oox::OptValue<OUString> presetShapeName = rAttribs.getString(XML_prst);
+ const OUString& preset = presetShapeName.get();
+ comphelper::SequenceAsHashMap aCustomShapeGeometry(
+ xPropertySet->getPropertyValue("CustomShapeGeometry"));
+ aCustomShapeGeometry["PresetTextWarp"] <<= preset;
+ xPropertySet->setPropertyValue(
+ "CustomShapeGeometry",
+ uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
+ }
+ }
+ break;
+ case XML_txbx:
+ {
+ mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true);
+ mpShapePtr->setTextBox(true);
+ //in case if the textbox is linked, save the attributes
+ //for further processing.
+ if (rAttribs.hasAttribute(XML_id))
+ {
+ OptValue<OUString> id = rAttribs.getString(XML_id);
+ if (id.has())
+ {
+ oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr;
+ linkedTxtBoxAttr.id = id.get().toInt32();
+ mpShapePtr->setTxbxHasLinkedTxtBox(true);
+ mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr);
+ }
+ }
+ return this;
+ }
+ break;
+ case XML_linkedTxbx:
+ {
+ //in case if the textbox is linked, save the attributes
+ //for further processing.
+ mpShapePtr->getCustomShapeProperties()->setShapeTypeOverride(true);
+ mpShapePtr->setTextBox(true);
+ OptValue<OUString> id = rAttribs.getString(XML_id);
+ OptValue<OUString> seq = rAttribs.getString(XML_seq);
+ if (id.has() && seq.has())
+ {
+ oox::drawingml::LinkedTxbxAttr linkedTxtBoxAttr;
+ linkedTxtBoxAttr.id = id.get().toInt32();
+ linkedTxtBoxAttr.seq = seq.get().toInt32();
+ mpShapePtr->setTxbxHasLinkedTxtBox(true);
+ mpShapePtr->setLinkedTxbxAttributes(linkedTxtBoxAttr);
+ }
+ }
+ break;
+ default:
+ return ShapeContext::onCreateContext(nElementToken, rAttribs);
+ }
+ return nullptr;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/WpsContext.hxx b/oox/source/shape/WpsContext.hxx
new file mode 100644
index 000000000..c5a6565a5
--- /dev/null
+++ b/oox/source/shape/WpsContext.hxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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_SOURCE_SHAPE_WPSCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_SHAPE_WPSCONTEXT_HXX
+
+#include <oox/core/contexthandler2.hxx>
+#include <oox/drawingml/shapecontext.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+
+namespace com
+{
+namespace sun
+{
+namespace star
+{
+namespace drawing
+{
+class XShape;
+}
+}
+}
+}
+
+namespace oox
+{
+namespace shape
+{
+/// Wps is the drawingML equivalent of v:shape.
+class WpsContext final : public oox::drawingml::ShapeContext
+{
+public:
+ WpsContext(oox::core::ContextHandler2Helper const& rParent,
+ css::uno::Reference<css::drawing::XShape> xShape,
+ oox::drawingml::ShapePtr const& pMasterShapePtr,
+ oox::drawingml::ShapePtr const& pShapePtr);
+ ~WpsContext() override;
+
+ oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElementToken,
+ const oox::AttributeList& rAttribs) override;
+
+private:
+ css::uno::Reference<css::drawing::XShape> mxShape;
+};
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */