diff --git a/sw/qa/extras/layout/data/tdf163060.fodt b/sw/qa/extras/layout/data/tdf163060.fodt new file mode 100644 index 000000000000..a5f7291e09a5 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf163060.fodt @@ -0,0 +1,205 @@ + + + + + + 0 + 0 + 27481 + 16293 + true + false + + + view2 + 21758 + 2300 + 0 + 0 + 27480 + 16291 + 0 + 1 + false + 140 + false + false + false + false + false + false + + + + + false + true + true + + false + 0 + false + true + false + true + false + false + true + 0 + true + false + false + false + true + false + true + false + false + false + false + true + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + high-resolution + true + 2040775 + false + false + false + + + true + + false + false + false + true + true + true + false + 0 + true + false + true + false + true + false + false + true + true + false + false + false + false + true + true + true + + false + false + true + 0 + false + true + + false + false + true + true + false + false + false + 1 + true + true + true + false + false + true + false + false + true + false + true + false + false + + true + 2246101 + true + false + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Quis pretium semper. Proin luctus orci a neque venenatis, quis commodo dolorsi + + + diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index 1f9358147e9f..852a213fbc03 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -389,6 +389,32 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf163042) CPPUNIT_ASSERT_EQUAL(static_cast(158), aPosition.GetContentIndex()); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf163060) +{ + createSwDoc("tdf163060.fodt"); + + // Ensure that all text portions are calculated before testing. + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwViewShell* pViewShell + = pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell(); + CPPUNIT_ASSERT(pViewShell); + pViewShell->Reformat(); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // There is only a single shrunk line 1, without breaking the last word + // before the last text portion "i" + + // This ends in "dolorsi" (not "dolors", as before) + assertXPath( + pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr, "portion"_ostr, + u"Quis pretium semper. Proin luctus orci a neque venenatis, quis commodo dolorsi"_ustr); + + // no second line (there was a second line with the text portion "i"). + assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf162109) { createSwDoc("tdf162109.fodt"); diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index f0867a2557a6..a9bd581a63ad 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -194,7 +194,9 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, { static constexpr OUStringLiteral STR_BLANK = u" "; sal_Int16 nSpaceWidth = rInf.GetTextSize(STR_BLANK).Width(); - nLineWidth += nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth); + SwTwips nExtraSpace = nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth); + nLineWidth += nExtraSpace; + rInf.SetExtraSpace(nExtraSpace); } if ( rInf.GetLen() < nMaxLen ) diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index 38f51bb74468..8471cf8282d5 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -220,6 +220,7 @@ SwTextSizeInfo::SwTextSizeInfo() , m_bForbiddenChars(false) , m_bSnapToGrid(false) , m_nDirection(0) +, m_nExtraSpace(0) {} SwTextSizeInfo::SwTextSizeInfo( const SwTextSizeInfo &rNew ) @@ -250,7 +251,8 @@ SwTextSizeInfo::SwTextSizeInfo( const SwTextSizeInfo &rNew ) m_bScriptSpace( rNew.HasScriptSpace() ), m_bForbiddenChars( rNew.HasForbiddenChars() ), m_bSnapToGrid( rNew.SnapToGrid() ), - m_nDirection( rNew.GetDirection() ) + m_nDirection( rNew.GetDirection() ), + m_nExtraSpace( rNew.GetExtraSpace() ) { #if OSL_DEBUG_LEVEL > 0 ChkOutDev( *this ); @@ -262,6 +264,7 @@ void SwTextSizeInfo::CtorInitTextSizeInfo( OutputDevice* pRenderContext, SwTextF { m_pKanaComp = nullptr; m_nKanaIdx = 0; + m_nExtraSpace = 0; m_pFrame = pFrame; CtorInitTextInfo( m_pFrame ); SwDoc const& rDoc(m_pFrame->GetDoc()); @@ -362,7 +365,8 @@ SwTextSizeInfo::SwTextSizeInfo( const SwTextSizeInfo &rNew, const OUString* pTex m_bScriptSpace( rNew.HasScriptSpace() ), m_bForbiddenChars( rNew.HasForbiddenChars() ), m_bSnapToGrid( rNew.SnapToGrid() ), - m_nDirection( rNew.GetDirection() ) + m_nDirection( rNew.GetDirection() ), + m_nExtraSpace( rNew.GetExtraSpace() ) { #if OSL_DEBUG_LEVEL > 0 ChkOutDev( *this ); diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index 461d7a1261eb..8576ed5c8707 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -175,6 +175,7 @@ protected: bool m_bForbiddenChars : 1; // Forbidden start/endline characters bool m_bSnapToGrid : 1; // paragraph snaps to grid sal_uInt8 m_nDirection : 2; // writing direction: 0/90/180/270 degree + SwTwips m_nExtraSpace; // extra space before shrinking = nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth) protected: void CtorInitTextSizeInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame, @@ -300,6 +301,10 @@ public: bool HasHint(TextFrameIndex nPos) const; + // extra space before shrinking = nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth) + void SetExtraSpace(SwTwips nVal) { m_nExtraSpace = nVal; } + SwTwips GetExtraSpace() const { return m_nExtraSpace; } + // If Kana Compression is enabled, a minimum and maximum portion width // is calculated. We format lines with minimal size and share remaining // space among compressed kanas. diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 3317ca05725e..752aadb5ffb8 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -2123,6 +2123,7 @@ TextFrameIndex SwTextFormatter::FormatLine(TextFrameIndex const nStartPos) } } GetInfo().ResetMaxWidthDiff(); + GetInfo().SetExtraSpace(0); // delete old rest if ( GetInfo().GetRest() ) diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 4c71e5da2c29..b310ee706cb5 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -514,7 +514,7 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) bool SwTextPortion::Format( SwTextFormatInfo &rInf ) { // GetLineWidth() takes care of DocumentSettingId::TAB_OVER_MARGIN. - if( rInf.GetLineWidth() < 0 || (!GetLen() && !InExpGrp()) ) + if( rInf.GetLineWidth() + rInf.GetExtraSpace() < 0 || (!GetLen() && !InExpGrp()) ) { Height( 0 ); Width( 0 );