sw/qa/core/text/data/redline-image-inline.docx |binary
 sw/qa/core/text/itrpaint.cxx                   |  158 +++++++++++++++++++------
 sw/source/core/inc/flyfrm.hxx                  |    2 
 sw/source/core/layout/fly.cxx                  |   42 ++++++
 sw/source/core/layout/paintfrm.cxx             |   26 +++-
 sw/source/core/text/porfly.cxx                 |   10 +
 sw/source/core/text/porlay.cxx                 |   14 ++
 7 files changed, 209 insertions(+), 43 deletions(-)

New commits:
commit 1efc9e16320153681e387499349f340b7ec57787
Author:     Miklos Vajna <[email protected]>
AuthorDate: Tue Jan 27 08:48:48 2026 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Jan 29 13:29:52 2026 +0100

    cool#13988 sw redline render mode: add colored border for anchored images
    
    So far the non-standard redline render mode for images focused on
    graying out images when they are meant to be "omitted".
    
    In the meantime, text got red/green colors since commit
    9bc163b5637572684ac6cc5985d276c4bc01679f (cool#13574 sw redline render
    mode: somewhat color ins/del as green/red, 2026-01-20), for the case
    when the inserted/deleted text is not omitted.
    
    Do the same for images: if an anchored image is not omitted, then
    provide a red/green border for deleted/inserted images.
    
    This is for anchored images, inline images need more work. Two
    alternatives would have been to draw this border at the end of
    SwFlyFrame::PaintSwFrame() (like the standard redline mode does its
    cross for deletes, but doesn't work due to clipping problems) or as part
    of SwLayoutFrame::PaintSubsidiaryLines() (like the gray "boundary"
    indicator does, also has clipping problems). Doing it in
    SwFrame::PaintSwFrameShadowAndBorder() is free from these clipping
    problems.
    
    Change-Id: I7489e5be5c7081a8e6dc243cb30d8fd2dc4f1917
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198254
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198284

diff --git a/sw/qa/core/text/itrpaint.cxx b/sw/qa/core/text/itrpaint.cxx
index 479ba5a628bf..14c1af1a02b4 100644
--- a/sw/qa/core/text/itrpaint.cxx
+++ b/sw/qa/core/text/itrpaint.cxx
@@ -150,17 +150,41 @@ CPPUNIT_TEST_FIXTURE(Test, 
testRedlineRenderModeOmitInsertDelete)
     CPPUNIT_ASSERT_EQUAL(120, GetColorHue(aColor3));
 }
 
-bool IsGrayScale(const Bitmap& rBitmap)
+struct ImageInfo
 {
-    BitmapScopedReadAccess pReadAccess(rBitmap);
-    Size aSize = rBitmap.GetSizePixel();
+    Bitmap m_aBitmap;
+    tools::Rectangle m_aRectangle;
+};
+
+bool IsGrayScale(const ImageInfo& rInfo)
+{
+    Bitmap aBitmap = rInfo.m_aBitmap;
+    BitmapScopedReadAccess pReadAccess(aBitmap);
+    Size aSize = rInfo.m_aBitmap.GetSizePixel();
     Color aColor = pReadAccess->GetColor(aSize.getHeight() / 2, 
aSize.getWidth() / 2);
     return aColor.GetRed() == aColor.GetGreen() && aColor.GetRed() == 
aColor.GetBlue();
 }
 
