[Libreoffice-commits] core.git: drawinglayer/CppunitTest_drawinglayer_processors.mk drawinglayer/qa drawinglayer/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Fri May 21 14:53:58 UTC 2021


 drawinglayer/CppunitTest_drawinglayer_processors.mk     |    1 
 drawinglayer/qa/unit/vclpixelprocessor2d.cxx            |   89 ++++++++++++++++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |   24 ++--
 3 files changed, 106 insertions(+), 8 deletions(-)

New commits:
commit 9bf9fea0afadef0912d38f0d08b2bf2959569100
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri May 21 14:48:58 2021 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri May 21 16:53:21 2021 +0200

    properly draw only parts of FillGradientPrimitive2D (tdf#139000)
    
    The size of the whole gradient is getDefinitionRange(), while
    getOutputRange() gives the area of it to draw.
    
    Change-Id: I85dd7fe51bcc9c332a6fb0e6748d5ac89266b910
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115923
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/drawinglayer/CppunitTest_drawinglayer_processors.mk b/drawinglayer/CppunitTest_drawinglayer_processors.mk
index 2c898e9b484a..94017d657d44 100644
--- a/drawinglayer/CppunitTest_drawinglayer_processors.mk
+++ b/drawinglayer/CppunitTest_drawinglayer_processors.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_CppunitTest_use_externals,drawinglayer_processors,\
 
 $(eval $(call gb_CppunitTest_add_exception_objects,drawinglayer_processors, \
 	drawinglayer/qa/unit/vclmetafileprocessor2d \
+	drawinglayer/qa/unit/vclpixelprocessor2d \
 ))
 
 $(eval $(call gb_CppunitTest_use_ure,drawinglayer_processors))
diff --git a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx
new file mode 100644
index 000000000000..17ef17969fe4
--- /dev/null
+++ b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <vcl/virdev.hxx>
+#include <vcl/BitmapReadAccess.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <tools/stream.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
+
+using namespace drawinglayer;
+
+class VclPixelProcessor2DTest : public test::BootstrapFixture
+{
+    // if enabled - check the result images with:
+    // "xdg-open ./workdir/CppunitTest/drawinglayer_processors.test.core/"
+    static constexpr const bool mbExportBitmap = false;
+
+    void exportDevice(const OUString& filename, const VclPtr<VirtualDevice>& device)
+    {
+        if (mbExportBitmap)
+        {
+            BitmapEx aBitmapEx(device->GetBitmapEx(Point(0, 0), device->GetOutputSizePixel()));
+            SvFileStream aStream(filename, StreamMode::WRITE | StreamMode::TRUNC);
+            GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx, aStream);
+        }
+    }
+
+public:
+    VclPixelProcessor2DTest()
+        : BootstrapFixture(true, false)
+    {
+    }
+
+    // Test that drawing only a part of a gradient draws the proper part of it.
+    void testTdf139000()
+    {
+        ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT);
+        device->SetOutputSizePixel(Size(100, 200));
+        device->SetBackground(Wallpaper(COL_RED));
+        device->Erase();
+
+        drawinglayer::geometry::ViewInformation2D view;
+        std::unique_ptr<processor2d::BaseProcessor2D> processor(
+            processor2d::createBaseProcessor2DFromOutputDevice(*device, view));
+        CPPUNIT_ASSERT(processor);
+
+        basegfx::B2DRange definitionRange(0, 0, 100, 200);
+        basegfx::B2DRange outputRange(0, 100, 100, 200); // Paint only lower half of the gradient.
+        attribute::FillGradientAttribute attributes(attribute::GradientStyle::Linear, 0, 0, 0, 0,
+                                                    COL_WHITE.getBColor(), COL_BLACK.getBColor());
+        rtl::Reference<primitive2d::FillGradientPrimitive2D> gradientPrimitive(
+            new primitive2d::FillGradientPrimitive2D(outputRange, definitionRange, attributes));
+        primitive2d::Primitive2DContainer primitives;
+        primitives.push_back(primitive2d::Primitive2DReference(gradientPrimitive));
+        processor->process(primitives);
+
+        exportDevice("test-tdf139000.png", device);
+        Bitmap bitmap = device->GetBitmap(Point(), device->GetOutputSizePixel());
+        Bitmap::ScopedReadAccess access(bitmap);
+        // The upper half should keep its red background color.
+        CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_RED), access->GetColor(Point(0, 99)));
+        // First line of the gradient should not be the start color, but something halfway.
+        CPPUNIT_ASSERT_LESS(static_cast<sal_uInt16>(16),
+                            access->GetColor(Point(0, 100)).GetColorError(COL_GRAY));
+        // Last line of the gradient should be the end color, or close.
+        CPPUNIT_ASSERT_LESS(static_cast<sal_uInt16>(16),
+                            access->GetColor(Point(0, 199)).GetColorError(COL_BLACK));
+    }
+
+    CPPUNIT_TEST_SUITE(VclPixelProcessor2DTest);
+    CPPUNIT_TEST(testTdf139000);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(VclPixelProcessor2DTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 143c9351a06a..9bdbf95a015b 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -1207,13 +1207,6 @@ void VclPixelProcessor2D::processFillGradientPrimitive2D(
 
     GradientStyle eGradientStyle = convertGradientStyle(rFillGradient.getStyle());
 
-    basegfx::B2DRange aRange(rPrimitive.getOutputRange());
-    aRange.transform(maCurrentTransformation);
-
-    const tools::Rectangle aRectangle(
-        sal_Int32(std::floor(aRange.getMinX())), sal_Int32(std::floor(aRange.getMinY())),
-        sal_Int32(std::ceil(aRange.getMaxX())), sal_Int32(std::ceil(aRange.getMaxY())));
-
     Gradient aGradient(eGradientStyle, Color(rFillGradient.getStartColor()),
                        Color(rFillGradient.getEndColor()));
 
@@ -1223,7 +1216,22 @@ void VclPixelProcessor2D::processFillGradientPrimitive2D(
     aGradient.SetOfsY(rFillGradient.getOffsetY() * 100.0);
     aGradient.SetSteps(rFillGradient.getSteps());
 
-    mpOutputDevice->DrawGradient(aRectangle, aGradient);
+    basegfx::B2DRange aOutputRange(rPrimitive.getOutputRange());
+    aOutputRange.transform(maCurrentTransformation);
+    basegfx::B2DRange aFullRange(rPrimitive.getDefinitionRange());
+    aFullRange.transform(maCurrentTransformation);
+
+    const tools::Rectangle aOutputRectangle(
+        std::floor(aOutputRange.getMinX()), std::floor(aOutputRange.getMinY()),
+        std::ceil(aOutputRange.getMaxX()), std::ceil(aOutputRange.getMaxY()));
+    const tools::Rectangle aFullRectangle(
+        std::floor(aFullRange.getMinX()), std::floor(aFullRange.getMinY()),
+        std::ceil(aFullRange.getMaxX()), std::ceil(aFullRange.getMaxY()));
+
+    mpOutputDevice->Push(PushFlags::CLIPREGION);
+    mpOutputDevice->IntersectClipRegion(aOutputRectangle);
+    mpOutputDevice->DrawGradient(aFullRectangle, aGradient);
+    mpOutputDevice->Pop();
 }
 
 } // end of namespace


More information about the Libreoffice-commits mailing list