From bcadc9a6ec5be2541e259f0fa18022c0661c8df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20N=C3=A9meth?= Date: Sat, 31 Aug 2024 15:47:17 +0200 Subject: [PATCH] tdf#162725 sw smart justify: fix last line with multiple portions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix last lines of paragraphs, which contains multiple portions, and exceeded the width of the paragraph because of missing space shrinking. Follow-up to commit 6b857398a59d16308d6185d01e003e401439f060 "tdf#162109 sw smart justify: fix overhanging last line" and commit 22eac3145ca62d15b47d95f4df60ce38d4f5aa46 "tdf#162220 sw smart justify: fix shrinking for single portion lines". This reverts (and improves) the code removed in tdf#162220 (commit 22eac3145ca62d15b47d95f4df60ce38d4f5aa46), because that code still needs for lines with multiple portions. Change-Id: Id87d87defc79742513ceb0f90b83e6d4f0e4b271 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172692 Tested-by: Jenkins Reviewed-by: László Németh --- sw/qa/extras/layout/data/tdf162725.fodt | 210 ++++++++++++++++++++++++ sw/qa/extras/layout/layout3.cxx | 17 ++ sw/source/core/text/itradj.cxx | 24 +++ 3 files changed, 251 insertions(+) create mode 100644 sw/qa/extras/layout/data/tdf162725.fodt diff --git a/sw/qa/extras/layout/data/tdf162725.fodt b/sw/qa/extras/layout/data/tdf162725.fodt new file mode 100644 index 000000000000..e9f3a76ff488 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf162725.fodt @@ -0,0 +1,210 @@ + + + + 2024-08-21T13:39:32.127488353PT2M47S2LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/c2a186c8c116a059796ca179e252b4feb9829950 + + + 0 + 0 + 27481 + 16293 + true + false + + + view2 + 5039 + 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 + 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 + 2157109 + true + false + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolors. + + + diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index 21f491b1248a..563d7c5be100 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -377,6 +377,23 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf162220) assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwGluePortion"_ostr); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf162725) +{ + createSwDoc("tdf162725.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 was no SwGluePortion, because of missing justification of the last paragraph line, + // despite it is a full line with shrunk spaces + assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwGluePortion"_ostr); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf132599_always) { uno::Reference xHyphenator = LinguMgr::GetHyphenator(); diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx index 277359ff25d1..169ddb1943ba 100644 --- a/sw/source/core/text/itradj.cxx +++ b/sw/source/core/text/itradj.cxx @@ -49,6 +49,30 @@ void SwTextAdjuster::FormatBlock( ) m_pCurr->ExtraShrunkWidth() <= m_pCurr->Width() && m_nStart + m_pCurr->GetLen() >= TextFrameIndex(GetInfo().GetText().getLength()); + // tdf#162725 if the last line is longer, than the paragraph width, + // it contains shrinking spaces: don't skip block format here + if( bSkip ) + { + // sum width of the text portions to calculate the line width without shrinking + tools::Long nBreakWidth = 0; + const SwLinePortion *pPos = m_pCurr->GetNextPortion(); + while( pPos && bSkip ) + { + if( !pPos->InGlueGrp() && + // don't calculate with the terminating space, + // otherwise it would result justified line mistakenly + ( pPos->GetNextPortion() || !pPos->IsHolePortion() ) ) + { + nBreakWidth += pPos->Width(); + } + + if( nBreakWidth > m_pCurr->Width() ) + bSkip = false; + + pPos = pPos->GetNextPortion(); + } + } + // Multi-line fields are tricky, because we need to check whether there are // any other text portions in the paragraph. if( bSkip )