-std::vector<Bitmap> GetMetaFileImages(const GDIMetaFile& rMetaFile)
+bool RectangleContainsPolygons(const tools::Rectangle& rRectangle,
+                               const std::vector<tools::Polygon>& rPolygons)
+{
+    static constexpr SwTwips nPixel = 15;
+    tools::Rectangle aRectangle(rRectangle.Left() - nPixel, rRectangle.Top() - 
nPixel,
+                                rRectangle.Right() + nPixel, 
rRectangle.Bottom() + nPixel);
+    for (const auto& rPolygon : rPolygons)
+    {
+        if (!aRectangle.Contains(rPolygon.GetBoundRect()))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+std::vector<ImageInfo> GetMetaFileImages(const GDIMetaFile& rMetaFile)
 {
-    std::vector<Bitmap> aImages;
+    std::vector<ImageInfo> aImages;
     for (size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction)
     {
         MetaAction* pAction = rMetaFile.GetAction(nAction);
@@ -170,11 +194,31 @@ std::vector<Bitmap> GetMetaFileImages(const GDIMetaFile& 
rMetaFile)
         }
 
         auto pAct = static_cast<MetaBmpExScaleAction*>(pAction);
-        aImages.push_back(pAct->GetBitmap());
+        ImageInfo aInfo;
+        aInfo.m_aBitmap = pAct->GetBitmap();
+        aInfo.m_aRectangle = { pAct->GetPoint(), pAct->GetSize() };
+        aImages.push_back(aInfo);
     }
     return aImages;
 }
 
+std::vector<tools::Polygon> GetMetaFilePolylines(const GDIMetaFile& rMetaFile)
+{
+    std::vector<tools::Polygon> aPolygons;
+    for (size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction)
+    {
+        MetaAction* pAction = rMetaFile.GetAction(nAction);
+        if (pAction->GetType() != MetaActionType::POLYLINE)
+        {
+            continue;
+        }
+
+        auto pAct = static_cast<MetaPolyLineAction*>(pAction);
+        aPolygons.push_back(pAct->GetPolygon());
+    }
+    return aPolygons;
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testAnchoredImageRedlineRenderModeOmitInsertDelete)
 {
     // Given a document with a normal, a deleted and an inserted image:
@@ -185,11 +229,14 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
     std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
 
     // Then make sure none of the images are grayscale:
-    std::vector<Bitmap> aImages = GetMetaFileImages(*xMetaFile);
+    std::vector<ImageInfo> aImages = GetMetaFileImages(*xMetaFile);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[2]));
+    std::vector<tools::Polygon> aPolygons = GetMetaFilePolylines(*xMetaFile);
+    // No frames around images.
+    CPPUNIT_ASSERT(aPolygons.empty());
 
     // Omit insert: default, default, grayscale.
     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
@@ -206,6 +253,10 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
     // Without the accompanying fix in place, this test would have failed, the 
image's center pixel
     // wasn't gray.
     CPPUNIT_ASSERT(IsGrayScale(aImages[2]));
+    aPolygons = GetMetaFilePolylines(*xMetaFile);
+    // Frame around the deleted image. This failed, there was no frame around 
the deleted image.
+    CPPUNIT_ASSERT(!aPolygons.empty());
+    CPPUNIT_ASSERT(RectangleContainsPolygons(aImages[1].m_aRectangle, 
aPolygons));
 
     // Omit deletes: default, grayscale, default.
     aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitDeletes);
@@ -218,6 +269,10 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(IsGrayScale(aImages[1]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[2]));
+    aPolygons = GetMetaFilePolylines(*xMetaFile);
+    // Frame around the inserted image.
+    CPPUNIT_ASSERT(!aPolygons.empty());
+    CPPUNIT_ASSERT(RectangleContainsPolygons(aImages[2].m_aRectangle, 
aPolygons));
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testInlineImageRedlineRenderModeOmitInsertDelete)
@@ -230,7 +285,7 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInlineImageRedlineRenderModeOmitInsertDelete)
     std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
 
     // Then make sure none of the images are grayscale:
-    std::vector<Bitmap> aImages = GetMetaFileImages(*xMetaFile);
+    std::vector<ImageInfo> aImages = GetMetaFileImages(*xMetaFile);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index 6b0982abf314..d5f8124af10b 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -313,6 +313,8 @@ public:
 
     bool IsSplitButNotYetMovedFollow() const;
 
+    bool GetRedlineRenderModeFrame(SvxBoxItem& rBoxItem) const;
+
 private:
     void UpdateUnfloatButton(SwWrtShell* pWrtSh, bool bShow) const;
     void PaintDecorators() const;
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 5d9f140adc7f..8e02d478681a 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -2332,6 +2332,48 @@ bool SwFlyFrame::IsSplitButNotYetMovedFollow() const
     return false;
 }
 
