[Libreoffice-commits] .: 3 commits - sw/qa writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Nov 30 08:25:26 PST 2012


 sw/qa/extras/rtfimport/data/fdo57708.rtf       |    8 ++
 sw/qa/extras/rtfimport/rtfimport.cxx           |   12 ++++
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   70 +++++++++++++++----------
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |   13 +++-
 4 files changed, 73 insertions(+), 30 deletions(-)

New commits:
commit 7baca04727fbd3297c6e4b9815bf2a4695175e2e
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Nov 30 17:15:35 2012 +0100

    fdo#57708 testcase
    
    Change-Id: I5064cb9bb9700483eac4d56a56e671a392e82f73

diff --git a/sw/qa/extras/rtfimport/data/fdo57708.rtf b/sw/qa/extras/rtfimport/data/fdo57708.rtf
new file mode 100644
index 0000000..54a7579
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo57708.rtf
@@ -0,0 +1,8 @@
+{\rtf1\ansi\ansicpg1250\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset238 Metrostyle Extended;}}{\colortbl;\red0\green0\blue0;}{\info{\title }{\author Crystal Reports}{\doccomm Powered By Crystal}{\company Crystal Decisions}}{\*\userprops {\propname Business Objects Context Information}\proptype30{\staticval 01734361CD07C3C85B968AA4B2781C480C308DEB5E1F83247788228D3179576779474C0EDA07FA11789515F5C58418E566CFBE6A992AA227B056A18BF687A22CF4C7A2A60E137F6E64ADB5B69ED3464CA2298397B1C63A46E7CA415DF52DCCA4B3EE086B2778F5C67ADA7979DE0AB40BE865BD20C51228AC3938C7268BEB053}{\propname Business Objects Context Information1}\proptype30{\staticval 196223CE7A2CA417EF871437DC7F0AFC626}}
+\paperw11904\paperh16834\margl1416\margr849\margt849\margb849\gutter0\windowctrl\ftnbj\viewkind1\viewscale100\sectd\linex0\sbknone
+\sect {\shp{\*\shpinst\shpleft1416\shptop879\shpright2719\shpbottom2138\shpfhdr0\shpbxpage\shpbypage\shpwr3\shpwrk0\shpfblwtxt1{\sp{\sn txflTextFlow}{\sv 0}}{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fBehindDocument}{\sv 1}}{\sp{\sn fLockAspectRatio}{\sv 0}}{\sp{\sn fPreferRelativeResize}{\sv 0}}{\sp{\sn pib}{\sv {\pict\wmetafile6\picw1303\pich1259\picwgoal1303\pichgoal1259\picscalex100\picscaley100 89504e470d0a1a0a0000000d4948445200000010000000100802000000909168360000015049444154789c9592c14a02511486bf99714ccb322d7521140541cb
+6a11448b164150fb8a363d41f4083d40cba0655044d0a637a837682fd1a6a2488b10b23475bcb77b671c491dc1cee23077e67cf7fcff39139252f29f08b59e3e
+1dae8b4c45998ff501a82e070f5cbd3366733acb5c6fa609fc0872651236df0deeca7d002a6cc33d1b941a146ab49ca937e37610e0c590c5c92b67f926a07243
+b293613f8b1108a8a84aadb01575c9799edd0c895010a0ae71048e77b99b6a92e53861a387a48a6033c5d208c297a43ca8a3697601d217b010632dd9a9f34be0
+9968021698bea4c76ab72f5dd0d6216c3211e1bec2a0c5e59bce9303baa770c7bd38aca7d729692bcd4d512b53bb3b7cc2f45dd604ab098e67b499366025ce5e
+96a317fd2162e2d76bbbb725bdcd80b12a603aca4581e7aade97e14ec2916ca719ed96e4c54692f5241f755de7019641eacfaff10b469261dc6a800dd30000000049454e44ae426082}}}}}{\pard \pvpg\phpg\posx2969\posy1070\absw7935\absh-423\qc\vertalt\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920{\ltrch\f0 \b\i0\ul0\strike0\fs35 \cf1 PM1 TEST\par}}}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index a201c36..7853fc3 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -126,6 +126,7 @@ public:
     void testFdo52989();
     void testFdo48442();
     void testFdo55525();
+    void testFdo57708();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -202,6 +203,7 @@ void Test::run()
         {"fdo52989.rtf", &Test::testFdo52989},
         {"fdo48442.rtf", &Test::testFdo48442},
         {"fdo55525.rtf", &Test::testFdo55525},
+        {"fdo57708.rtf", &Test::testFdo57708},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -929,6 +931,16 @@ void Test::testFdo55525()
     CPPUNIT_ASSERT_EQUAL(sal_Int16(1016), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators")[0].Position);
 }
 
