[Libreoffice-commits] core.git: sw/qa sw/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Wed May 8 09:46:48 UTC 2019


 sw/qa/extras/layout/data/tdf116501.odt |binary
 sw/qa/extras/layout/layout.cxx         |    6 ++++++
 sw/source/core/inc/layact.hxx          |    5 +++++
 sw/source/core/inc/tabfrm.hxx          |   10 ++++++++++
 sw/source/core/layout/layact.cxx       |   21 ++++++++++++++++++++-
 sw/source/core/layout/tabfrm.cxx       |    4 +++-
 6 files changed, 44 insertions(+), 2 deletions(-)

New commits:
commit 91b2239783dc716bd71ce7962bfd7e341dfe4175
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Tue May 7 17:22:41 2019 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Wed May 8 11:45:49 2019 +0200

    tdf#116501 fix freezing at embedded text tables
    
    by disabling their in-row splitting using loop control.
    
    Change-Id: Ibd93213fa0ce45458ce188de20da982e4abc17c5
    Reviewed-on: https://gerrit.libreoffice.org/71920
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/qa/extras/layout/data/tdf116501.odt b/sw/qa/extras/layout/data/tdf116501.odt
new file mode 100644
index 000000000000..7d38b8be53c2
Binary files /dev/null and b/sw/qa/extras/layout/data/tdf116501.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 381f9c0087b6..bb3aea800d0e 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2965,6 +2965,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf123651)
     assertXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "top", "7639");
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf116501)
+{
+    //just care it doesn't freeze
+    createDoc("tdf116501.odt");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/layact.hxx b/sw/source/core/inc/layact.hxx
index 8f5960837031..1253233778e6 100644
--- a/sw/source/core/inc/layact.hxx
+++ b/sw/source/core/inc/layact.hxx
@@ -95,6 +95,11 @@ class SwLayAction
     // OD 14.04.2003 #106346# - new flag for content formatting on interrupt.
     bool    mbFormatContentOnInterrupt;
 
+    // for loop control by disabling in-row splitting within embedded tables
+    const SwPageFrame  *m_pCurPage;
+    sal_uInt16 m_nTabLevel;  // embedding level
+    sal_uInt32 m_nCallCount; // calling FormatLayoutTab on the same page
+
     void PaintContent( const SwContentFrame *, const SwPageFrame *,
                      const SwRect &rOldRect, long nOldBottom );
     bool PaintWithoutFlys( const SwRect &, const SwContentFrame *,
diff --git a/sw/source/core/inc/tabfrm.hxx b/sw/source/core/inc/tabfrm.hxx
index 176396c6667a..cc57d46d8492 100644
--- a/sw/source/core/inc/tabfrm.hxx
+++ b/sw/source/core/inc/tabfrm.hxx
@@ -84,6 +84,8 @@ class SwTabFrame: public SwLayoutFrame, public SwFlowFrame
 
     bool m_bInRecalcLowerRow : 1;
 
+    bool m_bSplitRowDisabled : 1;          // loop control
+
     /**
      * Split() splits the Frame at the specified position: a Follow is
      * created and constructed and inserted directly after this.
@@ -173,6 +175,14 @@ public:
     {
         m_bInRecalcLowerRow = bNew;
     }
+    bool IsSplitRowDisabled() const
+    {
+        return m_bSplitRowDisabled;
+    }
+    void SetSplitRowDisabled()
+    {
+        m_bSplitRowDisabled = true;
+    }
 
     // #i26945#
     bool IsConsiderObjsForMinCellHeight() const
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index 8e02e75e9362..c58261786a6b 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -258,7 +258,10 @@ SwLayAction::SwLayAction( SwRootFrame *pRt, SwViewShellImp *pI ) :
     m_nStartTicks( std::clock() ),
     m_nInputType( VclInputFlags::NONE ),
     m_nEndPage( USHRT_MAX ),
-    m_nCheckPageNum( USHRT_MAX )
+    m_nCheckPageNum( USHRT_MAX ),
+    m_pCurPage( nullptr ),
+    m_nTabLevel( 0 ),
+    m_nCallCount( 0 )
 {
     m_bPaintExtraData = ::IsExtraData( m_pImp->GetShell()->GetDoc() );
     m_bPaint = m_bComplete = m_bWaitAllowed = m_bCheckPages = true;
@@ -286,6 +289,7 @@ void SwLayAction::Reset()
     m_bPaint = m_bComplete = m_bWaitAllowed = m_bCheckPages = true;
     m_bInput = m_bAgain = m_bNextCycle = m_bCalcLayout = m_bIdle = m_bReschedule =
     m_bUpdateExpFields = m_bBrowseActionStop = false;
+    m_pCurPage = nullptr;
 }
 
 bool SwLayAction::RemoveEmptyBrowserPages()
@@ -1172,6 +1176,12 @@ bool SwLayAction::IsShortCut( SwPageFrame *&prPage )
 // introduce support for vertical layout
 bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLay, bool bAddRect )
 {
+    // save page for loop control
+    if( pLay->IsPageFrame() && static_cast<SwPageFrame*>(pLay) != m_pCurPage )
+    {
+        m_nCallCount = 0;
+        m_pCurPage = static_cast<SwPageFrame*>(pLay);
+    }
     OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
     if ( IsAgain() )
         return false;
@@ -1351,7 +1361,16 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLa
         if ( pLow->IsLayoutFrame() )
         {
             if ( pLow->IsTabFrame() )
+            {
+                // loop control for embedded tables
+                if ( m_nTabLevel > 0 && ++m_nCallCount > 50 ) {
+                    static_cast<SwTabFrame*>(pLow)->SetSplitRowDisabled();
+                }
+
+                ++m_nTabLevel;
                 bTabChanged |= FormatLayoutTab( static_cast<SwTabFrame*>(pLow), bAddRect );
+                --m_nTabLevel;
+            }
             // Skip the ones already registered for deletion
             else if( !pLow->IsSctFrame() || static_cast<SwSectionFrame*>(pLow)->GetSection() )
                 bChanged |= FormatLayout( pRenderContext, static_cast<SwLayoutFrame*>(pLow), bAddRect );
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 060a8dcf6de3..a9667a964308 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -80,6 +80,7 @@ SwTabFrame::SwTabFrame( SwTable &rTab, SwFrame* pSib )
     , m_bConsiderObjsForMinCellHeight(true)
     , m_bObjsDoesFit(true)
     , m_bInRecalcLowerRow(false)
+    , m_bSplitRowDisabled(false)
 {
     mbFixSize = false;     //Don't fall for import filter again.
     mnFrameType = SwFrameType::Tab;
@@ -118,6 +119,7 @@ SwTabFrame::SwTabFrame( SwTabFrame &rTab )
     , m_bConsiderObjsForMinCellHeight(true)
     , m_bObjsDoesFit(true)
     , m_bInRecalcLowerRow(false)
+    , m_bSplitRowDisabled(false)
 {
     mbFixSize = false;     //Don't fall for import filter again.
     mnFrameType = SwFrameType::Tab;
@@ -1018,7 +1020,7 @@ bool SwTabFrame::Split( const SwTwips nCutPos, bool bTryToSplit, bool bTableRowK
     //                   table, or it will be set to false under certain
     //                   conditions that are not suitable for splitting
     //                   the row.
-    bool bSplitRowAllowed = pRow->IsRowSplitAllowed();
+    bool bSplitRowAllowed = pRow->IsRowSplitAllowed() && !IsSplitRowDisabled();
 
     // #i29438#
     // #i26945# - Floating screen objects no longer forbid


More information about the Libreoffice-commits mailing list