+bool SwFlyFrame::GetRedlineRenderModeFrame(SvxBoxItem& rBoxItem) const
+{
+    // If we're in non-standard redline mode, then color deletes and inserts 
depending on the
+    // redline render mode. Similar to what SwFntObj::DrawText() does for 
redlined text.
+    const SwViewShell* pViewShell = getRootFrame()->GetCurrShell();
+    if (!pViewShell)
+    {
+        return false;
+    }
+
+    const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
+    if (!pViewOptions)
+    {
+        return false;
+    }
+
+    SwRedlineRenderMode eRedlineRenderMode = 
pViewOptions->GetRedlineRenderMode();
+    std::optional<Color> oColor;
+    if (eRedlineRenderMode == SwRedlineRenderMode::OmitInserts && IsDeleted())
+    {
+        oColor.emplace(COL_RED);
+    }
+    else if (eRedlineRenderMode == SwRedlineRenderMode::OmitDeletes && 
IsInserted())
+    {
+        oColor.emplace(COL_GREEN);
+    }
+    if (!oColor)
+    {
+        return false;
+    }
+
+    editeng::SvxBorderLine aBorderLine;
+    aBorderLine.SetWidth(1);
+    aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
+    aBorderLine.SetColor(*oColor);
+    rBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+    rBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+    rBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+    rBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+    return true;
+}
+
 SwTwips SwFlyFrame::Grow_(SwTwips nDist, SwResizeLimitReason& reason, bool 
bTst)
 {
     if (!Lower())
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index 3abe024fa602..73bec434fb24 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4320,8 +4320,11 @@ 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() );
+                                     (getFramePrintArea().SSize() != 
getFrameArea().SSize() || eRedlineRenderMode != SwRedlineRenderMode::Standard));
 
         // #i47804# - paint background of parent fly frame
         // for transparent graphics in layer Hell, if parent fly frame isn't
