vcl/qa/cppunit/outdev.cxx | 32 ++++++++++++++++++++++++++++++++ vcl/source/outdev/bitmap.cxx | 15 ++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-)
New commits: commit dd4a67084853a030bf4b9f1f85d728620e0604a5 Author: Miklos Vajna <[email protected]> AuthorDate: Tue Oct 8 09:16:27 2019 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Oct 8 14:31:32 2019 +0200 vcl: avoid downscale && upscale in DrawTransformedBitmapEx() If we rotate a bitmap and put it to a metafile, we'll create a MetaBmpExScaleAction. But just because we need to store a transformed bitmap for rotation purposes, it doesn't mean we also need to scale it. This helps in case later the metafile is upscaled and the downscaled bitmap would look blurry. Change-Id: I7d64a88af460e80dffde8052186888eddbb440fe Reviewed-on: https://gerrit.libreoffice.org/80426 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx index 0484e4a4143d..53f2424f5dbe 100644 --- a/vcl/qa/cppunit/outdev.cxx +++ b/vcl/qa/cppunit/outdev.cxx @@ -13,6 +13,8 @@ #include <vcl/virdev.hxx> #include <vcl/window.hxx> #include <vcl/bitmapaccess.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/metaact.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -27,6 +29,7 @@ public: void testWindowBackgroundColor(); void testGetReadableFontColorPrinter(); void testGetReadableFontColorWindow(); + void testDrawTransformedBitmapEx(); CPPUNIT_TEST_SUITE(VclOutdevTest); CPPUNIT_TEST(testVirtualDevice); @@ -35,6 +38,7 @@ public: CPPUNIT_TEST(testWindowBackgroundColor); CPPUNIT_TEST(testGetReadableFontColorPrinter); CPPUNIT_TEST(testGetReadableFontColorWindow); + CPPUNIT_TEST(testDrawTransformedBitmapEx); CPPUNIT_TEST_SUITE_END(); }; @@ -132,6 +136,34 @@ void VclOutdevTest::testUseAfterDispose() pVDev->GetViewTransformation(); } +void VclOutdevTest::testDrawTransformedBitmapEx() +{ + // Create a virtual device, and connect a metafile to it. + // Also create a 16x16 bitmap. + ScopedVclPtrInstance<VirtualDevice> pVDev; + Bitmap aBitmap(Size(16, 16), 24); + BitmapEx aBitmapEx(aBitmap); + basegfx::B2DHomMatrix aMatrix; + aMatrix.scale(8, 8); + aMatrix.rotate(M_PI / 2); + GDIMetaFile aMtf; + aMtf.Record(pVDev.get()); + + // Draw the rotated bitmap on the vdev. + pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf.GetActionSize()); + MetaAction* pAction = aMtf.GetAction(0); + CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType()); + auto pBitmapAction = static_cast<MetaBmpExScaleAction*>(pAction); + const BitmapEx& rBitmapEx = pBitmapAction->GetBitmapEx(); + Size aTransformedSize = rBitmapEx.GetSizePixel(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 16x16 + // - Actual : 8x8 + // I.e. the bitmap before scaling was already scaled down, just because it was rotated. + CPPUNIT_ASSERT_EQUAL(Size(16, 16), aTransformedSize); +} + CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 7959b13f8f68..2cbdb2fdb2b3 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -1208,7 +1208,7 @@ void OutputDevice::DrawTransformedBitmapEx( const bool bInvert(RasterOp::Invert == meRasterOp); const bool bBitmapChangedColor(mnDrawMode & (DrawModeFlags::BlackBitmap | DrawModeFlags::WhiteBitmap | DrawModeFlags::GrayBitmap )); bool bDone(false); - const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); + basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile ); if(bTryDirectPaint) @@ -1272,6 +1272,19 @@ void OutputDevice::DrawTransformedBitmapEx( aTransformed = BitmapEx(aContent, aMaskBmp); } + // Remove scaling from aFulltransform: we transform due to shearing or rotation, scaling + // will happen according to aDestSize. + basegfx::B2DVector aFullScale, aFullTranslate; + double fFullRotate, fFullShearX; + aFullTransform.decompose(aFullScale, aFullTranslate, fFullRotate, fFullShearX); + if (aFullScale.getX() != 0 && aFullScale.getY() != 0) + { + basegfx::B2DHomMatrix aTransform = basegfx::utils::createScaleB2DHomMatrix( + rOriginalSizePixel.getWidth() / aFullScale.getX(), + rOriginalSizePixel.getHeight() / aFullScale.getY()); + aFullTransform *= aTransform; + } + aTransformed = aTransformed.getTransformed( aFullTransform, aVisibleRange, _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
