[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - include/oox oox/qa oox/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Wed Mar 4 09:54:23 UTC 2020
include/oox/vml/vmlshape.hxx | 4 ++++
include/oox/vml/vmlshapecontainer.hxx | 1 +
oox/qa/unit/data/group-spt202.docx |binary
oox/qa/unit/vml.cxx | 19 +++++++++++++++++++
oox/source/vml/vmlshape.cxx | 4 ++++
oox/source/vml/vmlshapecontainer.cxx | 5 +++++
oox/source/vml/vmlshapecontext.cxx | 21 ++++++++++++++++++++-
7 files changed, 53 insertions(+), 1 deletion(-)
New commits:
commit 7d210f5c9bf7db39f0043d8d218b337b9a78053d
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Mar 2 20:23:04 2020 +0100
Commit: Xisco Faulí <xiscofauli at libreoffice.org>
CommitDate: Wed Mar 4 10:53:52 2020 +0100
tdf#84399 VML import: map <v:shape o:spt="202"> to TextShape
This partially reverts commit 81f9fe3a14f0fc99afbfa7ce3a26a9c7855d0919
(fdo#74401 VML groupshape import: only handle v:rect as TextShape,
2014-03-19), which wanted to map triangles to custom shapes.
It was overlooked that we can have not only explicit rectangles and
custom shapes, but also <v:shape> elements which have their shape type
explicitly set to TextBox. The later is now again handled similar to
rectangles. This keeps the triangle case working, but fixes the <v:shape
o:spt="202"> case.
We need to make this decision while parsing the XML, so some rework is
needed to have earlier access to its container (group shape or draw
page) and also to its shape type.
(cherry picked from commit 198685ded79d64b21023ee85e9a15fa1b32705a0)
Conflicts:
include/oox/vml/vmlshapecontainer.hxx
Change-Id: I33a4b3cd03b0df5d93cffa19e7ea834113df2bdc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89876
Tested-by: Jenkins
Reviewed-by: Xisco Faulí <xiscofauli at libreoffice.org>
diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index dc4db50c27fe..2b3677df106d 100644
--- a/include/oox/vml/vmlshape.hxx
+++ b/include/oox/vml/vmlshape.hxx
@@ -264,6 +264,9 @@ public:
void convertFormatting(
const css::uno::Reference< css::drawing::XShape >& rxShape ) const;
+ void setContainer(ShapeContainer* pContainer);
+ ShapeContainer* getContainer() const;
+
protected:
explicit ShapeBase( Drawing& rDrawing );
@@ -284,6 +287,7 @@ protected:
protected:
ShapeModel maShapeModel; ///< The model structure containing shape data.
+ ShapeContainer* mpContainer = nullptr;
};
diff --git a/include/oox/vml/vmlshapecontainer.hxx b/include/oox/vml/vmlshapecontainer.hxx
index ff39d5f7212c..72fc9286536e 100644
--- a/include/oox/vml/vmlshapecontainer.hxx
+++ b/include/oox/vml/vmlshapecontainer.hxx
@@ -126,6 +126,7 @@ template< typename ShapeT >
std::shared_ptr<ShapeT> ShapeContainer::createShape()
{
std::shared_ptr< ShapeT > xShape( new ShapeT( mrDrawing ) );
+ xShape->setContainer(this);
maShapes.push_back( xShape );
return xShape;
}
diff --git a/oox/qa/unit/data/group-spt202.docx b/oox/qa/unit/data/group-spt202.docx
new file mode 100644
index 000000000000..14bf00b50ed5
Binary files /dev/null and b/oox/qa/unit/data/group-spt202.docx differ
diff --git a/oox/qa/unit/vml.cxx b/oox/qa/unit/vml.cxx
index ad4e9e229739..01539abdfbda 100644
--- a/oox/qa/unit/vml.cxx
+++ b/oox/qa/unit/vml.cxx
@@ -84,6 +84,25 @@ CPPUNIT_TEST_FIXTURE(OoxVmlTest, testLayoutFlowAltAlone)
CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, nWritingMode);
}
+CPPUNIT_TEST_FIXTURE(OoxVmlTest, testSpt202ShapeType)
+{
+ // Load a document with a groupshape, 2nd child is a <v:shape>, its type has o:spt set to 202
+ // (TextBox).
+ load("group-spt202.docx");
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(1), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: com.sun.star.drawing.TextShape
+ // - Actual : com.sun.star.drawing.CustomShape
+ // and then the size of the group shape was incorrect, e.g. its right edge was outside the page
+ // boundaries.
+ CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.TextShape"), xShape->getShapeType());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 0771d9ecda61..82cacfdcaf68 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -489,6 +489,10 @@ void ShapeBase::convertFormatting( const Reference< XShape >& rxShape ) const
}
}
+void ShapeBase::setContainer(ShapeContainer* pContainer) { mpContainer = pContainer; }
+
+ShapeContainer* ShapeBase::getContainer() const { return mpContainer; }
+
// protected ------------------------------------------------------------------
awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
index e8008a1f4638..bed4256c40e0 100644
--- a/oox/source/vml/vmlshapecontainer.cxx
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -79,6 +79,11 @@ void ShapeContainer::finalizeFragmentImport()
const ShapeType* ShapeContainer::getShapeTypeById( const OUString& rShapeId ) const
{
+ if (maTypesById.empty() && !maTypes.empty())
+ {
+ lclMapShapesById(const_cast<ShapeTypeMap&>(maTypesById), maTypes);
+ }
+
// search in own shape template list
if( const ShapeType* pType = maTypesById.get( rShapeId ).get() )
return pType;
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index 76953fe750e7..dd36fb521519 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -30,6 +30,7 @@
#include <oox/vml/vmltextboxcontext.hxx>
#include <osl/diagnose.h>
+#include <filter/msfilter/escherex.hxx>
namespace oox {
namespace vml {
@@ -478,17 +479,35 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const Attri
if( isRootElement() ) switch( nElement )
{
case VML_TOKEN( textbox ):
+ {
+ // Calculate the shape type: map both <rect> and <v:shape> with a textbox shape type to
+ // a TextShape.
+ sal_Int32 nShapeType = 0;
+ if (ShapeContainer* pShapeContainer = mrShape.getContainer())
+ {
+ OUString aType = mrShapeModel.maType;
+ if (!aType.isEmpty() && aType[0] == '#')
+ {
+ aType = aType.copy(1);
+ }
+ if (const ShapeType* pShapeType = pShapeContainer->getShapeTypeById(aType))
+ {
+ nShapeType = pShapeType->getTypeModel().moShapeType.get();
+ }
+ }
+
if (getParentElement() != VML_TOKEN( group ))
{
// Custom shape in Writer with a textbox are transformed into a frame
dynamic_cast<SimpleShape&>( mrShape ).setService(
"com.sun.star.text.TextFrame");
}
- else if (getCurrentElement() == VML_TOKEN(rect))
+ else if (getCurrentElement() == VML_TOKEN(rect) || nShapeType == ESCHER_ShpInst_TextBox)
// Transform only rectangles into a TextShape inside a groupshape.
dynamic_cast<SimpleShape&>(mrShape).setService("com.sun.star.drawing.TextShape");
return new TextBoxContext( *this, mrShapeModel.createTextBox(mrShape.getTypeModel()), rAttribs,
mrShape.getDrawing().getFilter().getGraphicHelper());
+ }
case VMLX_TOKEN( ClientData ):
return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs );
case VMLPPT_TOKEN( textdata ):
More information about the Libreoffice-commits
mailing list