sw/qa/core/text/itrpaint.cxx | 11 +++++++++++ sw/source/core/layout/fly.cxx | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
New commits: commit 1c4128cf789dea9fd27515b62472162588cd0038 Author: Miklos Vajna <[email protected]> AuthorDate: Wed Jan 28 15:26:24 2026 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Jan 29 08:15:50 2026 +0100 cool#13988 sw redline render mode: add colored border for inline images Anchored images conditionally got a red/green frame in since commit afdf4e287fb91c7baf2767eb95b0565472b8343d (cool#13988 sw redline render mode: add colored border for anchored images, 2026-01-27), but the same didn't work for inline images. Seems what happens is that SwFlyFrame::GetRedlineRenderModeFrame() sets the border line with to 1 (in twips, so some minimal value), but then this is turned into a SdrFrameBorderPrimitive2D, which gets decomposed into a PolygonStrokePrimitive2D. At this point the cairo pixel processor handles it at CairoPixelProcessor2D::processPolygonStrokePrimitive2D(), which assumes that hairline is when the width is 0. The trouble is that in case Writer sets the width to 0, then we don't even start processing such stroke primitives. Solve the problem by going with a larger border width: just query from output device what would be a logic value for a 1px border, so it does show up reliably. This is similar to how SwViewOption::s_nPixelTwips gets configured already. Note that the testcase just asserts these polygons are painted, but it can't verify how CairoPixelProcessor2D simply didn't paint the old bad width. Change-Id: I83f7aec4d09fc628dd314e1325bfd47af07308ca Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198282 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/sw/qa/core/text/itrpaint.cxx b/sw/qa/core/text/itrpaint.cxx index 21306cccb708..e84c1183468d 100644 --- a/sw/qa/core/text/itrpaint.cxx +++ b/sw/qa/core/text/itrpaint.cxx @@ -290,6 +290,9 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineImageRedlineRenderModeOmitInsertDelete) 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(); @@ -306,6 +309,10 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineImageRedlineRenderModeOmitInsertDelete) // 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: no polygons -> no frame. + CPPUNIT_ASSERT(!aPolygons.empty()); + CPPUNIT_ASSERT(RectangleContainsPolygons(aImages[1].m_aRectangle, aPolygons)); // Omit deletes: default, grayscale, default. aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitDeletes); @@ -318,6 +325,10 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineImageRedlineRenderModeOmitInsertDelete) 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)); } } diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index edab63b8f4de..e5b34953e0e5 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2350,7 +2350,12 @@ bool SwFlyFrame::GetRedlineRenderModeFrame(SvxBoxItem& rBoxItem) const } editeng::SvxBorderLine aBorderLine; - aBorderLine.SetWidth(1); + + // Set a logic value which is roughly 1 pixel wide, so the border is visible. + vcl::RenderContext* pOut = pViewShell->GetOut(); + tools::Long nWidth = pOut ? pOut->PixelToLogic(Size(1, 1)).Width() : 0; + aBorderLine.SetWidth(nWidth); + aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID); aBorderLine.SetColor(*oColor); rBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
