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(-)

New commits:
commit 53de98b29548ded88e0a44c80256fc5e340d551e
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Nov 23 14:01:10 2023 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Nov 27 14:48:19 2023 +0100

    tdf#158333 sw smart justify: fix multiple text portions
    
    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 <nem...@numbertext.org>

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<SwXTextDocument*>(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

Reply via email to