+void Test::testFdo57708()
+{
+    // There were two issues: the doc was of 2 pages and the picture was missing.
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
+    // Two objects: a picture and a textframe.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xDraws->getCount());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 8063e36115a11ddf3db05928db9287947beee74d
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Nov 30 16:32:56 2012 +0100

    fdo#57708 fix RTF import of pictures right before text frames
    
    Change-Id: Ibfeaadd5b48fd48c2c1f20de5dc272d9a326bfc4

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5a2f9b6..9c988d7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -274,7 +274,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     m_aHexBuffer(),
     m_bIgnoreNextContSectBreak(false),
     m_bNeedSect(true),
-    m_bWasInFrame(false)
+    m_bWasInFrame(false),
+    m_bHadPicture(false)
 {
     OSL_ASSERT(xInputStream.is());
     m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
@@ -497,6 +498,8 @@ void RTFDocumentImpl::parBreak()
     Mapper().endCharacterGroup();
     Mapper().endParagraphGroup();
 
+    m_bHadPicture = false;
+
     // start new one
     Mapper().startParagraphGroup();
 }
@@ -813,6 +816,8 @@ int RTFDocumentImpl::resolvePict(bool bInline)
         m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     }
 
+    // Make sure we don't loose these properties with a too early reset.
+    m_bHadPicture = true;
     return 0;
 }
 
@@ -2055,6 +2060,8 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
             }
             break;
         case RTF_PARD:
+            if (m_bHadPicture)
+                dispatchSymbol(RTF_PAR);
             m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
             m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
             m_aStates.top().resetFrame();
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 7147fa7..fad32e6 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -587,6 +587,8 @@ namespace writerfilter {
                 bool m_bNeedSect;
                 /// If aFrame.inFrame() was true in the previous state.
                 bool m_bWasInFrame;
+                /// A picture was seen in the current paragraph.
+                bool m_bHadPicture;
         };
     } // namespace rtftok
 } // namespace writerfilter
commit b836bf389d1150c9cafbb0aefa641af2316e536c
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Nov 30 15:33:52 2012 +0100

    fdo#57708 fix fake page break problem during RTF import
    
    The core of this change is: so far the continous section break at the
    end of the document was sent as a normal section break. This was
    introduced in commit 892d33c8d5033b4f8f7889bf91d257f55adf0e1f, probably
    as a workaround (sadly it's not documented and I no longer remember).
    Don't do this, since it causes additional page breaks during import.
    Instead, fix properly whatever was broken after getting rid of this
    workaround.
    
    Change-Id: I28c372d539c150fe21ff9db31209f9935a5e9063

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index d1888dc..5a2f9b6 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -272,7 +272,9 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     m_bIsInFrame(false),
     m_aUnicodeBuffer(),
     m_aHexBuffer(),
-    m_bDeferredContSectBreak(false)
+    m_bIgnoreNextContSectBreak(false),
+    m_bNeedSect(true),
+    m_bWasInFrame(false)
 {
     OSL_ASSERT(xInputStream.is());
     m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
@@ -399,6 +401,11 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
     m_bNeedPar = bNeedPar;
 }
 
+void RTFDocumentImpl::setNeedSect(bool bNeedSect)
+{
+    m_bNeedSect = bNeedSect;
+}
+
 writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
 {
     int nStyle = m_aStates.top().nCurrentStyleIndex;
@@ -496,6 +503,8 @@ void RTFDocumentImpl::parBreak()
 
 void RTFDocumentImpl::sectBreak(bool bFinal = false)
 {
+    SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
+    bool bNeedSect = m_bNeedSect;
     // If there is no paragraph in this section, then insert a dummy one, as required by Writer
     if (m_bNeedPar)
         dispatchSymbol(RTF_PAR);
@@ -512,10 +521,15 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
         resolveSubstream(aPair.second, aPair.first);
     }
 
-    RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
-    // In case the last section is a continous one, we don't need to output a section break.
-    if (bFinal && pBreak.get() && !pBreak->getInt())
-        m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
+    // Normally a section break at the end of the doc is necessary. Unless the
+    // last control word in the document is a section break itself.
+    if (!bNeedSect)
+    {
+        RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
+        // In case the last section is a continous one, we don't need to output a section break.
+        if (bFinal && pBreak.get() && !pBreak->getInt())
+            m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
+    }
 
     // Section properties are a paragraph sprm.
     RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms));
@@ -536,6 +550,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
         Mapper().startParagraphGroup();
     }
     m_bNeedPar = true;
+    m_bNeedSect = false;
 }
 
 void RTFDocumentImpl::seek(sal_uInt32 nPos)
