[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - sw/qa writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Mar 8 20:22:29 UTC 2017


 sw/qa/extras/rtfimport/data/tdf104287.rtf      |   38 ++++++++++++++++++
 sw/qa/extras/rtfimport/rtfimport.cxx           |    8 +++
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   13 ++++++
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |    4 +
 writerfilter/source/rtftok/rtfvalue.cxx        |   52 ++++++++++++++++++-------
 writerfilter/source/rtftok/rtfvalue.hxx        |    6 ++
 6 files changed, 106 insertions(+), 15 deletions(-)

New commits:
commit 9a899023db876630b74493da588b4a5490f90894
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Mar 7 09:34:38 2017 +0100

    tdf#104287 RTF import: handle bitmap shapes inside tables
    
    Regression from commit 015fd55c94b7b650ed8e572cafaf3b0f903b01b9
    (tdf#96275 RTF import: fix anchor of shapes inside tables, 2016-05-10),
    the problem was that since shapes inside tables are now buffered, some
    previously hidden problems in the buffering became visible.
    
    For one, there was no code to make sure that a bitmap shape is not
    appended at the end of the buffer again when it gets re-played. For
    another, only the bitmap shape itself was buffered, not its size.
    
    (cherry picked from commit 8240be9170cc473506531dad2fda82469ae84443)
    
    Conflicts:
    	sw/qa/extras/rtfimport/rtfimport.cxx
    	writerfilter/source/rtftok/rtfvalue.cxx
    	writerfilter/source/rtftok/rtfvalue.hxx
    
    Change-Id: I04d65eb794ff6b160ef77af85479ba25ea5f8aa7
    Reviewed-on: https://gerrit.libreoffice.org/34953
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/qa/extras/rtfimport/data/tdf104287.rtf b/sw/qa/extras/rtfimport/data/tdf104287.rtf
new file mode 100644
index 0000000..2ec87e6
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/tdf104287.rtf
@@ -0,0 +1,38 @@
+{\rtf1\ansi\deff3\adeflang1025
+\deftab709
+\viewscale100
+\formshade\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
+{\*\ftnsep\chftnsep}
+\trowd\trql\ltrrow\trpaddft3\trpaddt0\trpaddfl3\trpaddl0\trpaddfb3\trpaddb0\trpaddfr3\trpaddr0\clbrdrt\brdrhair\brdrw1\brdrcf1\clpadfl3\clpadl55\clbrdrl\brdrhair\brdrw1\brdrcf1\clpadft3\clpadt55\clbrdrb\brdrhair\brdrw1\brdrcf1\clpadfb3\clpadb55\clbrdrr\brdrhair\brdrw1\brdrcf1\clpadfr3\clpadr55\cellx9638\shpwr2\shpwrk3\shpbypara\shpbyignore\shptop0\shpbxcolumn\shpbxignore\shpleft0\pgndec\pard\plain \s20\noline\intbl\rtlch \ltrch\loch
+{\*\flymaincnt5\flyanchor0\flycntnt}
+{\shp
+{\*\shpinst\shpwr2\shpwrk3\shpbypara\shpbyignore\shptop0\shpbottom6332\shpbxcolumn\shpbxignore\shpleft0\shpright9528
+{\sp
+{\sn shapeType}
+{\sv 75}
+}
+{\sp
+{\sn wzDescription}
+{\sv }
+}
+{\sp
+{\sn wzName}
+{\sv }
+}
+{\sp
+{\sn pib}
+{\sv 
+{\pict\picscalex63\picscaley63\piccropl0\piccropr0\piccropt0\piccropb0\picw1002\pich666\picwgoal15030\pichgoal9990\pngblip
+{\*\blipuid ebd28c5d3cbcfd4779e8e481da18cc69}
+89504e470d0a1a0a0000000d4948445200000010000000100802000000909168360000015049444154789c9592c14a02511486bf99714ccb322d7521140541cb
+6a11448b164150fb8a363d41f4083d40cba0655044d0a637a837682fd1a6a2488b10b23475bcb77b671c491dc1cee23077e67cf7fcff39139252f29f08b59e3e
+1dae8b4c45998ff501a82e070f5cbd3366733acb5c6fa609fc0872651236df0deeca7d002a6cc33d1b941a146ab49ca937e37610e0c590c5c92b67f926a07243
+b293613f8b1108a8a84aadb01575c9799edd0c895010a0ae71048e77b99b6a92e53861a387a48a6033c5d208c297a43ca8a3697601d217b010632dd9a9f34be0
+9968021698bea4c76ab72f5dd0d6216c3211e1bec2a0c5e59bce9303baa770c7bd38aca7d729692bcd4d512b53bb3b7cc2f45dd604ab098e67b499366025ce5e
+96a317fd2162e2d76bbbb725bdcd80b12a603aca4581e7aade97e14ec2916ca719ed96e4c54692f5241f755de7019641eacfaff10b469261dc6a800dd30000000049454e44ae426082}
+}
+}
+}
+}
+\cell\row\pard\pard\plain \s0\widctlpar\hyphpar0\cf0\kerning1\dbch\af8\langfe2052\dbch\af6\afs24\alang1081\loch\f3\hich\af3\fs24\lang1043\rtlch \ltrch\loch
+\par }
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 54e4758..1b9a2cc 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -2738,6 +2738,14 @@ DECLARE_RTFIMPORT_TEST(testTdf104744, "tdf104744.rtf")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1270), getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
 }
 
