[Libreoffice-commits] core.git: vcl/qa vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Thu Oct 10 18:25:21 UTC 2019
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 <vmiklos at collabora.com>
AuthorDate: Thu Oct 10 19:03:53 2019 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
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 <vmiklos at collabora.com>
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
More information about the Libreoffice-commits
mailing list