@@ -1126,7 +1141,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
 int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
 {
     checkUnicode();
-    checkDeferredContSectBreak();
+    setNeedSect();
     RTFSkipDestination aSkip(*this);
     switch (nKeyword)
     {
@@ -1551,7 +1566,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
 {
     if (nKeyword != RTF_HEXCHAR)
         checkUnicode();
-    checkDeferredContSectBreak();
+    setNeedSect();
     RTFSkipDestination aSkip(*this);
     sal_uInt8 cCh = 0;
 
@@ -1609,13 +1624,8 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
             break;
         case RTF_SECT:
             {
-                RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
-                if (pBreak.get() && !pBreak->getInt())
-                {
-                    // This is a continous section break, don't send it yet.
-                    // It's possible that we'll have nothing after this token, and then we should ignore it.
-                    m_bDeferredContSectBreak = true;
-                }
+                if (m_bIgnoreNextContSectBreak)
+                    m_bIgnoreNextContSectBreak = false;
                 else
                     sectBreak();
             }
@@ -1759,9 +1769,17 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
                 if (pBreak.get() && !pBreak->getInt())
                 {
+                    if (m_bWasInFrame)
+                    {
+                        dispatchSymbol(RTF_PAR);
+                        m_bWasInFrame = false;
+                    }
                     dispatchFlag(RTF_SBKPAGE);
                     sectBreak();
                     dispatchFlag(RTF_SBKNONE);
+                    if (m_bNeedPar)
+                        dispatchSymbol(RTF_PAR);
+                    m_bIgnoreNextContSectBreak = true;
                 }
                 else
                 {
@@ -1792,7 +1810,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
 int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 {
     checkUnicode();
-    checkDeferredContSectBreak();
+    setNeedSect();
     RTFSkipDestination aSkip(*this);
     int nParam = -1;
     int nSprm = -1;
@@ -2474,7 +2492,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
 {
     checkUnicode(nKeyword != RTF_U, true);
-    checkDeferredContSectBreak();
+    setNeedSect();
     RTFSkipDestination aSkip(*this);
     int nSprm = 0;
     RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
@@ -3282,7 +3300,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
 int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
 {
     checkUnicode();
-    checkDeferredContSectBreak();
+    setNeedSect();
     RTFSkipDestination aSkip(*this);
     int nSprm = -1;
     RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
@@ -3477,6 +3495,7 @@ int RTFDocumentImpl::popState()
 
     checkUnicode();
     RTFParserState aState(m_aStates.top());
+    m_bWasInFrame = aState.aFrame.inFrame();
     sal_Int32 nMathToken = 0;
 
     switch (m_aStates.top().nDestinationState)
@@ -3950,7 +3969,6 @@ int RTFDocumentImpl::popState()
     {
         if (m_bNeedCr)
             dispatchSymbol(RTF_PAR);
-        m_bDeferredContSectBreak = false;
         sectBreak(true);
     }
 
@@ -4170,15 +4188,6 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
     }
 }
 
-void RTFDocumentImpl::checkDeferredContSectBreak()
-{
-    if (m_bDeferredContSectBreak)
-    {
-        m_bDeferredContSectBreak = false;
-        sectBreak();
-    }
-}
-
 RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
     : m_pDocumentImpl(pDocumentImpl),
     nInternalState(INTERNAL_NORMAL),
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 9801164..7147fa7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -487,8 +487,8 @@ namespace writerfilter {
                 void replayBuffer(RTFBuffer_t& rBuffer);
                 /// If we have some unicode or hex characters to send.
                 void checkUnicode(bool bUnicode = true, bool bHex = true);
-                /// If we have a pending continous section break.
-                void checkDeferredContSectBreak();
+                /// If we need a final section break at the end of the document.
+                void setNeedSect(bool bNeedSect = true);
 
                 uno::Reference<uno::XComponentContext> const& m_xContext;
                 uno::Reference<io::XInputStream> const& m_xInputStream;
@@ -581,7 +581,12 @@ namespace writerfilter {
                 rtl::OStringBuffer m_aHexBuffer;
                 /// Formula import.
                 oox::formulaimport::XmlStreamBuilder m_aMathBuffer;
-                bool m_bDeferredContSectBreak;
+                /// If the next continous section break should be ignored.
+                bool m_bIgnoreNextContSectBreak;
+                /// If a section break is needed before the end of the doc (false right after a section break).
+                bool m_bNeedSect;
+                /// If aFrame.inFrame() was true in the previous state.
+                bool m_bWasInFrame;
         };
     } // namespace rtftok
 } // namespace writerfilter


More information about the Libreoffice-commits mailing list