diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-06-29 07:54:17 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-06-29 10:51:11 +0200 |
commit | 761d3a128214b48645f00e2ff094e0f8928d1ee1 (patch) | |
tree | 5b86dd3344617260176d4ec0fb1e50f2981dff49 | |
parent | 6ab6f7bf61efe7f42161a2d5760763bf39f8795a (diff) |
This reverts commit 7ef9c3ef30023cc40068e1f735aa4bec4811288b (plus relevant part
of c08d71a0e0015ec7857335b68a354df04fa04a0c "Fix typos" follow-up). It started
to cause <https://ci.libreoffice.org/job/lo_ubsan/2441/> to fail with
> /sw/source/core/text/itrcrsr.cxx:1659:50: runtime error: downcast of address 0x60700059b250 which does not point to an object of type 'SwTextPortion'
> 0x60700059b250: note: object is of type 'SwHolePortion'
> 00 00 00 00 90 23 40 a7 6f 7f 00 00 e1 03 00 00 00 00 00 00 0d 01 00 00 00 00 00 00 00 00 00 00
> ^~~~~~~~~~~~~~~~~~~~~~~
> vptr for 'SwHolePortion'
> #0 0x7f6f9f1777f0 in SwTextCursor::GetModelPositionForViewPoint(SwPosition*, Point const&, bool, SwCursorMoveState*) const /sw/source/core/text/itrcrsr.cxx:1659:50
> #1 0x7f6f9efc2b39 in SwTextFrame::UnitDown_(SwPaM*, long, bool) const /sw/source/core/text/frmcrsr.cxx:1200:49
> #2 0x7f6f9efc5b50 in SwTextFrame::UnitDown(SwPaM*, long, bool) const /sw/source/core/text/frmcrsr.cxx:1298:31
> #3 0x7f6f9be4bac8 in SwCursor::UpDown(bool, unsigned short, Point const*, long, SwRootFrame&) /sw/source/core/crsr/swcrsr.cxx:2062:31
> #4 0x7f6f9bf0692b in SwShellCursor::UpDown(bool, unsigned short) /sw/source/core/crsr/viscrs.cxx:1025:22
> #5 0x7f6f9bb840c0 in SwCursorShell::UpDown(bool, unsigned short) /sw/source/core/crsr/crsrsh.cxx:511:29
> #6 0x7f6fa37f131d in SwCursorShell::Down(unsigned short) /sw/inc/crsrsh.hxx:359:50
> #7 0x7f6fa37dcfc9 in SwWrtShell::Down(bool, unsigned short, bool) /sw/source/uibase/wrtsh/move.cxx:171:27
> #8 0x7f6fb6aa1325 in testTdf43100_CursorMoveToSpacesOverMargin::TestBody() /sw/qa/core/text/text.cxx:532:20
during CppunitTest_sw_core_text
CPPUNIT_TEST_NAME=testTdf43100_CursorMoveToSpacesOverMargin::TestBody
Change-Id: I37947825ec9db826446ed28fa87a23ee60749b82
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136549
Reviewed-by: László Németh <nemeth@numbertext.org>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/core/text/data/tdf43100_tdf120715_cursorOnSpacesOverMargin.docx | bin | 9606 -> 0 bytes | |||
-rw-r--r-- | sw/qa/core/text/text.cxx | 68 | ||||
-rw-r--r-- | sw/source/core/text/guess.cxx | 10 | ||||
-rw-r--r-- | sw/source/core/text/guess.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/itrcrsr.cxx | 46 | ||||
-rw-r--r-- | sw/source/core/text/itrpaint.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/text/itrtxt.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/text/porlin.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/text/portxt.cxx | 20 | ||||
-rw-r--r-- | sw/source/core/text/portxt.hxx | 1 |
10 files changed, 27 insertions, 131 deletions
diff --git a/sw/qa/core/text/data/tdf43100_tdf120715_cursorOnSpacesOverMargin.docx b/sw/qa/core/text/data/tdf43100_tdf120715_cursorOnSpacesOverMargin.docx Binary files differdeleted file mode 100644 index 474d805d893e..000000000000 --- a/sw/qa/core/text/data/tdf43100_tdf120715_cursorOnSpacesOverMargin.docx +++ /dev/null diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 99d80f649fef..2db4d6dab348 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -470,74 +470,6 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testRedlineDelete) pDoc->getIDocumentRedlineAccess().GetRedlineTable().size()); } -CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf120715_CursorMoveWhenTypingSpaceAtCenteredLineEnd) -{ - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf43100_tdf120715_cursorOnSpacesOverMargin.docx"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - // Make a paint to force the call of AddExtraBlankWidth, that calculate width for holePortions. - pDoc->GetDocShell()->GetPreviewBitmap(); - - // Move the cursor to the last character of the document. - pWrtShell->EndOfSection(); - - //Press space and check if the cursor move right with the additional space. - sal_Int32 nOldCursorPos = pWrtShell->GetCharRect().Left(); - pWrtShell->Insert(" "); - sal_Int32 nNewCursorPos = pWrtShell->GetCharRect().Left(); - CPPUNIT_ASSERT_GREATER(nOldCursorPos, nNewCursorPos); -} - -CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf43100_CursorMoveToSpacesOverMargin) -{ - // Test the cursor movement over the right margin in several different paragraphs. - // These differences are based on its paragraphs - // - alignment (left, center, right, justified), - // - line count (1 line, 2 lines, blank line containing only spaces) - SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf43100_tdf120715_cursorOnSpacesOverMargin.docx"); - SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); - - // Make a paint to force the call of AddExtraBlankWidth, that calculate width for holePortions. - pDoc->GetDocShell()->GetPreviewBitmap(); - - // Move the cursor to the 2. line. - pWrtShell->Down(/*bSelect=*/false, 1, /*bBasicCall=*/false); - // Move the cursor to the right margin. - pWrtShell->RightMargin(false, false); - - sal_Int32 nMarginPos = pWrtShell->GetCharRect().Left(); - sal_Int32 nLastCursorPos = nMarginPos; - - // Move the cursor right 5 times, every step should increase the cursor x position. - // Before this fix, the cursor stopped at the margin. - for (int i = 0; i < 5; i++) - { - pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); - sal_Int32 nNewCursorPos = pWrtShell->GetCharRect().Left(); - CPPUNIT_ASSERT_GREATER(nLastCursorPos, nNewCursorPos); - nLastCursorPos = nNewCursorPos; - } - - // Move down the cursor several lines, and check if it will keep nearly its horizontal position. - // Some of the lines are not reach beyond the margin, there the cursor won't be able to keep its - // original position. - bool aLineReachOverMargin[] = { false, true, true, false, false, true, true, false, true, - true, true, true, false, true, true, false, false }; - // Cursor position can be a bit inaccurate, because it can only be positioned on characters, - // that is based on the actual line layout, therefore the actual cursor position - // is checked against a more distinct position instead of the nMarginPos. - sal_Int32 nAvgLeft = (nMarginPos + nLastCursorPos) / 2; - for (int i = 2; i < 17; i++) - { - pWrtShell->Down(/*bSelect=*/false, 1, /*bBasicCall=*/false); - sal_Int32 nNewCursorPos = pWrtShell->GetCharRect().Left(); - if (aLineReachOverMargin[i]) - CPPUNIT_ASSERT_GREATER(nAvgLeft, nNewCursorPos); - else - CPPUNIT_ASSERT_LESS(nAvgLeft, nNewCursorPos); - } -} - CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index 34681c158ed4..d469083f7eb1 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -100,9 +100,6 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, TextFrameIndex nCharsCnt = nMaxLen - nSpaceCnt; if ( nSpaceCnt && nCharsCnt < rPor.GetLen() ) { - if (nSpaceCnt) - rInf.GetTextSize( &rSI, rInf.GetIdx() + nCharsCnt, nSpaceCnt, - nMaxComp, m_nExtraBlankWidth, nMaxSizeDiff ); nMaxLen = nCharsCnt; if ( !nMaxLen ) return true; @@ -614,13 +611,6 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, else m_nBreakWidth = 0; - if (m_nBreakStart > rInf.GetIdx() + nPorLen + m_nFieldDiff) - { - rInf.GetTextSize(&rSI, rInf.GetIdx() + nPorLen, - m_nBreakStart - rInf.GetIdx() - nPorLen - m_nFieldDiff, nMaxComp, - m_nExtraBlankWidth, nMaxSizeDiff, rInf.GetCachedVclData().get()); - } - if( m_pHanging ) { m_nBreakPos = m_nCutPos; diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx index f83c7e280ae4..696a09fc8589 100644 --- a/sw/source/core/text/guess.hxx +++ b/sw/source/core/text/guess.hxx @@ -38,10 +38,9 @@ class SwTextGuess TextFrameIndex m_nFieldDiff; // absolute positions can be wrong if we // a field in the text has been expanded sal_uInt16 m_nBreakWidth; // width of the broken portion - sal_uInt16 m_nExtraBlankWidth; // width of spaces after the break public: SwTextGuess(): m_nCutPos(0), m_nBreakStart(0), - m_nBreakPos(0), m_nFieldDiff(0), m_nBreakWidth(0), m_nExtraBlankWidth(0) + m_nBreakPos(0), m_nFieldDiff(0), m_nBreakWidth(0) { } // true, if current portion still fits to current line @@ -52,7 +51,6 @@ public: SwHangingPortion* GetHangingPortion() const { return m_pHanging.get(); } SwHangingPortion* ReleaseHangingPortion() { return m_pHanging.release(); } sal_uInt16 BreakWidth() const { return m_nBreakWidth; } - sal_uInt16 ExtraBlankWidth() const { return m_nExtraBlankWidth; } TextFrameIndex CutPos() const { return m_nCutPos; } TextFrameIndex BreakStart() const { return m_nBreakStart; } TextFrameIndex BreakPos() const {return m_nBreakPos; } diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 88679296a951..546d91b17403 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -401,26 +401,6 @@ void SwTextCursor::CtorInitTextCursor( SwTextFrame *pNewFrame, SwTextSizeInfo *p // GetInfo().SetOut( GetInfo().GetWin() ); } -// tdf#120715 tdf#43100: Make width for some HolePortions, so cursor will be able to move into it. -// It should not change the layout, so this should be called after the layout is calculated. -void SwTextCursor::AddExtraBlankWidth() -{ - SwLinePortion* pPos = m_pCurr->GetNextPortion(); - SwLinePortion* pNextPos; - while (pPos) - { - pNextPos = pPos->GetNextPortion(); - // Do it only if it is the last portion that able to handle the cursor, - // else the next portion would misscalculate the cursor position - if (pPos->ExtraBlankWidth() && (!pNextPos || pNextPos->IsMarginPortion())) - { - pPos->Width(pPos->Width() + pPos->ExtraBlankWidth()); - pPos->ExtraBlankWidth(0); - } - pPos = pNextPos; - } -} - // 1170: Ancient bug: Shift-End forgets the last character ... void SwTextCursor::GetEndCharRect(SwRect* pOrig, const TextFrameIndex nOfst, SwCursorMoveState* pCMS, const tools::Long nMax ) @@ -1233,6 +1213,10 @@ void SwTextCursor::GetCharRect( SwRect* pOrig, TextFrameIndex const nOfst, GetCharRect_( pOrig, nFindOfst, pCMS ); + // This actually would have to be "-1 LogicToPixel", but that seems too + // expensive, so it's a value (-12), that should hopefully be OK. + const SwTwips nTmpRight = Right() - 12; + pOrig->Pos().AdjustX(aCharPos.X() ); pOrig->Pos().AdjustY(aCharPos.Y() ); @@ -1244,6 +1228,13 @@ void SwTextCursor::GetCharRect( SwRect* pOrig, TextFrameIndex const nOfst, pCMS->m_p2Lines->aPortion.Pos().AdjustY(aCharPos.Y() ); } + const IDocumentSettingAccess& rIDSA = GetTextFrame()->GetDoc().getIDocumentSettingAccess(); + const bool bTabOverMargin = rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN) + || rIDSA.get(DocumentSettingId::TAB_OVER_SPACING); + // Make sure the cursor respects the right margin, unless in compat mode, where the tab size has priority over the margin size. + if( pOrig->Left() > nTmpRight && !bTabOverMargin) + pOrig->Pos().setX( nTmpRight ); + if( nMax ) { if( pOrig->Top() + pOrig->Height() > nMax ) @@ -1264,6 +1255,16 @@ void SwTextCursor::GetCharRect( SwRect* pOrig, TextFrameIndex const nOfst, pCMS->m_aRealHeight.setY( nMax - nTmp ); } } + tools::Long nOut = pOrig->Right() - GetTextFrame()->getFrameArea().Right(); + if( nOut > 0 ) + { + if( GetTextFrame()->getFrameArea().Width() < GetTextFrame()->getFramePrintArea().Left() + + GetTextFrame()->getFramePrintArea().Width() ) + nOut += GetTextFrame()->getFrameArea().Width() - GetTextFrame()->getFramePrintArea().Left() + - GetTextFrame()->getFramePrintArea().Width(); + if( nOut > 0 ) + pOrig->Pos().AdjustX( -(nOut + 10) ); + } } /** @@ -1319,6 +1320,9 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con if( bLeftOver ) x = nLeftMargin; const bool bRightOver = x > nRightMargin; + if( bRightOver ) + x = nRightMargin; + const bool bRightAllowed = pCMS && ( pCMS->m_eState == CursorMoveState::NONE ); // Until here everything in document coordinates. @@ -1643,7 +1647,7 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con return GetModelPositionForViewPoint( pPos, Point( GetLineStart() + nX, rPoint.Y() ), bChgNode, pCMS ); } - if( pPor->InTextGrp() || pPor->IsHolePortion() ) + if( pPor->InTextGrp() ) { sal_uInt8 nOldProp; if( GetPropFont() ) diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx index a66d358645f0..3935630192dd 100644 --- a/sw/source/core/text/itrpaint.cxx +++ b/sw/source/core/text/itrpaint.cxx @@ -127,7 +127,6 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip, // maybe catch-up adjustment GetAdjusted(); - AddExtraBlankWidth(); GetInfo().SetpSpaceAdd( m_pCurr->GetpLLSpaceAdd() ); GetInfo().ResetSpaceIdx(); GetInfo().SetKanaComp( m_pCurr->GetpKanaComp() ); diff --git a/sw/source/core/text/itrtxt.hxx b/sw/source/core/text/itrtxt.hxx index 0b48e3b874fe..f36932dbd5f9 100644 --- a/sw/source/core/text/itrtxt.hxx +++ b/sw/source/core/text/itrtxt.hxx @@ -270,7 +270,6 @@ class SwTextCursor : public SwTextAdjuster protected: void CtorInitTextCursor( SwTextFrame *pFrame, SwTextSizeInfo *pInf ); explicit SwTextCursor(SwTextNode const * pTextNode) : SwTextAdjuster(pTextNode) { } - void AddExtraBlankWidth(); public: SwTextCursor( SwTextFrame *pTextFrame, SwTextSizeInfo *pTextSizeInf ) : SwTextAdjuster(pTextFrame->GetTextNodeFirst()) diff --git a/sw/source/core/text/porlin.hxx b/sw/source/core/text/porlin.hxx index 5ce25a3dd76b..3cd1d9fff942 100644 --- a/sw/source/core/text/porlin.hxx +++ b/sw/source/core/text/porlin.hxx @@ -63,7 +63,6 @@ private: PortionType mnWhichPor; // Who's who? bool m_bJoinBorderWithPrev; bool m_bJoinBorderWithNext; - SwTwips m_nExtraBlankWidth = 0; // width of spaces after the break void Truncate_(); @@ -84,8 +83,6 @@ public: SwTwips PrtWidth() const { return Width(); } void AddPrtWidth( const SwTwips nNew ) { Width( Width() + nNew ); } void SubPrtWidth( const SwTwips nNew ) { Width( Width() - nNew ); } - SwTwips ExtraBlankWidth() const { return m_nExtraBlankWidth; } - void ExtraBlankWidth(const SwTwips nNew) { m_nExtraBlankWidth = nNew; } SwTwips GetHangingBaseline() const { return mnHangingBaseline; } void SetHangingBaseline( const SwTwips nNewBaseline ) { mnHangingBaseline = nNewBaseline; } @@ -194,7 +191,6 @@ inline SwLinePortion &SwLinePortion::operator=(const SwLinePortion &rPortion) mnWhichPor = rPortion.mnWhichPor; m_bJoinBorderWithPrev = rPortion.m_bJoinBorderWithPrev; m_bJoinBorderWithNext = rPortion.m_bJoinBorderWithNext; - m_nExtraBlankWidth = rPortion.m_nExtraBlankWidth; return *this; } @@ -206,8 +202,7 @@ inline SwLinePortion::SwLinePortion(const SwLinePortion &rPortion) : mnHangingBaseline( rPortion.mnHangingBaseline ), mnWhichPor( rPortion.mnWhichPor ), m_bJoinBorderWithPrev( rPortion.m_bJoinBorderWithPrev ), - m_bJoinBorderWithNext( rPortion.m_bJoinBorderWithNext ), - m_nExtraBlankWidth(rPortion.m_nExtraBlankWidth) + m_bJoinBorderWithNext( rPortion.m_bJoinBorderWithNext ) { } diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index c0f66496f134..a5ae0ea7e287 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -321,7 +321,6 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) if ( !bFull ) { Width( aGuess.BreakWidth() ); - ExtraBlankWidth(aGuess.ExtraBlankWidth()); // Caution! if( !InExpGrp() || InFieldGrp() ) SetLen( rInf.GetLen() ); @@ -410,8 +409,6 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) { SwHolePortion *pNew = new SwHolePortion( *this ); pNew->SetLen( nRealStart - aGuess.BreakPos() ); - pNew->Width(0); - pNew->ExtraBlankWidth( aGuess.ExtraBlankWidth() ); Insert( pNew ); } } @@ -752,29 +749,12 @@ SwHolePortion::SwHolePortion( const SwTextPortion &rPor ) { SetLen( TextFrameIndex(1) ); Height( rPor.Height() ); - Width(0); SetAscent( rPor.GetAscent() ); SetWhichPor( PortionType::Hole ); } SwLinePortion *SwHolePortion::Compress() { return this; } -// The GetTextSize() assumes that the own length is correct -SwPosSize SwHolePortion::GetTextSize(const SwTextSizeInfo& rInf) const -{ - SwPosSize aSize = rInf.GetTextSize(); - if (!GetJoinBorderWithPrev()) - aSize.Width(aSize.Width() + rInf.GetFont()->GetLeftBorderSpace()); - if (!GetJoinBorderWithNext()) - aSize.Width(aSize.Width() + rInf.GetFont()->GetRightBorderSpace()); - - aSize.Height(aSize.Height() + - rInf.GetFont()->GetTopBorderSpace() + - rInf.GetFont()->GetBottomBorderSpace()); - - return aSize; -} - void SwHolePortion::Paint( const SwTextPaintInfo &rInf ) const { if( !rInf.GetOut() ) diff --git a/sw/source/core/text/portxt.hxx b/sw/source/core/text/portxt.hxx index a30f6f0e53b1..77ec0a9f1363 100644 --- a/sw/source/core/text/portxt.hxx +++ b/sw/source/core/text/portxt.hxx @@ -69,7 +69,6 @@ public: void SetBlankWidth( const sal_uInt16 nNew ) { m_nBlankWidth = nNew; } virtual SwLinePortion *Compress() override; virtual bool Format( SwTextFormatInfo &rInf ) override; - virtual SwPosSize GetTextSize(const SwTextSizeInfo& rInfo) const override; virtual void Paint( const SwTextPaintInfo &rInf ) const override; // Accessibility: pass information about this portion to the PortionHandler |