sw/qa/extras/ooxmlexport/ooxmlexport16.cxx |    6 ++++++
 sw/source/core/text/txttab.cxx             |   23 +++++++++++++++++++----
 2 files changed, 25 insertions(+), 4 deletions(-)

New commits:
commit b85491e40ccb83ff78c7c4b2c0d535eafa5d23ed
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Fri Jun 11 16:19:12 2021 +0200
Commit:     Justin Luth <justin_l...@sil.org>
CommitDate: Sat Jun 19 20:13:49 2021 +0200

    tdf#142404 DOCX c15: handle remaining TabOverSpacing tabs
    
    The previous commit handled the case where a non-first
    LEFT tab was beyond the text area. But the remaining
    cases were still being (mis)treated as automatic tabs.
    
    We won't worry about the impact where compatibilityMode
    is less than 15/2013+ since Word is absolutely goofy,
    and LO doesn't even come close to matching it.
    
    But in compat15 mode, the end result of having a
    non-LEFT tab over the margin effecively means that
    the text will flow backwards from the right margin,
    just as if it was a RIGHT tabstop. So treat all of
    the remaining tabs as a right-tab at the end of
    the paragraph-area.
    
    Change-Id: I43a38516c0639c56341bdba0213ffb4a7d5cbf3c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117340
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index 408f0e608da0..5d567543bcec 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -254,6 +254,12 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf142404_tabOverSpacingC15, "tdf142404_
     CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Big tab: full paragraph area used", 
737, nLineWidth, 100);
 
     // Pages 2/3 are TabOverMargin - in this particular case tabs should not 
go over margin.
+    CPPUNIT_ASSERT_EQUAL(OUString("A right tab positioned at"), 
parseDump("//page[2]/body/txt[6]/Text[1]", "Portion"));
+    sal_Int32 nParaWidth = parseDump("//page[2]/body/txt[6]/infos/prtBounds", 
"width").toInt32();
+    // the clearest non-first-line visual example is this second tab in the 
right-tab paragraph.
+    nLineWidth = parseDump("//page[2]/body/txt[6]/LineBreak[4]", 
"nWidth").toInt32();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Full paragraph area used", nLineWidth, 
nParaWidth);
+
     CPPUNIT_ASSERT_EQUAL(OUString("TabOverflow does what?"), 
parseDump("//page[3]/body/txt[2]/Text[1]", "Portion"));
     // Not 1 line high (Word 2010 DOCX and ODT), or 4 lines high (prev LO 
DOCX),
     // but 8 lines high.
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
index 4039509dd4ae..d3319dea4a7a 100644
--- a/sw/source/core/text/txttab.cxx
+++ b/sw/source/core/text/txttab.cxx
@@ -131,6 +131,7 @@ SwTabPortion *SwTextFormatter::NewTabPortion( 
SwTextFormatInfo &rInf, bool bAuto
         }
 
         SwTwips nNextPos = 0;
+        bool bAbsoluteNextPos = false;
 
         // #i24363# tab stops relative to indent
         // nSearchPos: The current position relative to the tabs origin
@@ -149,8 +150,7 @@ SwTabPortion *SwTextFormatter::NewTabPortion( 
SwTextFormatInfo &rInf, bool bAuto
         const SvxTabStop* pTabStop = m_aLineInf.GetTabStop( nSearchPos, 
nMyRight );
         if (!nMyRight)
             nMyRight = nOldRight;
-        if (pTabStop &&
-            (pTabStop->GetTabPos() <= nMyRight || pTabStop->GetAdjustment() == 
SvxTabAdjust::Left))
+        if (pTabStop)
         {
             cFill = ' ' != pTabStop->GetFill() ? pTabStop->GetFill() : 0;
             cDec = pTabStop->GetDecimal();
@@ -161,6 +161,21 @@ SwTabPortion *SwTextFormatter::NewTabPortion( 
SwTextFormatInfo &rInf, bool bAuto
                 //calculate default tab position of default tabs in negative 
indent
                 nNextPos = ( nSearchPos / nNextPos ) * nNextPos;
             }
+            else if (pTabStop->GetTabPos() > nMyRight
+                     && pTabStop->GetAdjustment() != SvxTabAdjust::Left)
+            {
+                // A rather special situation. The tabstop found is:
+                // 1.) in a document compatible with MS formats
+                // 2.) not a left tabstop.
+                // 3.) not the first tabstop (in that case nMyRight was 
adjusted to match tabPos).
+                // 4.) beyond the end of the text area
+                // Therefore, they act like right-tabstops at the edge of the 
para area.
+                // This benefits DOCX 2013+, and doesn't hurt the earlier 
formats,
+                // since up till now these were just treated as automatic 
tabstops.
+                eAdj = SvxTabAdjust::Right;
+                bAbsoluteNextPos = true;
+                nNextPos = rInf.Width();
+            }
             bAutoTabStop = false;
         }
         else
@@ -196,7 +211,6 @@ SwTabPortion *SwTextFormatter::NewTabPortion( 
SwTextFormatInfo &rInf, bool bAuto
             }
             cFill = 0;
             eAdj = SvxTabAdjust::Left;
-            pTabStop = nullptr;
         }
 
         // #i115705# - correction and refactoring:
@@ -265,7 +279,8 @@ SwTabPortion *SwTextFormatter::NewTabPortion( 
SwTextFormatInfo &rInf, bool bAuto
             }
         }
 
-        nNextPos += bRTL ? nLinePos - nTabLeft : nTabLeft - nLinePos;
+        if (!bAbsoluteNextPos)
+            nNextPos += bRTL ? nLinePos - nTabLeft : nTabLeft - nLinePos;
         OSL_ENSURE( nNextPos >= 0, "GetTabStop: Don't go back!" );
         nNewTabPos = sal_uInt16(nNextPos);
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to