diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-12-17 17:42:31 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-12-18 22:30:15 +0100 |
commit | da68e7c9442770f319676bb1cffab724b463ab19 (patch) | |
tree | 6cc4aaecc6b6155d4ceb8334dbd19add5968e4a3 /sw | |
parent | 859125dae998fd181f3b2704d3c1e49f757fcc69 (diff) |
sw_redlinehide_4b: surprising discoveries
It turns out that there was a small problem in the interpretation of
sw_JoinText(), or rather, its caller,
SwRangeRedline::DelCopyOfSection(), which, since about OOo 3.2 and
i#100466, passes in bForceJoinNext, so the result is that the first node
wins always, not just for RES_BREAK/RES_PAGEDESC items.
This means that pParaPropsNode and pFirstNode are the same thing really.
Another little problem is that the SwAttrIter was initing the font
wrongly: the relevant items are the items in the *current* node's item
set on top of the item set of the paragraph style, i.e. the *first*
node's style.
Simple reproducer: ooo79457-1.odt
Change-Id: I06ef3c1695b8f3cdbded238864a60d5eb9ce4c44
(cherry picked from commit c20308f1b919ca5ce61233068946e5fddb7eadb3)
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/layout/frmtool.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/itratr.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/text/itratr.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/text/redlnitr.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/text/txtdrop.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/text/txtfrm.cxx | 16 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 3 |
8 files changed, 35 insertions, 19 deletions
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 51a71c499662..b9bb1b498496 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -437,6 +437,7 @@ public: /// Returns the text portion we want to edit (for inline see underneath) const OUString& GetText() const; SwTextNode const* GetTextNodeForParaProps() const; + SwTextNode const* GetTextNodeForFirstText() const; SwTextNode * GetTextNodeFirst() { return const_cast<SwTextNode*>(const_cast<SwTextFrame const*>(this)->GetTextNodeFirst()); }; SwTextNode const* GetTextNodeFirst() const; diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 4cf8effa38e2..9790d77241d1 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1170,10 +1170,6 @@ void AppendObjs(const SwFrameFormats *const pTable, sal_uLong const nIndex, { AppendObjsOfNode(pTable, pNode->GetIndex(), pFrame, pPage, pDoc, &iterFirst, &iter); } - else - { - assert(pMerged->pParaPropsNode == iter->pNode); // first iteration - } pNode = iter->pNode; iterFirst = iter; } diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 613a7264cdbc..f964a13f858f 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -205,7 +205,7 @@ bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const bool bParaFo { assert(m_pMergedPara); m_pTextNode = m_pMergedPara->pFirstNode; - InitFontAndAttrHandler(*m_pTextNode, m_pMergedPara->mergedText, nullptr); + InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode, m_pMergedPara->mergedText, nullptr); } // reset font to its original state @@ -339,7 +339,7 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) // items at all; it can only apply a previously effective item. // So do this by recreating the font from scratch. // Apply new para items: - InitFontAndAttrHandler(*newPos.first, m_pMergedPara->mergedText, nullptr); + InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *newPos.first, m_pMergedPara->mergedText, nullptr); // reset to next m_pTextNode = newPos.first; m_nStartIndex = 0; @@ -361,7 +361,7 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) m_pTextNode = newPos.first; // sw_redlinehide: hope it's okay to use the current text node // here; the AttrHandler shouldn't care about non-char items - InitFontAndAttrHandler(*m_pTextNode, m_pMergedPara->mergedText, nullptr); + InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode, m_pMergedPara->mergedText, nullptr); } } if (m_pMergedPara || m_pTextNode->GetpSwpHints()) @@ -1418,8 +1418,7 @@ SwTwips SwTextNode::GetWidthOfLeadingTabs() const { // Only consider master frames: if (!pFrame->IsFollow() && - // sw_redlinehide: paraPropsNode has the first text of the frame - (!pFrame->GetMergedPara() || pFrame->GetMergedPara()->pParaPropsNode == this)) + pFrame->GetTextNodeForFirstText() == this) { SwRectFnSet aRectFnSet(pFrame); SwRect aRect; diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx index 959436609608..2dddd1265d8c 100644 --- a/sw/source/core/text/itratr.hxx +++ b/sw/source/core/text/itratr.hxx @@ -65,7 +65,8 @@ private: void SeekFwd(sal_Int32 nOldPos, sal_Int32 nNewPos); void SetFnt( SwFont* pNew ) { m_pFont = pNew; } - void InitFontAndAttrHandler(SwTextNode const& rTextNode, + void InitFontAndAttrHandler( + SwTextNode const& rPropsNode, SwTextNode const& rTextNode, OUString const& rText, bool const* pbVertLayout); protected: diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index bd97d9e0e670..14793f210a83 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -219,13 +219,14 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, if (extents.empty()) // there was no text anywhere { assert(mergedText.isEmpty()); - pParaPropsNode = &rTextNode; // if every node is empty, the first one wins +// pParaPropsNode = &rTextNode; // if every node is empty, the first one wins } else { assert(!mergedText.isEmpty()); - pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty +// pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty } + pParaPropsNode = &rTextNode; // well, actually... // keep lists up to date with visible nodes if (pParaPropsNode->IsInList() && !pParaPropsNode->GetNum(rFrame.getRootFrame())) { @@ -300,12 +301,14 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, } // namespace sw -void SwAttrIter::InitFontAndAttrHandler(SwTextNode const& rTextNode, +void SwAttrIter::InitFontAndAttrHandler( + SwTextNode const& rPropsNode, + SwTextNode const& rTextNode, OUString const& rText, bool const*const pbVertLayout) { // Build a font matching the default paragraph style: - SwFontAccess aFontAccess( &rTextNode.GetAnyFormatColl(), m_pViewShell ); + SwFontAccess aFontAccess( &rPropsNode.GetAnyFormatColl(), m_pViewShell ); // It is possible that Init is called more than once, e.g., in a // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide) // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt @@ -396,7 +399,9 @@ void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode, if (m_pScriptInfo->GetInvalidityA() != TextFrameIndex(COMPLETE_STRING)) m_pScriptInfo->InitScriptInfo(rTextNode, m_pMergedPara, bRTL); - InitFontAndAttrHandler(rTextNode, + InitFontAndAttrHandler( + m_pMergedPara ? *m_pMergedPara->pParaPropsNode : rTextNode, + rTextNode, m_pMergedPara ? m_pMergedPara->mergedText : rTextNode.GetText(), & bVertLayout); diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx index a19d7086f5ac..a1d371dd5143 100644 --- a/sw/source/core/text/txtdrop.cxx +++ b/sw/source/core/text/txtdrop.cxx @@ -250,8 +250,7 @@ bool SwTextNode::GetDropSize(int& rFontHeight, int& rDropHeight, int& rDropDesce { // Only (master-) text frames can have a drop cap. if (!pLastFrame->IsFollow() && - // sw_redlinehide: paraPropsNode has the first text of the frame - (!pLastFrame->GetMergedPara() || pLastFrame->GetMergedPara()->pParaPropsNode == this)) + pLastFrame->GetTextNodeForFirstText() == this) { if( !pLastFrame->HasPara() ) diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index f2b2ed9acebf..8a97bcba42d5 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1061,6 +1061,7 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged, // pFirstNode is never updated if (nErased && nErased == nFoundNode) { // all visible text from node was erased +#if 0 if (rMerged.pParaPropsNode == &rNode) { rMerged.pParaPropsNode->RemoveFromListRLHidden(); @@ -1069,6 +1070,7 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged, : rMerged.extents.front().pNode; rMerged.pParaPropsNode->AddToListRLHidden(); } +#endif // NOPE must listen on all non-hidden nodes; particularly on pLastNode rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode)); } rMerged.mergedText = text.makeStringAndClear(); @@ -1219,7 +1221,21 @@ SwTextNode const* SwTextFrame::GetTextNodeForParaProps() const //nope assert(GetPara()); sw::MergedPara const*const pMerged(GetMergedPara()); if (pMerged) + { + assert(pMerged->pFirstNode == pMerged->pParaPropsNode); // surprising news! return pMerged->pParaPropsNode; + } + else + return static_cast<SwTextNode const*>(SwFrame::GetDep()); +} + +SwTextNode const* SwTextFrame::GetTextNodeForFirstText() const +{ + sw::MergedPara const*const pMerged(GetMergedPara()); + if (pMerged) + return pMerged->extents.empty() + ? pMerged->pFirstNode + : pMerged->extents.front().pNode; else return static_cast<SwTextNode const*>(SwFrame::GetDep()); } diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index f9a838bad1c5..fa6e26e4ed21 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -4290,8 +4290,7 @@ void SwTextNode::AddToList() { if (pFrame->getRootFrame()->IsHideRedlines()) { - sw::MergedPara const*const pMerged = pFrame->GetMergedPara(); - if (!pMerged || this == pMerged->pParaPropsNode) + if (pFrame->GetTextNodeForParaProps() == this) { AddToListRLHidden(); } |