vcl/qa/cppunit/outdev.cxx | 37 +++++++++++++++++++++++++++++++++++++ vcl/source/outdev/bitmap.cxx | 22 ++++++++++++++++++---- 2 files changed, 55 insertions(+), 4 deletions(-)
New commits: commit 68549e00d5e23aa22bc974a8151d93cd948444b3 Author: Miklos Vajna <[email protected]> AuthorDate: Thu Oct 10 19:03:53 2019 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Oct 10 20:24:26 2019 +0200 vcl, BitmapEx transformed draw: special-case simple rotations In case OutputDevice::DrawTransformedBitmapEx() has to do both shearing and rotation, then recording to a metafile is unchanged. But if we need to do rotation, then it's not necessary to go via transformations. This has the additional benefit that 90/180/270 degree rotations don't introduce an off-by-one error, where the first row and col of the transformed bitmap is transparent. (At the moment it's not clear what introduces the unwanted translation, but at least the direct Rotate() way resolves the visible end-user problem, see the test.) Change-Id: Ie1adbdb2221b086c19cc66f69308b6b7256fe29a Reviewed-on: https://gerrit.libreoffice.org/80626 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx index 53f2424f5dbe..e6a6b8f1c5f6 100644 --- a/vcl/qa/cppunit/outdev.cxx +++ b/vcl/qa/cppunit/outdev.cxx @@ -15,6 +15,7 @@ #include <vcl/bitmapaccess.hxx> #include <vcl/gdimtf.hxx> #include <vcl/metaact.hxx> +#include <bitmapwriteaccess.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -142,9 +143,22 @@ void VclOutdevTest::testDrawTransformedBitmapEx() // Also create a 16x16 bitmap. ScopedVclPtrInstance<VirtualDevice> pVDev; Bitmap aBitmap(Size(16, 16), 24); + { + // Fill the top left quarter with black. + BitmapScopedWriteAccess pWriteAccess(aBitmap); + pWriteAccess->Erase(COL_WHITE); + for (int i = 0; i < 8; ++i) + { + for (int j = 0; j < 8; ++j) + { + pWriteAccess->SetPixel(j, i, COL_BLACK); + } + } + } BitmapEx aBitmapEx(aBitmap); basegfx::B2DHomMatrix aMatrix; aMatrix.scale(8, 8); + // Rotate 90 degrees clockwise, so the black part goes to the top right. aMatrix.rotate(M_PI / 2); GDIMetaFile aMtf; aMtf.Record(pVDev.get()); @@ -162,6 +176,29 @@ void VclOutdevTest::testDrawTransformedBitmapEx() // - Actual : 8x8 // I.e. the bitmap before scaling was already scaled down, just because it was rotated. CPPUNIT_ASSERT_EQUAL(Size(16, 16), aTransformedSize); + + aBitmap = rBitmapEx.GetBitmap(); + Bitmap::ScopedReadAccess pAccess(aBitmap); + for (int i = 0; i < 16; ++i) + { + for (int j = 0; j < 16; ++j) + { + BitmapColor aColor = pAccess->GetPixel(j, i); + Color aExpected = i >= 8 && j < 8 ? COL_BLACK : COL_WHITE; + std::stringstream ss; + ss << "Color is expected to be "; + ss << ((aExpected == COL_WHITE) ? "white" : "black"); + ss << ", is " << aColor.AsRGBHexString(); + ss << " (row " << j << ", col " << i << ")"; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: c[00000000] + // - Actual : c[ffffff00] + // - Color is expected to be black, is ffffff (row 0, col 8) + // i.e. the top right quarter of the image was not fully black, there was a white first + // row. + CPPUNIT_ASSERT_EQUAL_MESSAGE(ss.str(), aExpected, Color(aColor)); + } + } } CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 2cbdb2fdb2b3..93c1f76aef1f 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -1285,10 +1285,24 @@ void OutputDevice::DrawTransformedBitmapEx( aFullTransform *= aTransform; } - aTransformed = aTransformed.getTransformed( - aFullTransform, - aVisibleRange, - fMaximumArea); + if (bSheared) + { + aTransformed = aTransformed.getTransformed( + aFullTransform, + aVisibleRange, + fMaximumArea); + } + else + { + // Just rotation, can do that directly. + fFullRotate = fmod(fFullRotate * -1, F_2PI); + if (fFullRotate < 0) + { + fFullRotate += F_2PI; + } + long nAngle10 = basegfx::fround(basegfx::rad2deg(fFullRotate) * 10); + aTransformed.Rotate(nAngle10, COL_TRANSPARENT); + } basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); // get logic object target range _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
