sw/qa/core/text/data/redline-bullet.docx |binary
 sw/qa/core/text/porfld.cxx               |   35 +++++++++++++++++++++++++++++++
 sw/source/core/layout/paintfrm.cxx       |    9 ++-----
 sw/source/core/text/porfld.cxx           |    4 ---
 sw/source/core/text/porfld.hxx           |    2 +
 sw/source/core/text/porfly.cxx           |    4 ---
 sw/source/core/text/txttab.cxx           |   11 +++++++--
 7 files changed, 51 insertions(+), 14 deletions(-)

New commits:
commit 7a721aa9b99a1a3f2587233984cdcbbda7847028
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri Feb 6 14:27:09 2026 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Mon Feb 9 09:23:53 2026 +0100

    cool#13988 sw redline render mode: handle tab portions
    
    Open the bugdoc, switch to non-standard redline render mode (e.g.
    dispatch .uno:RedlineRenderMode), the tab portion in the second line
    should not be crossed out, but it is.
    
    What happens is similar to number portions, but here the tab portion
    doesn't have its own font, it conditionally inherits the font of the
    previous number portion.
    
    Fix this by improving SwTabPortion::Paint() to use the new
    GetRedlineRenderModeFont() of the number portion when we're in
    non-standard redline render mode.
    
    Also simplify some existing checks for getting the redline render mode,
    now that I found that SwTextSizeInfo::GetOpt() gives you a
    SwViewOption&.
    
    Change-Id: I1bd5aca7705de6641630439f6ff83a73a7fba8b2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198838
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sw/qa/core/text/data/redline-bullet.docx 
b/sw/qa/core/text/data/redline-bullet.docx
new file mode 100644
index 000000000000..0830adca71a5
Binary files /dev/null and b/sw/qa/core/text/data/redline-bullet.docx differ
diff --git a/sw/qa/core/text/porfld.cxx b/sw/qa/core/text/porfld.cxx
index 6ab3d3f3c550..67b36a596292 100644
--- a/sw/qa/core/text/porfld.cxx
+++ b/sw/qa/core/text/porfld.cxx
@@ -66,6 +66,41 @@ CPPUNIT_TEST_FIXTURE(Test, 
testNumberPortionRedlineRenderMode)
     // i.e. there was an unexpected underline.
     CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aUnderline);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTabPortionRedlineRenderMode)
+{
+    // Given a document with redlines, the tab number portion is deleted:
+    createSwDoc("redline-bullet.docx");
+    SwDocShell* pDocShell = getSwDocShell();
+
+    // When redline render mode is standard:
+    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    // Then make sure we paint a strikeout:
+    MetafileXmlDump aDumper;
+    xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
+    assertXPath(pXmlDoc, "//stretchtext", 1);
+    OUString aStrikeout
+        = getXPath(pXmlDoc, "(//stretchtext)[1]/preceding-sibling::font[1]", 
"strikeout");
+    CPPUNIT_ASSERT_EQUAL(u"1"_ustr, aStrikeout);
+
+    // And given "omit inserts" redline render mode:
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    SwViewOption aOpt(*pWrtShell->GetViewOptions());
+    aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitInserts);
+    pWrtShell->ApplyViewOptions(aOpt);
+
+    // When rendering:
+    xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    // Then make sure we don't paint a strikeout:
+    pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 1
+    // i.e. the stretched text was painted, which used a strikeout font.
+    assertXPath(pXmlDoc, "//stretchtext", 0);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index d89437ee530f..398786e5da05 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4276,6 +4276,9 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& 
rRenderContext, SwRect const&
         }
     }
 
+    const SwViewOption* pViewOptions = pShell ? pShell->GetViewOptions() : 
nullptr;
+    SwRedlineRenderMode eRedlineRenderMode
+        = pViewOptions ? pViewOptions->GetRedlineRenderMode() : 
SwRedlineRenderMode::Standard;
     {
         bool bContour = GetFormat()->GetSurround().IsContour();
         tools::PolyPolygon aPoly;
@@ -4322,9 +4325,6 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& 
rRenderContext, SwRect const&
             }
         }
         // paint of margin needed.
-        const SwViewOption* pViewOptions = pShell ? pShell->GetViewOptions() : 
nullptr;
-        SwRedlineRenderMode eRedlineRenderMode = pViewOptions ? 
pViewOptions->GetRedlineRenderMode()
-            : SwRedlineRenderMode::Standard;
         const bool bPaintMarginOnly( !bPaintCompleteBack &&
                                      (getFramePrintArea().SSize() != 
getFrameArea().SSize() || eRedlineRenderMode != SwRedlineRenderMode::Standard));
 
