vcl/qa/cppunit/skia/skia.cxx | 30 ++++++++++++++++++++++++++++++ vcl/skia/gdiimpl.cxx | 20 ++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-)
New commits: commit ded4b38deb2d7190ecc500250b63204b0f6d5577 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Wed Mar 17 16:03:12 2021 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Mar 17 21:22:17 2021 +0100 round polygon points before merging them for Skia drawing (tdf#140848) basegfx::utils::mergeToSinglePolyPolygon() appears to have rounding problems. Point coordinates are in pixels anyway. Change-Id: I9880cc32f934a08923a5c59278f6aa07852c05f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112647 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> (cherry picked from commit ff1cfaf87ce0aa9673e1c3f92308cde6a2c6aa69) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112615 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx index 1f04c5825584..33341bf6ad69 100644 --- a/vcl/qa/cppunit/skia/skia.cxx +++ b/vcl/qa/cppunit/skia/skia.cxx @@ -36,6 +36,7 @@ public: void testAlphaBlendWith(); void testBitmapCopyOnWrite(); void testTdf137329(); + void testTdf140848(); CPPUNIT_TEST_SUITE(SkiaTest); CPPUNIT_TEST(testBitmapErase); @@ -44,6 +45,7 @@ public: CPPUNIT_TEST(testAlphaBlendWith); CPPUNIT_TEST(testBitmapCopyOnWrite); CPPUNIT_TEST(testTdf137329); + CPPUNIT_TEST(testTdf140848); CPPUNIT_TEST_SUITE_END(); private: @@ -326,6 +328,34 @@ void SkiaTest::testTdf137329() CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(4, 4))); } +void SkiaTest::testTdf140848() +{ + if (!SkiaHelper::isVCLSkiaEnabled()) + return; + ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); + device->SetOutputSizePixel(Size(1300, 400)); + device->SetBackground(Wallpaper(COL_BLACK)); + device->SetAntialiasing(AntialiasingFlags::Enable); + device->Erase(); + device->SetLineColor(); + device->SetFillColor(COL_WHITE); + basegfx::B2DPolygon p1 = { { 952.73121259842514519, 102.4599685039370911 }, + { 952.73121259842514519, 66.55445669291347599 }, + { 1239.9753070866140661, 66.554456692913390725 }, + { 1239.9753070866140661, 138.36548031496062094 }, + { 952.73121259842514519, 138.36548031496070621 } }; + basegfx::B2DPolygon p2 = { { 1168.1642834645670064, 210.17650393700790801 }, + { 1168.1642834645670064, 66.554456692913404936 }, + { 1239.9753070866140661, 66.554456692913390725 }, + { 1239.9753070866142934, 353.79855118110236845 }, + { 1168.1642834645670064, 353.79855118110236845 } }; + device->DrawPolyPolygon(basegfx::B2DPolyPolygon(p1)); + device->DrawPolyPolygon(basegfx::B2DPolyPolygon(p2)); + //savePNG("/tmp/tdf140848.png", device); + // Rounding errors caused the overlapping part not to be drawn. + CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(1200, 100))); +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(SkiaTest); diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 4e6383d91473..ba9737c6544c 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -1012,6 +1012,20 @@ bool SkiaSalGraphicsImpl::delayDrawPolyPolygon(const basegfx::B2DPolyPolygon& aP return true; } +// Tdf#140848 - basegfx::utils::mergeToSinglePolyPolygon() seems to have rounding +// errors that sometimes cause it to merge incorrectly. +static void roundPolygonPoints(basegfx::B2DPolyPolygon& polyPolygon) +{ + for (basegfx::B2DPolygon& polygon : polyPolygon) + { + polygon.makeUnique(); + for (sal_uInt32 i = 0; i < polygon.count(); ++i) + polygon.setB2DPoint(i, basegfx::B2DPoint(basegfx::fround(polygon.getB2DPoint(i)))); + // Control points are saved as vectors relative to points, so hopefully + // there's no need to round those. + } +} + void SkiaSalGraphicsImpl::checkPendingDrawing() { if (mLastPolyPolygonInfo.polygons.size() != 0) @@ -1023,10 +1037,12 @@ void SkiaSalGraphicsImpl::checkPendingDrawing() if (polygons.size() == 1) performDrawPolyPolygon(polygons.front(), transparency, true); else - // TODO: tdf#136222 shows that basegfx::utils::mergeToSinglePolyPolygon() is unreliable - // in corner cases, possibly either a bug or rounding errors somewhere. + { + for (basegfx::B2DPolyPolygon& p : polygons) + roundPolygonPoints(p); performDrawPolyPolygon(basegfx::utils::mergeToSinglePolyPolygon(polygons), transparency, true); + } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits