include/drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx |    3 
 sd/qa/unit/PNGExportTests.cxx                                    |    2 
 sd/qa/unit/import-tests2.cxx                                     |    5 -
 sd/qa/unit/layout-tests.cxx                                      |   16 +--
 svgio/qa/cppunit/SvgImportTest.cxx                               |    8 -
 svgio/source/svgreader/svgsvgnode.cxx                            |   20 ++--
 vcl/qa/cppunit/GraphicTest.cxx                                   |   44 
+++++-----
 vcl/qa/cppunit/TypeSerializerTest.cxx                            |    2 
 8 files changed, 47 insertions(+), 53 deletions(-)

New commits:
commit aa2c07951b565cd5464a36a2b0721f888ab8531c
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Feb 26 20:57:06 2026 +0900
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Fri Feb 27 14:51:03 2026 +0100

    svgio: fix rendering, which makes SVG images 1px bigger
    
    We added a rectangle using PolygonHairlinePrimitive2D to the
    HiddenGeometryPrimitive2D, so we can mark the boundary of the
    SVG image. The problem with using the hairline primitive for this
    is that the hairline size is grown by 0.5 in each direction
    (implGrowHairline, which is called in getB2DRange), which also makes
    our SVG size 1px bigger than it should be.
    
    Using FilledRectanglePrimitive2D instead fixes this problem as the
    rectangle isn't grown in size.
    
    Also needed to change a lot of tests that were using SVG images
    and asserted the size of the image in ome way.
    
    Change-Id: Ic2aa98b3df1f0746e4cfbd3474b6a93d0f4072ea
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200440
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/include/drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx 
b/include/drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx
index 47c9bbb83b0b..0bb67c3d0c7a 100644
--- a/include/drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx
@@ -68,8 +68,7 @@ public:
     sometimes useful for simpler tasks and decomposes to a
     more generalized PolyPolygonColorPrimitive2D (see above)
 */
-class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) FilledRectanglePrimitive2D final
-    : public BasePrimitive2D
+class DRAWINGLAYER_DLLPUBLIC FilledRectanglePrimitive2D final : public 
BasePrimitive2D
 {
 private:
     /// the  geometry
diff --git a/sd/qa/unit/PNGExportTests.cxx b/sd/qa/unit/PNGExportTests.cxx
index bfc78b4781ec..911bf9e91f2b 100644
--- a/sd/qa/unit/PNGExportTests.cxx
+++ b/sd/qa/unit/PNGExportTests.cxx
@@ -1004,7 +1004,7 @@ CPPUNIT_TEST_FIXTURE(SdPNGExportTest, testTdf162259)
     xGraphicExporter->filter(aDescriptor);
     Bitmap bmp = 
vcl::PngImageReader(*maTempFile.GetStream(StreamMode::READ)).read();
 
-    tools::Rectangle topX(12, 21, 37, 60);
+    tools::Rectangle topX(12, 20, 37, 60);
     int topNonWhites = 0;
     tools::Rectangle bottomX(12, 82, 37, 126);
     int bottomNonWhites = 0;
diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx
index 061ebf899c8d..0a4fef8a2b44 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -1477,10 +1477,7 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testtdf163852)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aCrop.Top);
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aCrop.Left);
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aCrop.Right);
-    // Without the fix in place, this test would have failed with
-    // - Expected: 702
-    // - Actual  : 0
-    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(702), aCrop.Bottom);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(688), aCrop.Bottom);
 }
 
 CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf149785)
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index fe3a27418553..0486b41527f3 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -484,29 +484,29 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf164622)
     // - Actual  : 892
     // - In <>, attribute 'y' of 