@@ -4496,9 +4496,6 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& 
rRenderContext, SwRect const&
     PaintDecorators();
 
     // crossing out for tracked deletion
-    const SwViewOption* pViewOptions = pShell->GetViewOptions();
-    SwRedlineRenderMode eRedlineRenderMode
-        = pViewOptions ? pViewOptions->GetRedlineRenderMode() : 
SwRedlineRenderMode::Standard;
     if (GetAuthor() != std::string::npos && IsDeleted()
         && eRedlineRenderMode == SwRedlineRenderMode::Standard)
     {
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index 3fad80b27316..c3690ed3b52e 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -741,9 +741,7 @@ void SwNumberPortion::Paint( const SwTextPaintInfo &rInf ) 
const
                         STRIKEOUT_NONE != m_pFont->GetStrikeout() ) &&
                         !m_pFont->IsWordLineMode();
 
-    const SwViewShell* pViewShell = rInf.GetVsh();
-    const SwViewOption* pViewOptions = pViewShell ? 
pViewShell->GetViewOptions() : nullptr;
-    SwRedlineRenderMode eRedlineRenderMode = pViewOptions ? 
pViewOptions->GetRedlineRenderMode() : SwRedlineRenderMode::Standard;
+    SwRedlineRenderMode eRedlineRenderMode = 
rInf.GetOpt().GetRedlineRenderMode();
     SwFont* pFont = m_pFont.get();
     if (eRedlineRenderMode != SwRedlineRenderMode::Standard)
     {
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
index 211f33f4d41a..8d0378804c32 100644
--- a/sw/source/core/text/porfld.hxx
+++ b/sw/source/core/text/porfld.hxx
@@ -37,6 +37,7 @@ class SwFieldPortion : public SwExpandPortion
 protected:
     OUString  m_aExpand;          // The expanded field
     std::unique_ptr<SwFont> m_pFont;  // For multi-line fields
+    /// This is used when the view's redline render mode is not standard.
     std::unique_ptr<SwFont> m_pRedlineRenderModeFont;
     TextFrameIndex m_nNextOffset;  // Offset of the follow in the original 
string
     TextFrameIndex m_nNextScriptChg;
@@ -68,6 +69,7 @@ public:
     bool HasFont() const { return nullptr != m_pFont; }
     // #i89179# - made public
     const SwFont *GetFont() const { return m_pFont.get(); }
+    const SwFont *GetRedlineRenderModeFont() const { return 
m_pRedlineRenderModeFont.get(); }
 
     const OUString& GetExp() const { return m_aExpand; }
     virtual bool GetExpText( const SwTextSizeInfo &rInf, OUString &rText ) 
const override;
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index 5b5b64bfccd9..9b3981a77863 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -241,9 +241,7 @@ void sw::FlyContentPortion::Paint(const SwTextPaintInfo& 
rInf) const
 
         // track changes: cross out the image, if it is deleted
         const SwFrame *pFrame = m_pFly->Lower();
-        const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
-        SwRedlineRenderMode eRedlineRenderMode
-            = pViewOptions ? pViewOptions->GetRedlineRenderMode() : 
SwRedlineRenderMode::Standard;
+        SwRedlineRenderMode eRedlineRenderMode = 
rInf.GetOpt().GetRedlineRenderMode();
         if (GetAuthor() != std::string::npos && IsDeleted() && pFrame
             && eRedlineRenderMode == SwRedlineRenderMode::Standard)
         {
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
index 22502f918a6d..c7ae1bc27655 100644
--- a/sw/source/core/text/txttab.cxx
+++ b/sw/source/core/text/txttab.cxx
@@ -593,8 +593,15 @@ void SwTabPortion::Paint( const SwTextPaintInfo &rInf ) 
const
              pPrevPortion->InNumberGrp() &&
              static_cast<const SwNumberPortion*>(pPrevPortion)->HasFont() )
         {
-            const SwFont* pNumberPortionFont =
-                    static_cast<const 
SwNumberPortion*>(pPrevPortion)->GetFont();
+            SwRedlineRenderMode eRedlineRenderMode = 
rInf.GetOpt().GetRedlineRenderMode();
+            auto pPrevNumberPortion = static_cast<const 
SwNumberPortion*>(pPrevPortion);
+            const SwFont* pNumberPortionFont = pPrevNumberPortion->GetFont();
+            if (eRedlineRenderMode != SwRedlineRenderMode::Standard)
+            {
+                // The number portion uses a font specific to the redline 
render mode, do the same
+                // for the subsequent tab portion, too.
+                pNumberPortionFont = 
pPrevNumberPortion->GetRedlineRenderModeFont();
+            }
             oSave.emplace( rInf, const_cast<SwFont*>(pNumberPortionFont) );
             bAfterNumbering = true;
         }

Reply via email to