summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/skia/utils.hxx9
-rw-r--r--vcl/qa/cppunit/skia/skia.cxx20
-rw-r--r--vcl/skia/gdiimpl.cxx31
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)
{