[Libreoffice-commits] core.git: vcl/CppunitTest_vcl_bitmap_test.mk vcl/qa vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Thu Oct 10 11:36:03 UTC 2019
vcl/CppunitTest_vcl_bitmap_test.mk | 1
vcl/qa/cppunit/BitmapExTest.cxx | 40 +++++++++++++++++++++++++++++++++++++
vcl/source/gdi/bitmapex.cxx | 37 ++++++++++++++++++++++++++++++++--
3 files changed, 76 insertions(+), 2 deletions(-)
New commits:
commit 55b4d5ea9e1a42edf71d2eef6028830983dbc11c
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Oct 10 09:49:29 2019 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu Oct 10 13:35:24 2019 +0200
vcl: only smooth bitmap transform when needed
If you have a very small bitmap and you rotate it by 90 degrees, then
smoothing is not needed, but the result will be blurry. So in case
scaling / shear doesn't need it and we do 90/180/270 rotation, avoid
smoothing.
Change-Id: I4b8fad4b0b70516d35eaecfa70a707e6e8362d18
Reviewed-on: https://gerrit.libreoffice.org/80589
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/vcl/CppunitTest_vcl_bitmap_test.mk b/vcl/CppunitTest_vcl_bitmap_test.mk
index 90db22099b40..9ebef12dcfb2 100644
--- a/vcl/CppunitTest_vcl_bitmap_test.mk
+++ b/vcl/CppunitTest_vcl_bitmap_test.mk
@@ -33,6 +33,7 @@ $(eval $(call gb_CppunitTest_set_include,vcl_bitmap_test,\
))
$(eval $(call gb_CppunitTest_use_libraries,vcl_bitmap_test, \
+ basegfx \
comphelper \
cppu \
cppuhelper \
diff --git a/vcl/qa/cppunit/BitmapExTest.cxx b/vcl/qa/cppunit/BitmapExTest.cxx
index 3a89441b9604..23f40f0013cd 100644
--- a/vcl/qa/cppunit/BitmapExTest.cxx
+++ b/vcl/qa/cppunit/BitmapExTest.cxx
@@ -12,6 +12,7 @@
#include <cppunit/extensions/HelperMacros.h>
#include <vcl/bitmapex.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
#include <bitmapwriteaccess.hxx>
#include <svdata.hxx>
#include <salinst.hxx>
@@ -22,10 +23,12 @@ class BitmapExTest : public CppUnit::TestFixture
{
void testGetPixelColor24_8();
void testGetPixelColor32();
+ void testTransformBitmapEx();
CPPUNIT_TEST_SUITE(BitmapExTest);
CPPUNIT_TEST(testGetPixelColor24_8);
CPPUNIT_TEST(testGetPixelColor32);
+ CPPUNIT_TEST(testTransformBitmapEx);
CPPUNIT_TEST_SUITE_END();
};
@@ -66,6 +69,43 @@ void BitmapExTest::testGetPixelColor32()
CPPUNIT_ASSERT_EQUAL(Color(0xAA, 0x00, 0xFF, 0x00), aBitmapEx.GetPixelColor(0, 0));
}
+void BitmapExTest::testTransformBitmapEx()
+{
+ Bitmap aBitmap(Size(16, 16), 24);
+ {
+ BitmapScopedWriteAccess pWriteAccess(aBitmap);
+ pWriteAccess->Erase(COL_WHITE);
+ for (int i = 0; i < 8; ++i)
+ {
+ for (int j = 0; j < 8; ++j)
+ {
+ pWriteAccess->SetPixel(i, j, COL_BLACK);
+ }
+ }
+ }
+ BitmapEx aBitmapEx(aBitmap);
+
+ basegfx::B2DHomMatrix aMatrix;
+ aMatrix.rotate(M_PI / 2);
+ BitmapEx aTransformed = aBitmapEx.TransformBitmapEx(16, 16, aMatrix);
+ aBitmap = aTransformed.GetBitmap();
+ Bitmap::ScopedReadAccess pAccess(aBitmap);
+ for (int i = 0; i < 16; ++i)
+ {
+ for (int j = 0; j < 16; ++j)
+ {
+ BitmapColor aColor = pAccess->GetPixel(i, j);
+ std::stringstream ss;
+ ss << "Color is expected to be white or black, is '" << aColor.AsRGBHexString() << "'";
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expression: aColor == COL_WHITE || aColor == COL_BLACK
+ // - Color is expected to be white or black, is 'bfbfbf'
+ // i.e. smoothing introduced noise for a simple 90 deg rotation.
+ CPPUNIT_ASSERT_MESSAGE(ss.str(), aColor == COL_WHITE || aColor == COL_BLACK);
+ }
+ }
+}
+
} // namespace
CPPUNIT_TEST_SUITE_REGISTRATION(BitmapExTest);
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index d4f96bcd86f3..5e410d05fb9b 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -867,6 +867,38 @@ namespace
return aDestination;
}
+
+ /// Decides if rTransformation needs smoothing or not (e.g. 180 deg rotation doesn't need it).
+ bool implTransformNeedsSmooth(const basegfx::B2DHomMatrix& rTransformation)
+ {
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ rTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+ if (aScale != basegfx::B2DVector(1, 1))
+ {
+ return true;
+ }
+
+ fRotate = fmod( fRotate, F_2PI );
+ if (fRotate < 0)
+ {
+ fRotate += F_2PI;
+ }
+ if (!rtl::math::approxEqual(fRotate, 0)
+ && !rtl::math::approxEqual(fRotate, F_PI2)
+ && !rtl::math::approxEqual(fRotate, F_PI)
+ && !rtl::math::approxEqual(fRotate, 3 * F_PI2))
+ {
+ return true;
+ }
+
+ if (!rtl::math::approxEqual(fShearX, 0))
+ {
+ return true;
+ }
+
+ return false;
+ }
} // end of anonymous namespace
BitmapEx BitmapEx::TransformBitmapEx(
@@ -879,14 +911,15 @@ BitmapEx BitmapEx::TransformBitmapEx(
// force destination to 24 bit, we want to smooth output
const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
- const Bitmap aDestination(impTransformBitmap(GetBitmapRef(), aDestinationSize, rTransformation, /*bSmooth*/true));
+ bool bSmooth = implTransformNeedsSmooth(rTransformation);
+ const Bitmap aDestination(impTransformBitmap(GetBitmapRef(), aDestinationSize, rTransformation, bSmooth));
// create mask
if(IsTransparent())
{
if(IsAlpha())
{
- const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, /*bSmooth*/true));
+ const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
return BitmapEx(aDestination, AlphaMask(aAlpha));
}
else
More information about the Libreoffice-commits
mailing list