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 edef9fffa00bddb8f03ef00e6b693c967a15b28f
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri Feb 6 14:27:09 2026 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Mon Feb 9 13:23:46 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/+/198970
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins

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 efbe61a2ac02..8560f507c53e 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4277,6 +4277,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;
@@ -4323,9 +4326,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));
 
@@ -4493,9 +4493,6 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& 
rRenderContext, SwRect const&
     PaintDecorators();
 
     // crossing out for tracked deletion
-    const SwViewOption* pViewOptions = pShell ? pShell->GetViewOptions() : 
nullptr;
-    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 7eb0cf6391fd..e0958971f770 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -753,9 +753,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 8d31c000487b..275f1120e330 100644
--- a/sw/source/core/text/porfld.hxx
+++ b/sw/source/core/text/porfld.hxx
@@ -39,6 +39,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;
@@ -70,6 +71,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 95c135276e83..3f333b05517c 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -242,9 +242,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