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 198685ded79d64b21023ee85e9a15fa1b32705a0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Mar 2 20:23:04 2020 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Mar 3 07:57:05 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.
    
    Change-Id: I33a4b3cd03b0df5d93cffa19e7ea834113df2bdc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89852
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index 5ec471299f3f..a4584cad2b7f 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 6be9020051c2..1b72c8a38f3b 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()
 {
     auto xShape = std::make_shared<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 833fc449d84c..b27876426956 100644
--- a/oox/qa/unit/vml.cxx
+++ b/oox/qa/unit/vml.cxx
@@ -72,6 +72,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 c28f9c44ca5d..3444c1cd2743 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -488,6 +488,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 beaac27ea153..d9aa7d9aab6b 100644
--- a/oox/source/vml/vmlshapecontainer.cxx
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -78,6 +78,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 d82d22ec2d7f..dbec50102fd1 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::vml {
 
@@ -477,17 +478,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 ):
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to