sw/qa/extras/layout/data/tdf158658c.rtf |   26 ++++++++++++++++++++++++++
 sw/qa/extras/layout/layout3.cxx         |   22 ++++++++++++++++++++++
 sw/source/core/text/portab.hxx          |    2 +-
 sw/source/core/text/txttab.cxx          |    9 +++++----
 4 files changed, 54 insertions(+), 5 deletions(-)

New commits:
commit 3822db0a7494d8081b04d80b1f1d797f2b71ef0e
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Jun 13 15:46:31 2024 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Jun 14 19:43:20 2024 +0200

    tdf#158658 sw: text formatting: make TabOverMargin even more crazy
    
    ... to better match Word's formatting.
    
    The bugdoc has a special case where a right-aligned tab is positioned at
    the right margin exactly, which causes the bFull condition in
    SwTabPortion::PreFormat() to be true.
    
    An obvious change to replace rInf.Width() - rInf.X() with
    rInf.GetLineWidth() in the condition makes no difference because
    m_pLastTab was already reset previously; instead, pass in the last tab
    from Format(), which indicates that the right edge position of the
    previous text portion was found via that tab.
    
    Additionally, change the condition that checks for TabOverMargin to also
    allow equal positions, i.e., exactly at the end of the paragraph.
    
    Change-Id: I5d3b1c13eca0bffa640745d7c5f4113699f79cad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168823
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 69d873e1c46f3cc8c524e18ac5a307a8d32ddd0f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168864
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/sw/qa/extras/layout/data/tdf158658c.rtf 
b/sw/qa/extras/layout/data/tdf158658c.rtf
new file mode 100644
index 000000000000..4148eb6d9a51
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf158658c.rtf
@@ -0,0 +1,26 @@
+{ 
tf1deflang1025nsinsicpg1250\uc1deff31507\deff0\stshfdbch31506\stshfloch31506\stshfhich31506\stshfbi31507\deflang1038\deflangfe1038
       hemelang1038    hemelangfe0     hemelangcs0
+{onttbl{0bidi romancharset0prq2 Times New Roman;}
+{himinor31506bidi swisscharset0prq2 Calibri;}
+{biminor31507bidi romancharset0prq2 Times New Roman;}
+}
+{\*\defchp 31506s22\lang1038\langfe1033\langfenp1033 }{\*\defpap \ql \li0 
i0\sa160\sl259\slmult1
+\widctlpar\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0 }
oqfpromote
+{\stylesheet{\ql \li0 
i0\sa160\sl259\slmult1\widctlpar\wrapdefaultspalphaspnumaautodjustright 
in0\lin0\itap0  tlchcs1 f31507fs22lang1025 
+\ltrchcs0 31506s22\lang1038\langfe1033+{\s15\ql \li0 i0\widctlpar   qc      
x4513   qr      x9026\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0 
 tlchcs1 f31507fs22lang1025 \ltrchcs0 31506
s22\lang1038\langfe1033+\sbasedon0 \snext15 \slink16 \sunhideused header;}}
+\paperw11906\paperh16838\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
 
+\deftab708\widowctrltnbjenddoc\hyphhotz425   rackmoves0      
rackformatting1\donotembedsysfont1 elyonvml0\donotembedlingdata0\grfdocevents0
alidatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
+\showxmlerrors1
oxlattoyenxpshrtn
oultrlspc\dntblnsbdb
ospaceforul
ormshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1
+\jexpandiewkind1iewscale100\pgbrdrhead\pgbrdrfoot\splytwnine
tnlytwnine\htmautsp
olnhtadjtbl\useltbalnlntblind\lytcalctblwd\lyttblrtgr\lnbrkrule
obrkwrptbl\snaptogridincellllowfieldendsel\wrppunct
+sianbrkrule
ewtblstyruls
ogrowautofit\usenormstyforlist
oindnmbrtselnbrelev
ocxsptable\indrlsweleven
oafcnsttblfelev\utinl\hwelev\spltpgpar
otcvasp
otbrkcnstfrctbl
otvatxbx\krnprsnet+
ofeaturethrottle1\ilfomacatclnup0
+\ltrpar \sectd \ltrsect\linex0\headery708ootery708+   qc      x4513   qr      
x9026\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0  tlchcs1 
f31507fs22lang1025 \ltrchcs0 31506s22\lang1038\langfe1033+      ab World  
      ab Here come some tabs: ab      ab      ab      ab      ab      ab      
ab      ab      ab      ab      ab      ab      ab      ab      ab      ab      
ab      ab      ab      ab 
+\par }}
+\pard\plain \ltrpar\ql \li0 i0\sa160\sl259\slmult1
+\widctlpar\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0  tlchcs1 
f31507fs22lang1025 \ltrchcs0 31506s22\lang1038\langfe1033+ tlchcs1 
f31507 \ltrchcs0 
+\par }
+}
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index bd7758159895..8c55a4ad772e 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -453,6 +453,28 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158658b)
         0);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158658c)
