diff options
-rw-r--r-- | vcl/inc/skia/utils.hxx | 9 | ||||
-rw-r--r-- | vcl/qa/cppunit/skia/skia.cxx | 20 | ||||
-rw-r--r-- | vcl/skia/gdiimpl.cxx | 31 |
3 files changed, 57 insertions, 3 deletions
diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx index 7da858ab1fff..b5412e9f9479 100644 --- a/vcl/inc/skia/utils.hxx +++ b/vcl/inc/skia/utils.hxx @@ -26,6 +26,7 @@ #include <driverblocklist.hxx> #include <SkRegion.h> +#include <SkSurface.h> #include <tools/sk_app/VulkanWindowContext.h> namespace SkiaHelper @@ -94,7 +95,13 @@ inline DriverBlocklist::DeviceVendor getVendor() return DriverBlocklist::GetVendorFromId(vendorId); } -} // namespace +} // namespace SkiaHelper + +// For unittests. +namespace SkiaTests +{ +VCL_DLLPUBLIC bool matrixNeedsHighQuality(const SkMatrix& matrix); +} template <typename charT, typename traits> inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx index a84cb7d19907..6b18967f0590 100644 --- a/vcl/qa/cppunit/skia/skia.cxx +++ b/vcl/qa/cppunit/skia/skia.cxx @@ -17,6 +17,7 @@ #include <vcl/skia/SkiaHelper.hxx> #include <skia/salbmp.hxx> +#include <skia/utils.hxx> #include <bitmap/BitmapWriteAccess.hxx> // This tests backends that use Skia (i.e. intentionally not the svp one, which is the default.) @@ -37,6 +38,7 @@ public: void testInterpretAs8Bit(); void testAlphaBlendWith(); void testBitmapCopyOnWrite(); + void testMatrixQuality(); void testTdf137329(); CPPUNIT_TEST_SUITE(SkiaTest); @@ -45,6 +47,7 @@ public: CPPUNIT_TEST(testInterpretAs8Bit); CPPUNIT_TEST(testAlphaBlendWith); CPPUNIT_TEST(testBitmapCopyOnWrite); + CPPUNIT_TEST(testMatrixQuality); CPPUNIT_TEST(testTdf137329); CPPUNIT_TEST_SUITE_END(); @@ -307,8 +310,25 @@ void SkiaTest::testBitmapCopyOnWrite() CPPUNIT_ASSERT(bitmap.unittestGetAlphaImage() != oldAlphaImage); } +void SkiaTest::testMatrixQuality() +{ + if (!SkiaHelper::isVCLSkiaEnabled()) + return; + // Not changing the size (but possibly rotated/flipped) does not need high quality transformations. + CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix())); + CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(90))); + CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(180))); + CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(270))); + CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(1, -1))); + CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(0, -1))); + CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(2, 1))); + CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(89))); +} + void SkiaTest::testTdf137329() { + if (!SkiaHelper::isVCLSkiaEnabled()) + return; // Draw a filled polygon in the entire device, with AA enabled. // All pixels in the device should be black, even those at edges (i.e. not affected by AA). ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index d8ddf48536c0..c511b2ef2f45 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -1766,6 +1766,33 @@ bool SkiaSalGraphicsImpl::hasFastDrawTransformedBitmap() const return true; } +// Whether applying matrix needs image smoothing for the transformation. +static bool matrixNeedsHighQuality(const SkMatrix& matrix) +{ + if (matrix.isIdentity()) + return false; + if (matrix.isScaleTranslate()) + { + if (abs(matrix.getScaleX()) == 1 && abs(matrix.getScaleY()) == 1) + return false; // Only at most flipping and keeping the size. + return true; + } + assert(!matrix.hasPerspective()); // we do not use this + if (matrix.getScaleX() == 0 && matrix.getScaleY() == 0) + { + // Rotating 90 or 270 degrees while keeping the size. + if ((matrix.getSkewX() == 1 && matrix.getSkewY() == -1) + || (matrix.getSkewX() == -1 && matrix.getSkewY() == 1)) + return false; + } + return true; +} + +namespace SkiaTests +{ +bool matrixNeedsHighQuality(const SkMatrix& matrix) { return ::matrixNeedsHighQuality(matrix); } +} + bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY, @@ -1816,7 +1843,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull, SkAutoCanvasRestore autoRestore(canvas, true); canvas->concat(matrix); SkPaint paint; - if (!matrix.isTranslate()) + if (matrixNeedsHighQuality(matrix)) paint.setFilterQuality(kHigh_SkFilterQuality); if (fAlpha == 1.0) canvas->drawImage(imageToDraw, 0, 0, &paint); @@ -1842,7 +1869,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull, SkAutoCanvasRestore autoRestore(canvas, true); canvas->concat(matrix); SkPaint paint; - if (!matrix.isTranslate()) + if (matrixNeedsHighQuality(matrix)) paint.setFilterQuality(kHigh_SkFilterQuality); if (pSkiaAlphaBitmap) { |