From 53de98b29548ded88e0a44c80256fc5e340d551e Mon Sep 17 00:00:00 2001 From: László Németh Date: Thu, 23 Nov 2023 14:01:10 +0100 Subject: tdf#158333 sw smart justify: fix multiple text portions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple text portions, e.g. if some part of a line contains direct character formatting breaks DOCX interoperability of justified paragraphs. Follow-up to commit 17eaebee279772b6062ae3448012133897fc71bb "tdf#119908 sw smart justify: fix justification by shrinking". Change-Id: Ia53e763fdba89bb733bde088874e641b25d733f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159862 Tested-by: Jenkins Reviewed-by: László Németh --- sw/qa/extras/layout/layout3.cxx | 36 ++++++++++++++++++++++++++++++++++++ sw/source/core/text/guess.cxx | 2 +- sw/source/core/text/porlin.cxx | 4 ++-- sw/source/core/text/portxt.cxx | 3 ++- 4 files changed, 41 insertions(+), 4 deletions(-) (limited to 'sw') diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index 797b41fc7baf..dc70bf41b6f8 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -201,6 +201,42 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf119908) CPPUNIT_ASSERT_GREATER(sal_Int32(5840), nPortionWidth); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333) +{ + createSwDoc("tdf130088.docx"); + // 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(); + + // shrink line 2 + assertXPath( + pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion", + "viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. "); + + // shrink line 7 + assertXPath( + pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[7]", "portion", + // This was "...diam ", not "...diam tempor " + "laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor "); + + // shrink line 2 of paragraph 2 + assertXPath( + pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]", "portion", + // This was "...Cras ", not "...Cras sodales " + "Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales "); + + // shrink line 2 of paragraph 4 + assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout[2]", "portion", + // This was "...et ", not "...et magnis " + "consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis "); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf106234) { createSwDoc("tdf106234.fodt"); diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index 6d92b64d9fce..5e66b366c63f 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -85,7 +85,7 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING)) { // allow up to 2% shrinking of the line - nLineWidth /= 0.98; + nLineWidth = nLineWidth / 0.98 + rInf.X() / 0.98 - rInf.X(); } // tdf#104668 space chars at the end should be cut if the compatibility option is enabled diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx index fdd0ffba53b9..6d0992f1abf6 100644 --- a/sw/source/core/text/porlin.cxx +++ b/sw/source/core/text/porlin.cxx @@ -276,9 +276,9 @@ void SwLinePortion::Move(SwTextPaintInfo & rInf) const bool bCounterDir = ( ! bFrameDir && DIR_RIGHT2LEFT == rInf.GetDirection() ) || ( bFrameDir && DIR_LEFT2RIGHT == rInf.GetDirection() ); - if ( InSpaceGrp() && rInf.GetSpaceAdd() ) + if ( InSpaceGrp() && rInf.GetSpaceAdd(/*bShrink=*/true) ) { - SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(), rInf ); + SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(/*bShrink=*/true), rInf ); if( rInf.IsRotated() ) rInf.Y( rInf.Y() + ( bB2T ? -nTmp : nTmp ) ); else if ( bCounterDir ) diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 1e2f8d1823d0..ff6d40cd4d95 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -668,7 +668,8 @@ tools::Long SwTextPortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeI } } - return sal_Int32(nCnt) * nSpaceAdd / SPACING_PRECISION_FACTOR; + return sal_Int32(nCnt) * (nSpaceAdd > LONG_MAX/2 ? LONG_MAX/2 - nSpaceAdd : nSpaceAdd) + / SPACING_PRECISION_FACTOR; } void SwTextPortion::HandlePortion( SwPortionHandler& rPH ) const -- cgit