+DECLARE_RTFIMPORT_TEST(testTdf104287, "tdf104287.rtf")
+{
+    uno::Reference<text::XTextContent> xShape(getShape(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xShape.is());
+    // This failed, the bitmap had no valid anchor.
+    CPPUNIT_ASSERT(xShape->getAnchor().is());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 19bc159..07ecb5f 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -1530,7 +1530,14 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer,
         else if (std::get<0>(aTuple) == BUFFER_STARTSHAPE)
             m_pSdrImport->resolve(std::get<1>(aTuple)->getShape(), false, RTFSdrImport::SHAPE);
         else if (std::get<0>(aTuple) == BUFFER_RESOLVESHAPE)
+        {
+            // Make sure there is no current buffer while replaying the shape,
+            // otherwise it gets re-buffered.
+            RTFBuffer_t* pCurrentBuffer = m_aStates.top().pCurrentBuffer;
+            m_aStates.top().pCurrentBuffer = nullptr;
             m_pSdrImport->resolve(std::get<1>(aTuple)->getShape(), true, RTFSdrImport::SHAPE);
+            m_aStates.top().pCurrentBuffer = pCurrentBuffer;
+        }
         else if (std::get<0>(aTuple) == BUFFER_ENDSHAPE)
             m_pSdrImport->close();
         else if (std::get<0>(aTuple) == BUFFER_RESOLVESUBSTREAM)
@@ -1541,6 +1548,8 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer,
             OUString aCustomMark = rAttributes.find(2)->getString();
             resolveSubstream(nPos, nId, aCustomMark);
         }
+        else if (std::get<0>(aTuple) == BUFFER_PICTURE)
+            m_aStates.top().aPicture = std::get<1>(aTuple)->getPicture();
         else
             assert(false);
     }
@@ -2085,6 +2094,10 @@ RTFError RTFDocumentImpl::popState()
             else
             {
                 // Shape inside table: buffer the import to have correct anchor position.
+                // Also buffer the RTFPicture of the state stack as it contains
+                // the shape size.
+                auto pPictureValue = std::make_shared<RTFValue>(m_aStates.top().aPicture);
+                m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_PICTURE, pPictureValue, nullptr));
                 auto pValue = std::make_shared<RTFValue>(m_aStates.top().aShape);
                 m_aStates.top().pCurrentBuffer->push_back(Buf_t(BUFFER_RESOLVESHAPE, pValue, nullptr));
             }
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 09905dc..bb79a6e 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -59,7 +59,9 @@ enum RTFBufferTypes
     /// Imports a shape.
     BUFFER_RESOLVESHAPE,
     BUFFER_ENDSHAPE,
-    BUFFER_RESOLVESUBSTREAM
+    BUFFER_RESOLVESUBSTREAM,
+    /// Restores RTFParserState::aPicture.
+    BUFFER_PICTURE
 };
 
 /// Form field types
diff --git a/writerfilter/source/rtftok/rtfvalue.cxx b/writerfilter/source/rtftok/rtfvalue.cxx
index dbfe14c..4814e88 100644
--- a/writerfilter/source/rtftok/rtfvalue.cxx
+++ b/writerfilter/source/rtftok/rtfvalue.cxx
@@ -24,7 +24,8 @@ RTFValue::RTFValue(int nValue, const OUString& sValue,
                    uno::Reference<io::XInputStream> const& xStream,
                    uno::Reference<embed::XEmbeddedObject> const& xObject,
                    bool bForceString,
-                   const RTFShape& aShape)
+                   const RTFShape& aShape,
+                   const RTFPicture& rPicture)
     : m_nValue(nValue),
       m_sValue(sValue),
       m_pAttributes(std::make_shared<RTFSprms>(rAttributes)),
@@ -33,7 +34,8 @@ RTFValue::RTFValue(int nValue, const OUString& sValue,
       m_xStream(xStream),
       m_xObject(xObject),
       m_bForceString(bForceString),
-      m_pShape(std::make_shared<RTFShape>(aShape))
+      m_pShape(std::make_shared<RTFShape>(aShape)),
+      m_pPicture(std::make_shared<RTFPicture>(rPicture))
 {
 }
 
@@ -46,7 +48,8 @@ RTFValue::RTFValue()
       m_xStream(),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -58,7 +61,8 @@ RTFValue::RTFValue(int nValue)
       m_xShape(),
       m_xStream(),
       m_xObject(),
-      m_bForceString(false)
+      m_bForceString(false),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
     m_pShape.reset(new RTFShape());
 }