'/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[4]'
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[1]",
-                "x", u"7556");
+                "x", u"7543");
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[1]",
-                "y", u"892");
+                "y", u"879");
 
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[2]",
-                "x", u"20440");
+                "x", u"20453");
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[2]",
-                "y", u"892");
+                "y", u"879");
 
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[3]",
-                "x", u"20440");
+                "x", u"20453");
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[3]",
                 "y", u"8998");
 
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[4]",
-                "x", u"7556");
+                "x", u"7543");
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[4]",
                 "y", u"8998");
 
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[5]",
-                "x", u"7556");
+                "x", u"7543");
     assertXPath(pXmlDoc, 
"/metafile/push[1]/push[1]/push[2]/push[1]/clipregion/polygon/point[5]",
-                "y", u"892");
+                "y", u"879");
 }
 
 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf168010)
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx 
b/svgio/qa/cppunit/SvgImportTest.cxx
index ca45500951a8..b1710e3d0028 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -1377,8 +1377,8 @@ CPPUNIT_TEST_FIXTURE(Test, 
testBehaviourWhenWidthAndHeightIsOrIsNotSet)
         double fWidth = (aRange.getWidth() / 2540.0) * 96.0;
         double fHeight = (aRange.getHeight() / 2540.0) * 96.0;
 
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fWidth, 1E-12);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fHeight, 1E-12);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, fWidth, 1E-12);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, fHeight, 1E-12);
     }
 
     {
@@ -1402,8 +1402,8 @@ CPPUNIT_TEST_FIXTURE(Test, 
testBehaviourWhenWidthAndHeightIsOrIsNotSet)
         double fWidth = (aRange.getWidth() / 2540.0) * 96.0;
         double fHeight = (aRange.getHeight() / 2540.0) * 96.0;
 
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fWidth, 1E-12);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fHeight, 1E-12);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, fWidth, 1E-12);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, fHeight, 1E-12);
     }
 }
 
diff --git a/svgio/source/svgreader/svgsvgnode.cxx 
b/svgio/source/svgreader/svgsvgnode.cxx
index e1c94e7b556a..d8d6d1514e2b 100644
--- a/svgio/source/svgreader/svgsvgnode.cxx
+++ b/svgio/source/svgreader/svgsvgnode.cxx
@@ -24,7 +24,7 @@
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
-#include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx>
 #include <o3tl/unit_conversion.hxx>
 #include <svgdocument.hxx>
@@ -619,14 +619,13 @@ namespace svgio::svgreader
                             // This is needed since e.g. an SdrObject using 
this as graphic will
                             // create a mapping transformation to exactly map 
the content to its
                             // real life size
-                            const 
drawinglayer::primitive2d::Primitive2DReference xLine(
-                                new 
drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
-                                    basegfx::utils::createPolygonFromRect(
-                                        aSvgCanvasRange),
+                            const 
drawinglayer::primitive2d::Primitive2DReference xRect(
+                                new 
drawinglayer::primitive2d::FilledRectanglePrimitive2D(
+                                    aSvgCanvasRange,
                                     basegfx::BColor(0.0, 0.0, 0.0)));
                             const 
drawinglayer::primitive2d::Primitive2DReference xHidden(
                                 new 
drawinglayer::primitive2d::HiddenGeometryPrimitive2D(
-                                    
drawinglayer::primitive2d::Primitive2DContainer { xLine }));
+                                    
drawinglayer::primitive2d::Primitive2DContainer { xRect }));
 
                             aSequence.push_back(xHidden);
                         }
@@ -702,14 +701,13 @@ namespace svgio::svgreader
             // tdf#118232 No geometry, Outermost SVG element and we have a 
ViewBox.
             // Create a HiddenGeometry Primitive containing an expanded
             // hairline geometry to have the size contained
-            const drawinglayer::primitive2d::Primitive2DReference xLine(
-                new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
-                    basegfx::utils::createPolygonFromRect(
-                        *getViewBox()),
+            const drawinglayer::primitive2d::Primitive2DReference xRect(
+                new drawinglayer::primitive2d::FilledRectanglePrimitive2D(
+                    *getViewBox(),
                     basegfx::BColor(0.0, 0.0, 0.0)));
             const drawinglayer::primitive2d::Primitive2DReference xHidden(
                 new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(
-                    drawinglayer::primitive2d::Primitive2DContainer { xLine 
}));
+                    drawinglayer::primitive2d::Primitive2DContainer { xRect 
}));
 
             rTarget.push_back(xHidden);
         }
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index bf042f1dbe62..3b0fa3fcc62a 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -873,12 +873,12 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithGfxLink)
     CPPUNIT_ASSERT_EQUAL(u"Origin URL"_ustr, aGraphic.getOriginURL());
 
     // Check size in pixels
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 
     // Set and check the PrefSize
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(1323), aGraphic.GetPrefSize().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(1323), aGraphic.GetPrefSize().Height());
     aGraphic.SetPrefSize(Size(200, 100));
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
@@ -893,8 +893,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithGfxLink)
     CPPUNIT_ASSERT_EQUAL(u"Origin URL"_ustr, aGraphic.getOriginURL());
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 
     // SWAP IN
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
@@ -906,8 +906,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithGfxLink)
     CPPUNIT_ASSERT_EQUAL(u"Origin URL"_ustr, aGraphic.getOriginURL());
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 }
 
 CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithoutGfxLink)