+{
+    createSwDoc("tdf158658c.rtf");
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    // Word 2013 puts all tabs into one line, the last 17 of them are off the 
page
+    assertXPath(pXmlDoc, 
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1);
+    assertXPath(
+        pXmlDoc,
+        
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabCenter']"_ostr,
+        1);
+    // the right tab is exactly at the margin of the paragraph
+    assertXPath(
+        pXmlDoc,
+        
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabRight']"_ostr,
+        1);
+    assertXPath(
+        pXmlDoc,
+        
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabLeft']"_ostr,
+        20);
+}
+
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf155177)
 {
     createSwDoc("tdf155177-1-min.odt");
diff --git a/sw/source/core/text/portab.hxx b/sw/source/core/text/portab.hxx
index 9ffe7be50651..42c21204c7b7 100644
--- a/sw/source/core/text/portab.hxx
+++ b/sw/source/core/text/portab.hxx
@@ -27,7 +27,7 @@ class SwTabPortion : public SwFixPortion
     const bool m_bAutoTabStop;
 
     // Format() branches either into PreFormat() or PostFormat()
-    bool PreFormat( SwTextFormatInfo &rInf );
+    bool PreFormat(SwTextFormatInfo &rInf, SwTabPortion const*);
 public:
     SwTabPortion( const sal_uInt16 nTabPos, const sal_Unicode cFill, const 
bool bAutoTab = true );
     virtual void Paint( const SwTextPaintInfo &rInf ) const override;
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
index 3f72f5375000..c34692e0024a 100644
--- a/sw/source/core/text/txttab.cxx
+++ b/sw/source/core/text/txttab.cxx
@@ -345,7 +345,7 @@ bool SwTabPortion::Format( SwTextFormatInfo &rInf )
         return PostFormat( rInf );
     if( pLastTab )
         pLastTab->PostFormat( rInf );
-    return PreFormat( rInf );
+    return PreFormat(rInf, pLastTab);
 }
 
 void SwTabPortion::FormatEOL( SwTextFormatInfo &rInf )
@@ -354,7 +354,7 @@ void SwTabPortion::FormatEOL( SwTextFormatInfo &rInf )
         PostFormat( rInf );
 }
 
-bool SwTabPortion::PreFormat( SwTextFormatInfo &rInf )
+bool SwTabPortion::PreFormat(SwTextFormatInfo &rInf, SwTabPortion const*const 
pLastTab)
 {
     OSL_ENSURE( rInf.X() <= GetTabPos(), "SwTabPortion::PreFormat: rush hour" 
);
 
@@ -396,7 +396,8 @@ bool SwTabPortion::PreFormat( SwTextFormatInfo &rInf )
     // 1. Minimal width does not fit to line anymore.
     // 2. An underflow event was called for the tab portion.
     bool bFull = ( bTabCompat && rInf.IsUnderflow() ) ||
-                     ( rInf.Width() <= rInf.X() + PrtWidth() && rInf.X() <= 
rInf.Width() ) ;
+             (rInf.Width() <= rInf.X() + PrtWidth() && rInf.X() <= rInf.Width()
+              && (!bTabOverMargin || !pLastTab));
 
     // #95477# Rotated tab stops get the width of one blank
     const Degree10 nDir = rInf.GetFont()->GetOrientation( 
rInf.GetTextFrame()->IsVertical() );
@@ -420,7 +421,7 @@ bool SwTabPortion::PreFormat( SwTextFormatInfo &rInf )
             {
                 // handle this case in PostFormat
                 if ((bTabOverMargin || bTabOverSpacing) && GetTabPos() > 
rInf.Width()
-                    && (!m_bAutoTabStop || rInf.X() > rInf.Width()))
+                    && (!m_bAutoTabStop || rInf.Width() <= rInf.X()))
                 {
                     if (bTabOverMargin || GetTabPos() < nTextFrameWidth)
                     {

Reply via email to