@@ -5512,7 +5515,8 @@ void SwFrame::PaintSwFrameShadowAndBorder(
     if (GetType() & 
(SwFrameType::NoTxt|SwFrameType::Row|SwFrameType::Body|SwFrameType::Footnote|SwFrameType::Column|SwFrameType::Root))
         return;
 
-    if (IsCellFrame() && !gProp.pSGlobalShell->GetViewOptions()->IsTable())
+    const SwViewOption& rViewOptions = *gProp.pSGlobalShell->GetViewOptions();
+    if (IsCellFrame() && !rViewOptions.IsTable())
         return;
 
     // #i29550#
@@ -5531,7 +5535,8 @@ void SwFrame::PaintSwFrameShadowAndBorder(
         return;
     }
 
-    const bool bLine = rAttrs.IsLine();
+    SwRedlineRenderMode eRedlineRenderMode = 
rViewOptions.GetRedlineRenderMode();
+    const bool bLine = (rAttrs.IsLine() || (IsFlyFrame() && eRedlineRenderMode 
!= SwRedlineRenderMode::Standard));
     const bool bShadow = rAttrs.GetShadow().GetLocation() != 
SvxShadowLocation::NONE;
 
     // - flag to control,
@@ -5610,6 +5615,21 @@ void SwFrame::PaintSwFrameShadowAndBorder(
         const SvxBorderLine* pTopBorder(rBox.GetTop());
         const SvxBorderLine* pBottomBorder(rBox.GetBottom());
 
+        auto pFlyFrame = IsFlyFrame() ? static_cast<const SwFlyFrame*>(this) : 
nullptr;
+        SvxBoxItem aBoxItem(RES_BOX);
+        if (pFlyFrame)
+        {
+            // This is a fly frame, see if it wants to paint a custom border 
based on the redline
+            // mode and status.
+            if (pFlyFrame->GetRedlineRenderModeFrame(aBoxItem))
+            {
+                pLeftBorder = aBoxItem.GetLeft();
+                pRightBorder = aBoxItem.GetRight();
+                pTopBorder = aBoxItem.GetTop();
+                pBottomBorder = aBoxItem.GetBottom();
+            }
+        }
+
         // if R2L, exchange Right/Left
         const bool bR2L(IsCellFrame() && IsRightToLeft());
 
commit dc59fe5a5d20ff9c0fa5128c3215a0e775dad4c0
Author:     Miklos Vajna <[email protected]>
AuthorDate: Thu Jan 22 08:37:58 2026 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Jan 29 13:29:46 2026 +0100

    cool#13988 sw redline render mode: handle inline images
    
    Load the bugdoc, dispatch .uno:RedlineRenderMode, anchored images in
    deletions are grey, but this doesn't work with inline images.
    
    There is some infrastructure for this added in commit
    d845b91bcc6eb885c55494d4d4fab4ec09577e1d (tdf#78864 sw track changes:
    cross out deleted images, 2021-04-30), but that crosses out images
    instead of shading.
    
    Fix this by checking for the usual SwRedlineRenderMode flags in
    sw::FlyContentPortion::Paint() to avoid the unwanted cross. Also extend
    SwLineLayout::CalcLine() to set the inserted/deleted flags on the fly
    frame for redlines, so SwGrfNode::GetGraphicAttr() can do its shading as
    usual.
    
    And add a GetMetaFileImages() in the test suite to reduce some
    duplication.
    
    Change-Id: I97f2311ad7e9a6ffc70d76c1811faa2c13e509fe
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197799
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198283

diff --git a/sw/qa/core/text/data/redline-image-inline.docx 
b/sw/qa/core/text/data/redline-image-inline.docx
new file mode 100644
index 000000000000..beaa9bbad87f
Binary files /dev/null and b/sw/qa/core/text/data/redline-image-inline.docx 
differ
diff --git a/sw/qa/core/text/itrpaint.cxx b/sw/qa/core/text/itrpaint.cxx
index cf0f37b19f57..479ba5a628bf 100644
--- a/sw/qa/core/text/itrpaint.cxx
+++ b/sw/qa/core/text/itrpaint.cxx
@@ -158,20 +158,12 @@ bool IsGrayScale(const Bitmap& rBitmap)
     return aColor.GetRed() == aColor.GetGreen() && aColor.GetRed() == 
aColor.GetBlue();
 }
 
-CPPUNIT_TEST_FIXTURE(Test, testAnchoredImageRedlineRenderModeOmitInsertDelete)
+std::vector<Bitmap> GetMetaFileImages(const GDIMetaFile& rMetaFile)
 {
-    // Given a document with a normal, a deleted and an inserted image:
-    createSwDoc("redline-image-anchored.docx");
-
-    // When using the standard redline render mode:
-    SwDocShell* pDocShell = getSwDocShell();
-    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
-
-    // Then make sure none of the images are grayscale:
     std::vector<Bitmap> aImages;
-    for (size_t nAction = 0; nAction < xMetaFile->GetActionSize(); ++nAction)
+    for (size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction)
     {
-        MetaAction* pAction = xMetaFile->GetAction(nAction);
+        MetaAction* pAction = rMetaFile.GetAction(nAction);
         if (pAction->GetType() != MetaActionType::BMPEXSCALE)
         {
             continue;
@@ -180,6 +172,20 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
         auto pAct = static_cast<MetaBmpExScaleAction*>(pAction);
         aImages.push_back(pAct->GetBitmap());
     }
+    return aImages;
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testAnchoredImageRedlineRenderModeOmitInsertDelete)
+{
+    // Given a document with a normal, a deleted and an inserted image:
+    createSwDoc("redline-image-anchored.docx");
+
+    // When using the standard redline render mode:
+    SwDocShell* pDocShell = getSwDocShell();
+    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    // Then make sure none of the images are grayscale:
+    std::vector<Bitmap> aImages = GetMetaFileImages(*xMetaFile);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
@@ -193,18 +199,7 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
 
     xMetaFile = pDocShell->GetPreviewMetaFile();
 
-    aImages.clear();
-    for (size_t nAction = 0; nAction < xMetaFile->GetActionSize(); ++nAction)
-    {
-        MetaAction* pAction = xMetaFile->GetAction(nAction);
-        if (pAction->GetType() != MetaActionType::BMPEXSCALE)
-        {
-            continue;
-        }
-
-        auto pAct = static_cast<MetaBmpExScaleAction*>(pAction);
-        aImages.push_back(pAct->GetBitmap());
-    }
+    aImages = GetMetaFileImages(*xMetaFile);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
@@ -218,18 +213,52 @@ CPPUNIT_TEST_FIXTURE(Test, 
testAnchoredImageRedlineRenderModeOmitInsertDelete)
 
     xMetaFile = pDocShell->GetPreviewMetaFile();
 
-    aImages.clear();
-    for (size_t nAction = 0; nAction < xMetaFile->GetActionSize(); ++nAction)
-    {
-        MetaAction* pAction = xMetaFile->GetAction(nAction);
-        if (pAction->GetType() != MetaActionType::BMPEXSCALE)
-        {
-            continue;
-        }
+    aImages = GetMetaFileImages(*xMetaFile);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
+    CPPUNIT_ASSERT(IsGrayScale(aImages[1]));
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[2]));
+}
 
-        auto pAct = static_cast<MetaBmpExScaleAction*>(pAction);
-        aImages.push_back(pAct->GetBitmap());
-    }
+CPPUNIT_TEST_FIXTURE(Test, testInlineImageRedlineRenderModeOmitInsertDelete)
+{
+    // Given a document with a normal, a deleted and an inserted image:
+    createSwDoc("redline-image-inline.docx");
+
+    // When using the standard redline render mode:
+    SwDocShell* pDocShell = getSwDocShell();
+    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    // Then make sure none of the images are grayscale:
+    std::vector<Bitmap> aImages = GetMetaFileImages(*xMetaFile);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[2]));
+
+    // Omit insert: default, default, grayscale.
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    SwViewOption aOpt(*pWrtShell->GetViewOptions());
+    aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitInserts);
+    pWrtShell->ApplyViewOptions(aOpt);
+
+    xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    aImages = GetMetaFileImages(*xMetaFile);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
+    CPPUNIT_ASSERT(!IsGrayScale(aImages[1]));
+    // Without the accompanying fix in place, this test would have failed, the 
image's center pixel
+    // wasn't gray.
+    CPPUNIT_ASSERT(IsGrayScale(aImages[2]));
+
+    // Omit deletes: default, grayscale, default.
+    aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitDeletes);
+    pWrtShell->ApplyViewOptions(aOpt);
+
+    xMetaFile = pDocShell->GetPreviewMetaFile();
+
+    aImages = GetMetaFileImages(*xMetaFile);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aImages.size());
     CPPUNIT_ASSERT(!IsGrayScale(aImages[0]));
     CPPUNIT_ASSERT(IsGrayScale(aImages[1]));
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index b0202f7fecca..da4fcbfdcd4e 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -40,6 +40,7 @@
 #include <sortedobjs.hxx>
 #include <officecfg/Office/Common.hxx>
 #include <PostItMgr.hxx>