@@ -940,12 +940,12 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithoutGfxLi
     CPPUNIT_ASSERT_EQUAL(u"Origin URL"_ustr, aGraphic.getOriginURL());
 
     // Check size in pixels
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 
     // Set and check the PrefSize
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(1323), aGraphic.GetPrefSize().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(1323), aGraphic.GetPrefSize().Height());
     aGraphic.SetPrefSize(Size(200, 100));
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
@@ -960,8 +960,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithoutGfxLi
 
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 
     // SWAP IN
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
@@ -973,8 +973,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, 
testSwappingGraphicProperties_SVG_WithoutGfxLi
 
     CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
     CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(50), aGraphic.GetSizePixel().Height());
 }
 
 CPPUNIT_TEST_FIXTURE(GraphicTest, testSwappingVectorGraphic_PDF_WithGfxLink)
@@ -1257,8 +1257,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, testLoadSVGZ)
     Graphic aGraphic = loadGraphic(u"TypeDetectionExample.svgz");
     CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
     const auto[scalingX, scalingY] = getDPIScaling();
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingX), 
aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingY), 
aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingX), 
aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingY), 
aGraphic.GetSizePixel().Height());
 }
 
 CPPUNIT_TEST_FIXTURE(GraphicTest, testTdf156016)
@@ -1269,8 +1269,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, testTdf156016)
     Graphic aGraphic = loadGraphic(u"tdf156016.svg");
     CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
     const auto[scalingX, scalingY] = getDPIScaling();
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingX), 
aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingY), 
aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingX), 
aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingY), 
aGraphic.GetSizePixel().Height());
 }
 
 CPPUNIT_TEST_FIXTURE(GraphicTest, testTdf149545)
@@ -1281,8 +1281,8 @@ CPPUNIT_TEST_FIXTURE(GraphicTest, testTdf149545)
     Graphic aGraphic = loadGraphic(u"tdf149545.svg");
     CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
     const auto[scalingX, scalingY] = getDPIScaling();
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingX), 
aGraphic.GetSizePixel().Width());
-    CPPUNIT_ASSERT_EQUAL(tools::Long(100 * scalingY), 
aGraphic.GetSizePixel().Height());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingX), 
aGraphic.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(tools::Long(99 * scalingY), 
aGraphic.GetSizePixel().Height());
 }
 
 CPPUNIT_TEST_FIXTURE(GraphicTest, testAvailableThreaded)
diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx 
b/vcl/qa/cppunit/TypeSerializerTest.cxx
index 147008c39668..f08ad0f01aa3 100644
--- a/vcl/qa/cppunit/TypeSerializerTest.cxx
+++ b/vcl/qa/cppunit/TypeSerializerTest.cxx
@@ -120,7 +120,7 @@ void TypeSerializerTest::testGraphic_Vector()
 
         CPPUNIT_ASSERT_EQUAL(sal_uInt64(290), aMemoryStream.remainingSize());
         std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
-        
CPPUNIT_ASSERT_EQUAL(std::string("e24553130d4b3c17da6b536bec89cb5579396540"),
+        
CPPUNIT_ASSERT_EQUAL(std::string("180d34efe330b7cb6e32be08cba11930713c0565"),
                              comphelper::hashToString(aHash));
 
         aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);

Reply via email to