[Libreoffice-commits] core.git: 4 commits - sw/source
Michael Stahl
mstahl at redhat.com
Fri Dec 15 16:46:00 UTC 2017
sw/source/core/inc/txtfrm.hxx | 13 +++++++++----
sw/source/core/layout/trvlfrm.cxx | 5 ++++-
sw/source/core/text/txtfrm.cxx | 14 +++++++-------
sw/source/core/text/txtinit.cxx | 4 ++--
sw/source/uibase/index/toxmgr.cxx | 12 ++++++++++--
5 files changed, 32 insertions(+), 16 deletions(-)
New commits:
commit b77881366b17230908f441dfa27afcafc4374708
Author: Michael Stahl <mstahl at redhat.com>
Date: Fri Dec 15 17:07:01 2017 +0100
tdf#100635 sw: fix layout crash caused by field expansion ...
... triggering recursive layout-in-layout where a SwTextFrame
that's being formatted is deleted inside some other frame's
SwTextNode::GetFormatted().
The offending field is a SwAuthorityField that's located in a
fly-frame with FLY_AT_PAGE anchor.
SwPageFrame::GetContentPosition() is only called by field expansion
code, so this shouldn't have an effect on layout.
It already has a fall-back for the case when the frame has invalid
flags, so handle the situation when the SwLineLayout has been
deleted from the SwCache due to overflow the same way,
which prevents the recursive formatting.
Change-Id: I90437edb5692dc2bdec7ad03964588942bde05be
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index df410a56ceb2..dfaa27bf2a03 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -1433,9 +1433,12 @@ void SwPageFrame::GetContentPosition( const Point &rPt, SwPosition &rPos ) const
else if ( aAct.X() > aRect.Right() )
aAct.X() = aRect.Right();
- if( !pAct->isFrameAreaDefinitionValid() )
+ if (!pAct->isFrameAreaDefinitionValid() ||
+ (pAct->IsTextFrame() && !static_cast<SwTextFrame const*>(pAct)->HasPara()))
{
// ContentFrame not formatted -> always on node-beginning
+ // tdf#100635 also if the SwTextFrame would require reformatting,
+ // which is unwanted in case this is called from text formatting code
SwContentNode* pCNd = const_cast<SwContentNode*>(pAct->GetNode());
OSL_ENSURE( pCNd, "Where is my ContentNode?" );
rPos.nNode = *pCNd;
commit aa07f2892e581dd31f1b8861499e29c96dddbac0
Author: Michael Stahl <mstahl at redhat.com>
Date: Fri Dec 15 17:18:39 2017 +0100
sw: prefix SwTextFrame::pTextCache member
Change-Id: Ibfbc59c9df89a3cde6226bd49cf33c2ac865d4a8
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 36016aaca196..6a22cff6f059 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -60,7 +60,7 @@ class SW_DLLPUBLIC SwTextFrame: public SwContentFrame
/// if there are too many of them, but the "valid" flags of the frame
/// will still be set; GetFormatted() is the function that forces
/// recreation of the SwLineLayout by Format() if necessary.
- static SwCache *pTextCache;
+ static SwCache *s_pTextCache;
static long nMinPrtLine; // This Line must not be underrun when printing
// Hack for table cells stretching multiple pages
@@ -451,7 +451,7 @@ public:
SwTextFrame *FindQuoVadisFrame();
/**
- * In case the SwLineLayout was cleared out of the pTextCache, recreate it.
+ * In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
*
* #i29062# GetFormatted() can trigger a full formatting
* of the paragraph, causing other layout frames to become invalid. This
@@ -472,8 +472,8 @@ public:
bool GetDropRect( SwRect &rRect ) const
{ return HasPara() && GetDropRect_( rRect ); }
- static SwCache *GetTextCache() { return pTextCache; }
- static void SetTextCache( SwCache *pNew ) { pTextCache = pNew; }
+ static SwCache *GetTextCache() { return s_pTextCache; }
+ static void SetTextCache( SwCache *pNew ) { s_pTextCache = pNew; }
static long GetMinPrtLine() { return nMinPrtLine; }
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index a93fcb77fc50..65dbf5193ce5 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -398,7 +398,7 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib )
void SwTextFrame::DestroyImpl()
{
- // Remove associated SwParaPortion from pTextCache
+ // Remove associated SwParaPortion from s_pTextCache
ClearPara();
const SwContentNode* pCNd;
@@ -2123,7 +2123,7 @@ SwTextFrame* SwTextFrame::GetFormatted( bool bForceQuickFormat )
vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
SwSwapIfSwapped swap( this );
- // In case the SwLineLayout was cleared out of the pTextCache, recreate it.
+ // In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
// Not for empty paragraphs
if( !HasPara() && !(isFrameAreaDefinitionValid() && IsEmpty()) )
{
@@ -2134,7 +2134,7 @@ SwTextFrame* SwTextFrame::GetFormatted( bool bForceQuickFormat )
// If the flags were valid (hence bFormat=true), Calc did nothing,
// so Format() must be called manually in order to recreate
// the SwLineLayout that has been deleted from the
- // SwTextFrame::pTextCache (hence !HasPara() above).
+ // SwTextFrame::s_pTextCache (hence !HasPara() above).
// Optimization with FormatQuick()
if( bFormat && !FormatQuick( bForceQuickFormat ) )
Format(getRootFrame()->GetCurrShell()->GetOut());
diff --git a/sw/source/core/text/txtinit.cxx b/sw/source/core/text/txtinit.cxx
index 67c81d185660..7770b1d3d5c0 100644
--- a/sw/source/core/text/txtinit.cxx
+++ b/sw/source/core/text/txtinit.cxx
@@ -38,7 +38,7 @@
#include <txtfly.hxx>
#include <dbg_lay.hxx>
-SwCache *SwTextFrame::pTextCache = nullptr;
+SwCache *SwTextFrame::s_pTextCache = nullptr;
long SwTextFrame::nMinPrtLine = 0;
SwContourCache *pContourCache = nullptr;
SwDropCapCache *pDropCapCache = nullptr;
@@ -59,7 +59,7 @@ void TextInit_()
pSwFontCache = new SwFontCache; // Cache for SwTextFormatColl -> SwFontObj = { SwFont aSwFont, SfxPoolItem* pDefaultArray }
SwCache *pTextCache = new SwCache( 250 // Cache for SwTextFrame -> SwTextLine = { SwParaPortion* pLine }
#ifdef DBG_UTIL
- , "static SwTextFrame::pTextCache"
+ , "static SwTextFrame::s_pTextCache"
#endif
);
SwTextFrame::SetTextCache( pTextCache );
commit c186ef35d56a420b272be33bea373aa516867e2f
Author: Michael Stahl <mstahl at redhat.com>
Date: Fri Dec 15 16:57:36 2017 +0100
sw: clarify what the hell SwTextFrame::GetFormatted() actually does
Change-Id: I3af0ef5f10c6c2172499b481f3fab1400dca3c6f
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index e510ca4d5934..36016aaca196 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -55,7 +55,12 @@ class SW_DLLPUBLIC SwTextFrame: public SwContentFrame
friend class TextFrameLockGuard; // May Lock()/Unlock()
friend bool sw_ChangeOffset( SwTextFrame* pFrame, sal_Int32 nNew );
- static SwCache *pTextCache; // Pointer to the Line Cache
+ /// SwLineLayout cache: the lines are not actually owned by the SwTextFrame
+ /// but by this SwCache, so they will be deleted in large documents
+ /// if there are too many of them, but the "valid" flags of the frame
+ /// will still be set; GetFormatted() is the function that forces
+ /// recreation of the SwLineLayout by Format() if necessary.
+ static SwCache *pTextCache;
static long nMinPrtLine; // This Line must not be underrun when printing
// Hack for table cells stretching multiple pages
@@ -446,7 +451,7 @@ public:
SwTextFrame *FindQuoVadisFrame();
/**
- * Makes up for formatting if the Idle Handler has struck
+ * In case the SwLineLayout was cleared out of the pTextCache, recreate it.
*
* #i29062# GetFormatted() can trigger a full formatting
* of the paragraph, causing other layout frames to become invalid. This
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 6759e1b47515..a93fcb77fc50 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2123,18 +2123,18 @@ SwTextFrame* SwTextFrame::GetFormatted( bool bForceQuickFormat )
vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
SwSwapIfSwapped swap( this );
- // The IdleCollector could've removed my cached information
- // Calc() calls our format
+ // In case the SwLineLayout was cleared out of the pTextCache, recreate it.
// Not for empty paragraphs
if( !HasPara() && !(isFrameAreaDefinitionValid() && IsEmpty()) )
{
// Calc() must be called, because frame position can be wrong
const bool bFormat = isFrameAreaSizeValid();
- Calc(pRenderContext);
+ Calc(pRenderContext); // calls Format() if invalid
- // It could be that Calc() did not trigger Format(), because
- // we've been asked by the IdleCollector to throw away our
- // format information
+ // If the flags were valid (hence bFormat=true), Calc did nothing,
+ // so Format() must be called manually in order to recreate
+ // the SwLineLayout that has been deleted from the
+ // SwTextFrame::pTextCache (hence !HasPara() above).
// Optimization with FormatQuick()
if( bFormat && !FormatQuick( bForceQuickFormat ) )
Format(getRootFrame()->GetCurrShell()->GetOut());
commit 2993bb634dc9ea66af90671a55a4503843338746
Author: Michael Stahl <mstahl at redhat.com>
Date: Thu Dec 14 18:52:15 2017 +0100
tdf#100635 sw: fix crash in SwTOXMgr::UpdateOrInsertTOX()
GetAuthBrackets() returns an empty string if the user selects
[None], in that case apparently 0 bytes are used, multiple places
check for that.
Change-Id: I8375621fa553bc780db343ed8a0bd7ecb3c832dc
diff --git a/sw/source/uibase/index/toxmgr.cxx b/sw/source/uibase/index/toxmgr.cxx
index bbd2b293628d..b5b8b31e9198 100644
--- a/sw/source/uibase/index/toxmgr.cxx
+++ b/sw/source/uibase/index/toxmgr.cxx
@@ -355,8 +355,16 @@ bool SwTOXMgr::UpdateOrInsertTOX(const SwTOXDescription& rDesc,
pFType = static_cast<SwAuthorityFieldType*>(
pSh->InsertFieldType(type));
}
- pFType->SetPreSuffix(rDesc.GetAuthBrackets()[0],
- rDesc.GetAuthBrackets()[1]);
+ OUString const& rBrackets(rDesc.GetAuthBrackets());
+ if (rBrackets.isEmpty())
+ {
+ pFType->SetPreSuffix('\0', '\0');
+ }
+ else
+ {
+ assert(rBrackets.getLength() == 2);
+ pFType->SetPreSuffix(rBrackets[0], rBrackets[1]);
+ }
pFType->SetSequence(rDesc.IsAuthSequence());
SwTOXSortKey rArr[3];
rArr[0] = rDesc.GetSortKey1();
More information about the Libreoffice-commits
mailing list