+#include <viewopt.hxx>
 
 /**
  * class SwFlyPortion => we expect a frame-locale SwRect!
@@ -223,9 +224,10 @@ void sw::FlyContentPortion::Paint(const SwTextPaintInfo& 
rInf) const
     if(rInf.GetTextFrame()->IsVertical())
         rInf.GetTextFrame()->SwitchHorizontalToVertical(aRepaintRect);
 
+    SwViewShell* pViewShell = m_pFly->getRootFrame()->GetCurrShell();
     if(!((m_pFly->IsCompletePaint() ||
             m_pFly->getFrameArea().Overlaps(aRepaintRect)) &&
-            SwFlyFrame::IsPaint(m_pFly->GetVirtDrawObj(), 
*m_pFly->getRootFrame()->GetCurrShell())))
+            SwFlyFrame::IsPaint(m_pFly->GetVirtDrawObj(), *pViewShell)))
         return;
 
     SwRect aRect(m_pFly->getFrameArea());
@@ -239,7 +241,11 @@ void sw::FlyContentPortion::Paint(const SwTextPaintInfo& 
rInf) const
 
         // track changes: cross out the image, if it is deleted
         const SwFrame *pFrame = m_pFly->Lower();
-        if ( GetAuthor() != std::string::npos && IsDeleted() && pFrame )
+        const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
+        SwRedlineRenderMode eRedlineRenderMode
+            = pViewOptions ? pViewOptions->GetRedlineRenderMode() : 
SwRedlineRenderMode::Standard;
+        if (GetAuthor() != std::string::npos && IsDeleted() && pFrame
+            && eRedlineRenderMode == SwRedlineRenderMode::Standard)
         {
             SwRect aPaintRect( pFrame->GetPaintArea() );
 
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index de25fc8ccc99..78f15f923aa2 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -672,6 +672,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, 
SwTextFormatInfo &rInf )
         if( pPos->IsFlyCntPortion() )
         {
             bool bDeleted = false;
+            bool bInserted = false;
             size_t nAuthor = std::string::npos;
             if ( bHasRedline )
             {
@@ -683,10 +684,21 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, 
SwTextFormatInfo &rInf )
                 bool bHasFlyRedline = 
rLine.GetRedln()->CheckLine(flyStart.first->GetIndex(),
                     flyStart.second, flyStart.first->GetIndex(), 
flyStart.second, sRedlineText,
                     bHasRedlineEnd, eRedlineEnd, /*pAuthorAtPos=*/&nAuthor);
-                bDeleted = bHasFlyRedline && eRedlineEnd == 
RedlineType::Delete;
+                if (bHasFlyRedline)
+                {
+                    bDeleted = eRedlineEnd == RedlineType::Delete;
+                    bInserted = eRedlineEnd == RedlineType::Insert;
+                }
             }
             static_cast<SwFlyCntPortion*>(pPos)->SetDeleted(bDeleted);
             static_cast<SwFlyCntPortion*>(pPos)->SetAuthor(nAuthor);
+
+            if (auto pFlyPortion = dynamic_cast<sw::FlyContentPortion*>(pPos))
+            {
+                SwFlyFrame* pFlyFrame = pFlyPortion->GetFlyFrame();
+                pFlyFrame->SetDeleted(bDeleted);
+                pFlyFrame->SetInserted(bInserted);
+            }
         }
         // anchored to characters
         else if ( pPos->IsFlyPortion() )

Reply via email to