@@ -72,7 +76,8 @@ RTFValue::RTFValue(const OUString& sValue, bool bForce)
       m_xStream(),
       m_xObject(),
       m_bForceString(bForce),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -85,7 +90,8 @@ RTFValue::RTFValue(RTFSprms rAttributes)
       m_xStream(),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -98,7 +104,8 @@ RTFValue::RTFValue(RTFSprms rAttributes, RTFSprms rSprms)
       m_xStream(),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -111,7 +118,8 @@ RTFValue::RTFValue(uno::Reference<drawing::XShape> const& xShape)
       m_xStream(),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -124,7 +132,8 @@ RTFValue::RTFValue(uno::Reference<io::XInputStream> const& xStream)
       m_xStream(xStream),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -137,7 +146,8 @@ RTFValue::RTFValue(uno::Reference<embed::XEmbeddedObject> const& xObject)
       m_xStream(),
       m_xObject(xObject),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>())
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>())
 {
 }
 
@@ -150,7 +160,18 @@ RTFValue::RTFValue(const RTFShape& aShape)
       m_xStream(),
       m_xObject(),
       m_bForceString(false),
-      m_pShape(std::make_shared<RTFShape>(aShape))
+      m_pShape(std::make_shared<RTFShape>(aShape)),
+      m_pPicture(std::make_shared<RTFPicture>())
+{
+}
+
+RTFValue::RTFValue(const RTFPicture& rPicture)
+    : m_nValue(),
+      m_pAttributes(std::make_shared<RTFSprms>()),
+      m_pSprms(std::make_shared<RTFSprms>()),
+      m_bForceString(false),
+      m_pShape(std::make_shared<RTFShape>()),
+      m_pPicture(std::make_shared<RTFPicture>(rPicture))
 {
 }
 
@@ -195,6 +216,11 @@ RTFShape& RTFValue::getShape() const
     return *m_pShape;
 }
 
+RTFPicture& RTFValue::getPicture() const
+{
+    return *m_pPicture;
+}
+
 writerfilter::Reference<Properties>::Pointer_t RTFValue::getProperties()
 {
     return std::make_shared<RTFReferenceProperties>(*m_pAttributes, *m_pSprms);
@@ -217,12 +243,12 @@ std::string RTFValue::toString() const
 
 RTFValue* RTFValue::Clone()
 {
-    return new RTFValue(m_nValue, m_sValue, *m_pAttributes, *m_pSprms, m_xShape, m_xStream, m_xObject, m_bForceString, *m_pShape);
+    return new RTFValue(m_nValue, m_sValue, *m_pAttributes, *m_pSprms, m_xShape, m_xStream, m_xObject, m_bForceString, *m_pShape, *m_pPicture);
 }
 
 RTFValue* RTFValue::CloneWithSprms(RTFSprms const& rAttributes, RTFSprms const& rSprms)
 {
-    return new RTFValue(m_nValue, m_sValue, rAttributes, rSprms, m_xShape, m_xStream, m_xObject, m_bForceString, *m_pShape);
+    return new RTFValue(m_nValue, m_sValue, rAttributes, rSprms, m_xShape, m_xStream, m_xObject, m_bForceString, *m_pShape, *m_pPicture);
 }
 
 bool RTFValue::equals(RTFValue& rOther)
diff --git a/writerfilter/source/rtftok/rtfvalue.hxx b/writerfilter/source/rtftok/rtfvalue.hxx
index eeb9730..6892581 100644
--- a/writerfilter/source/rtftok/rtfvalue.hxx
+++ b/writerfilter/source/rtftok/rtfvalue.hxx
@@ -20,6 +20,7 @@ namespace rtftok
 {
 class RTFSprms;
 class RTFShape;
+class RTFPicture;
 /// Value of an RTF keyword
 class RTFValue
     : public Value
@@ -30,7 +31,7 @@ public:
              css::uno::Reference<css::drawing::XShape> const& xShape,
              css::uno::Reference<css::io::XInputStream> const& xStream,
              css::uno::Reference<css::embed::XEmbeddedObject> const& xObject,
-             bool bForceString, const RTFShape& aShape);
+             bool bForceString, const RTFShape& aShape, const RTFPicture& rPicture);
     RTFValue();
     RTFValue(int nValue);
     RTFValue(const OUString& sValue, bool bForce = false);
@@ -40,6 +41,7 @@ public:
     RTFValue(css::uno::Reference<css::io::XInputStream> const& xStream);
     RTFValue(css::uno::Reference<css::embed::XEmbeddedObject> const& xObject);
     RTFValue(const RTFShape& aShape);
+    RTFValue(const RTFPicture& rPicture);
     virtual ~RTFValue() override;
     void setString(const OUString& sValue);
     virtual int getInt() const override;
@@ -55,6 +57,7 @@ public:
     RTFSprms& getAttributes();
     RTFSprms& getSprms();
     RTFShape& getShape() const;
+    RTFPicture& getPicture() const;
     bool equals(RTFValue& rOther);
 private:
     RTFValue& operator=(RTFValue const& rOther) = delete;
@@ -67,6 +70,7 @@ private:
     css::uno::Reference<css::embed::XEmbeddedObject> m_xObject;
     bool m_bForceString;
     std::shared_ptr<RTFShape> m_pShape;
+    std::shared_ptr<RTFPicture> m_pPicture;
 };
 } // namespace rtftok
 } // namespace writerfilter


More information about the Libreoffice-commits mailing list