tdf#160782: convert to bitmapEx from 0,0 to width,height

This is the way it's done everywhere.
Partially revert 4b6e0f2c88debaedb514c868e061c21e15215b6e
"tdf#160726, tdf#48062: Simplify how BitmapExs are created"

Change-Id: I15fea0b6855a65da7cb48b24fc00ba303e33dcf8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166456
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
index e50e59a1..22a20f0 100644
--- a/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
+++ b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
@@ -147,7 +147,8 @@ namespace drawinglayer::unorenderer
                        convertToBitmapEx(
                            std::move(xEmbedSeq),
                            aViewInformation2D,
                            basegfx::B2DRange(0, 0, nDiscreteWidth, nDiscreteHeight),
                            nDiscreteWidth,
                            nDiscreteHeight,
                            MaximumQuadraticPixels));

                    if(!aBitmapEx.IsEmpty())
diff --git a/drawinglayer/source/primitive2d/glowprimitive2d.cxx b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
index 5cec7a4..6bf9dea 100644
--- a/drawinglayer/source/primitive2d/glowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
@@ -176,8 +176,7 @@ void GlowPrimitive2D::create2DDecomposition(
    // I have now added a helper that just creates the mask without having
    // to render the content, use it, it's faster
    const AlphaMask aAlpha(::drawinglayer::createAlphaMask(
        std::move(xEmbedSeq), aViewInformation2D,
        basegfx::B2DRange(0, 0, nDiscreteClippedWidth, nDiscreteClippedHeight),
        std::move(xEmbedSeq), aViewInformation2D, nDiscreteClippedWidth, nDiscreteClippedHeight,
        nMaximumQuadraticPixels));

    if (aAlpha.IsEmpty())
diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
index 8068a386..516b004 100644
--- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
@@ -136,7 +136,8 @@ namespace drawinglayer::primitive2d
                    convertToBitmapEx(
                        std::move(xEmbedSeq),
                        aViewInformation2D,
                        basegfx::B2DRange(0, 0, mnDiscreteWidth, mnDiscreteHeight),
                        mnDiscreteWidth,
                        mnDiscreteHeight,
                        mnDiscreteWidth * mnDiscreteHeight));

                if(!aBitmapEx.IsEmpty())
@@ -196,7 +197,8 @@ namespace drawinglayer::primitive2d
            return convertToBitmapEx(
                        std::move(xEmbedSeq),
                        aViewInformation2D,
                        basegfx::B2DRange(0, 0, nWidth, nHeight),
                        nWidth,
                        nHeight,
                        nWidth * nHeight);
        }

diff --git a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
index c32f37b..5de34c5 100644
--- a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
@@ -217,8 +217,7 @@ void ShadowPrimitive2D::create2DDecomposition(
    // I have now added a helper that just creates the mask without having
    // to render the content, use it, it's faster
    const AlphaMask aAlpha(::drawinglayer::createAlphaMask(
        std::move(xEmbedSeq), aViewInformation2D,
        basegfx::B2DRange(0, 0, nDiscreteClippedWidth, nDiscreteClippedHeight),
        std::move(xEmbedSeq), aViewInformation2D, nDiscreteClippedWidth, nDiscreteClippedHeight,
        nMaximumQuadraticPixels));

    // if we have no shadow, we are done
diff --git a/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx b/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
index fb01242..e6f92f3 100644
--- a/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
@@ -174,8 +174,7 @@ void SoftEdgePrimitive2D::create2DDecomposition(
        // Otherwise, blurring of edges will fail in cases like running in a
        // slideshow or exporting to PDF.
        const BitmapEx aBitmapEx(::drawinglayer::convertToBitmapEx(
            std::move(xEmbedSeq), aViewInformation2D,
            basegfx::B2DRange(0, 0, nDiscreteClippedWidth, nDiscreteClippedHeight),
            std::move(xEmbedSeq), aViewInformation2D, nDiscreteClippedWidth, nDiscreteClippedHeight,
            nMaximumQuadraticPixels, true));

        if (aBitmapEx.IsEmpty())
diff --git a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
index 5347378..6bfc958 100644
--- a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
@@ -1060,9 +1060,8 @@ sal::systools::COMReference<ID2D1Bitmap> D2DPixelProcessor2D::implCreateAlpha_B2

    // use new mode to create AlphaChannel (not just AlphaMask) for transparency channel
    const AlphaMask aAlpha(::drawinglayer::createAlphaMask(
        std::move(xEmbedSeq), aEmptyViewInformation2D,
        basegfx::B2DRange(0, 0, nDiscreteClippedWidth, nDiscreteClippedHeight),
        nMaximumQuadraticPixels, true));
        std::move(xEmbedSeq), aEmptyViewInformation2D, nDiscreteClippedWidth,
        nDiscreteClippedHeight, nMaximumQuadraticPixels, true));
    sal::systools::COMReference<ID2D1Bitmap> pRetval;

    if (aAlpha.IsEmpty())
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index e3c7703..d93d98f 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -2524,11 +2524,9 @@ void VclMetafileProcessor2D::processTransparencePrimitive2D(
    // limitation to paint the content
    const auto aViewInformation2D(geometry::createViewInformation2D({}));
    const sal_uInt32 nMaximumQuadraticPixels(500000);
    const BitmapEx aBitmapEx(
        convertToBitmapEx(std::move(xEmbedSeq), aViewInformation2D,
                          basegfx::B2DRange(0, 0, basegfx::fround(aDiscreteRange.getWidth()),
                                            basegfx::fround(aDiscreteRange.getHeight())),
                          nMaximumQuadraticPixels));
    const BitmapEx aBitmapEx(convertToBitmapEx(
        std::move(xEmbedSeq), aViewInformation2D, basegfx::fround(aDiscreteRange.getWidth()),
        basegfx::fround(aDiscreteRange.getHeight()), nMaximumQuadraticPixels));

    // add to target metafile (will create MetaFloatTransparentAction)
    mpOutputDevice->DrawBitmapEx(Point(basegfx::fround<tools::Long>(aLogicRange.getMinX()),
diff --git a/drawinglayer/source/tools/converters.cxx b/drawinglayer/source/tools/converters.cxx
index a040a7c..cf339f8 100644
--- a/drawinglayer/source/tools/converters.cxx
+++ b/drawinglayer/source/tools/converters.cxx
@@ -73,7 +73,7 @@ bool implPrepareConversion(drawinglayer::primitive2d::Primitive2DContainer& rSeq

AlphaMask implcreateAlphaMask(drawinglayer::primitive2d::Primitive2DContainer& rSequence,
                              const drawinglayer::geometry::ViewInformation2D& rViewInformation2D,
                              const Size& rSizePixel, const Point& rPoint, bool bUseLuminance)
                              const Size& rSizePixel, bool bUseLuminance)
{
    ScopedVclPtrInstance<VirtualDevice> pContent;

@@ -122,11 +122,12 @@ AlphaMask implcreateAlphaMask(drawinglayer::primitive2d::Primitive2DContainer& r

    // get alpha channel from vdev
    pContent->EnableMapMode(false);
    const Point aEmptyPoint;

    // Convert from transparency->alpha.
    // FIXME in theory I should be able to directly construct alpha by using black as background
    // and white as foreground, but that doesn't work for some reason.
    Bitmap aContentBitmap = pContent->GetBitmap(rPoint, rSizePixel);
    Bitmap aContentBitmap = pContent->GetBitmap(aEmptyPoint, rSizePixel);
    aContentBitmap.Invert();

    return AlphaMask(aContentBitmap);
@@ -137,39 +138,34 @@ namespace drawinglayer
{
AlphaMask createAlphaMask(drawinglayer::primitive2d::Primitive2DContainer&& rSeq,
                          const geometry::ViewInformation2D& rViewInformation2D,
                           const basegfx::B2DRange& rTargetRange,
                          sal_uInt32 nDiscreteWidth, sal_uInt32 nDiscreteHeight,
                          sal_uInt32 nMaxSquarePixels, bool bUseLuminance)
{
    drawinglayer::primitive2d::Primitive2DContainer aSequence(std::move(rSeq));
    sal_uInt32 nDiscreteWidth = rTargetRange.getWidth();
    sal_uInt32 nDiscreteHeight = rTargetRange.getHeight();

    if (!implPrepareConversion(aSequence, nDiscreteWidth, nDiscreteHeight, nMaxSquarePixels))
    {
        return AlphaMask();
    }

    const Point aPoint(rTargetRange.getMinX(), rTargetRange.getMinY());
    const Size aSizePixel(nDiscreteWidth, nDiscreteHeight);

    return implcreateAlphaMask(aSequence, rViewInformation2D, aSizePixel, aPoint, bUseLuminance);
    return implcreateAlphaMask(aSequence, rViewInformation2D, aSizePixel, bUseLuminance);
}

BitmapEx convertToBitmapEx(drawinglayer::primitive2d::Primitive2DContainer&& rSeq,
                           const geometry::ViewInformation2D& rViewInformation2D,
                           const basegfx::B2DRange& rTargetRange,
                           sal_uInt32 nDiscreteWidth, sal_uInt32 nDiscreteHeight,
                           sal_uInt32 nMaxSquarePixels, bool bForceAlphaMaskCreation)
{
    drawinglayer::primitive2d::Primitive2DContainer aSequence(std::move(rSeq));
    sal_uInt32 nDiscreteWidth = rTargetRange.getWidth();
    sal_uInt32 nDiscreteHeight = rTargetRange.getHeight();

    if (!implPrepareConversion(aSequence, nDiscreteWidth, nDiscreteHeight, nMaxSquarePixels))
    {
        return BitmapEx();
    }

    const Point aPoint(rTargetRange.getMinX(), rTargetRange.getMinY());
    const Point aEmptyPoint;
    const Size aSizePixel(nDiscreteWidth, nDiscreteHeight);

    // Create target VirtualDevice. Go back to using a simple RGB
@@ -228,7 +224,7 @@ BitmapEx convertToBitmapEx(drawinglayer::primitive2d::Primitive2DContainer&& rSe
    pContentProcessor->process(aSequence);

    // create final BitmapEx result (content)
    Bitmap aRetval(pContent->GetBitmap(aPoint, aSizePixel));
    Bitmap aRetval(pContent->GetBitmap(aEmptyPoint, aSizePixel));

#ifdef DBG_UTIL
    static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
@@ -249,7 +245,7 @@ BitmapEx convertToBitmapEx(drawinglayer::primitive2d::Primitive2DContainer&& rSe
    // Create the AlphaMask using a method that does this always correct (also used
    // now in GlowPrimitive2D and ShadowPrimitive2D which both only need the
    // AlphaMask to do their job, so speeding that up, too).
    AlphaMask aAlpha(implcreateAlphaMask(aSequence, rViewInformation2D, aSizePixel, aPoint, false));
    AlphaMask aAlpha(implcreateAlphaMask(aSequence, rViewInformation2D, aSizePixel, false));

#ifdef DBG_UTIL
    if (bDoSaveForVisualControl)
@@ -360,7 +356,7 @@ BitmapEx convertPrimitive2DContainerToBitmapEx(primitive2d::Primitive2DContainer
        primitive2d::Primitive2DContainer xEmbedSeq{ xEmbedRef };

        BitmapEx aBitmapEx(convertToBitmapEx(std::move(xEmbedSeq), aViewInformation2D,
                                             basegfx::B2DRange(0, 0, nDiscreteWidth, nDiscreteHeight),
                                             nDiscreteWidth, nDiscreteHeight,
                                             nMaximumQuadraticPixels));

        if (aBitmapEx.IsEmpty())
diff --git a/include/drawinglayer/converters.hxx b/include/drawinglayer/converters.hxx
index 4e4d621..d090b1e 100644
--- a/include/drawinglayer/converters.hxx
+++ b/include/drawinglayer/converters.hxx
@@ -33,15 +33,15 @@ namespace drawinglayer
//           for any content (e.g. gradients)
AlphaMask DRAWINGLAYER_DLLPUBLIC createAlphaMask(
    drawinglayer::primitive2d::Primitive2DContainer&& rSeq,
    const geometry::ViewInformation2D& rViewInformation2D, const basegfx::B2DRange& rTargetRange,
    sal_uInt32 nMaxSquarePixels, bool bUseLuminance = false);
    const geometry::ViewInformation2D& rViewInformation2D, sal_uInt32 nDiscreteWidth,
    sal_uInt32 nDiscreteHeight, sal_uInt32 nMaxSquarePixels, bool bUseLuminance = false);

// Helper for convertPrimitive2DContainerToBitmapEx below, but can be also used
// directly
BitmapEx DRAWINGLAYER_DLLPUBLIC convertToBitmapEx(
    drawinglayer::primitive2d::Primitive2DContainer&& rSeq,
    const geometry::ViewInformation2D& rViewInformation2D, const basegfx::B2DRange& rTargetRange,
    sal_uInt32 nMaxSquarePixels, bool bForceAlphaMaskCreation = false);
    const geometry::ViewInformation2D& rViewInformation2D, sal_uInt32 nDiscreteWidth,
    sal_uInt32 nDiscreteHeight, sal_uInt32 nMaxSquarePixels, bool bForceAlphaMaskCreation = false);

// helper to convert any Primitive2DSequence to a good quality BitmapEx,
// using default parameters
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index abf7f58..31eb63c 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -1625,13 +1625,13 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf160517)
    assertXPath(pDocument,
            "/primitive2D/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D//transform/bitmap"_ostr, "xy13"_ostr, "10");
            "/primitive2D//transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D//transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D//transform/bitmap"_ostr, "xy22"_ostr, "110");
    assertXPath(pDocument,
            "/primitive2D//transform/bitmap"_ostr, "xy23"_ostr, "10");
            "/primitive2D//transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D//transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1661,13 +1661,13 @@ CPPUNIT_TEST_FIXTURE(Test, testArithmeticComposite)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "50");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "50");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1678,7 +1678,7 @@ CPPUNIT_TEST_FIXTURE(Test, testArithmeticComposite)
    // Check the colors in the diagonal
    OUString sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[25]"_ostr, "row"_ostr);
    std::vector<OUString> aPixels = comphelper::string::split(sDataRow, ',');
    CPPUNIT_ASSERT_EQUAL(OUString("ff8000"), aPixels[25]);
    CPPUNIT_ASSERT_EQUAL(OUString("000000"), aPixels[25]);

    sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[75]"_ostr, "row"_ostr);
    aPixels = comphelper::string::split(sDataRow, ',');
@@ -1686,7 +1686,7 @@ CPPUNIT_TEST_FIXTURE(Test, testArithmeticComposite)

    sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[125]"_ostr, "row"_ostr);
    aPixels = comphelper::string::split(sDataRow, ',');
    CPPUNIT_ASSERT_EQUAL(OUString("000000"), aPixels[125]);
    CPPUNIT_ASSERT_EQUAL(OUString("ff8000"), aPixels[125]);
}

CPPUNIT_TEST_FIXTURE(Test, testArithmeticComposite2)
@@ -1705,13 +1705,13 @@ CPPUNIT_TEST_FIXTURE(Test, testArithmeticComposite2)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1777,6 +1777,50 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf160726)
    CPPUNIT_ASSERT_EQUAL(OUString("ffff00"), aPixels[200]);
}

CPPUNIT_TEST_FIXTURE(Test, testTdf160782)
{
    xmlDocUniquePtr pDocument = dumpAndParseSvg(u"/svgio/qa/cppunit/data/tdf160782.svg");

    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "height"_ostr, "255");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "width"_ostr, "255");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap/data"_ostr, 255);

    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy11"_ostr, "255");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "255");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy32"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy33"_ostr, "1");

    // Check the colors in the diagonal
    OUString sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[50]"_ostr, "row"_ostr);
    std::vector<OUString> aPixels = comphelper::string::split(sDataRow, ',');
    CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aPixels[50]);

    sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[125]"_ostr, "row"_ostr);
    aPixels = comphelper::string::split(sDataRow, ',');
    CPPUNIT_ASSERT_EQUAL(OUString("ffff00"), aPixels[125]);

    sDataRow = getXPath(pDocument, "/primitive2D/transform/transform/bitmap/data[200]"_ostr, "row"_ostr);
    aPixels = comphelper::string::split(sDataRow, ',');
    CPPUNIT_ASSERT_EQUAL(OUString("ffff00"), aPixels[200]);
}

CPPUNIT_TEST_FIXTURE(Test, testScreenBlend)
{
    xmlDocUniquePtr pDocument = dumpAndParseSvg(u"/svgio/qa/cppunit/data/screenBlend.svg");
@@ -1793,13 +1837,13 @@ CPPUNIT_TEST_FIXTURE(Test, testScreenBlend)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1837,13 +1881,13 @@ CPPUNIT_TEST_FIXTURE(Test, testMultiplyBlend)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1881,13 +1925,13 @@ CPPUNIT_TEST_FIXTURE(Test, testDarkenBlend)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
@@ -1925,13 +1969,13 @@ CPPUNIT_TEST_FIXTURE(Test, testLightenBlend)
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy12"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy13"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy21"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy22"_ostr, "150");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "20");
            "/primitive2D/transform/transform/bitmap"_ostr, "xy23"_ostr, "0");
    assertXPath(pDocument,
            "/primitive2D/transform/transform/bitmap"_ostr, "xy31"_ostr, "0");
    assertXPath(pDocument,
diff --git a/svgio/qa/cppunit/data/tdf160782.svg b/svgio/qa/cppunit/data/tdf160782.svg
new file mode 100644
index 0000000..1464e69
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf160782.svg
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   width="500"
   height="500"
   viewBox="0 0 500 500"
   version="1.1">
  <defs
     id="defs2">
    <filter
       height="2"
       width="2"
       id="filter2103">
      <feOffset
         result="result1"
         id="feOffset2097"
         dy="50"
         dx="50" />
      <feColorMatrix
         result="result2"
         values="1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 "
         id="feColorMatrix2099" />
      <feComposite
         operator="arithmetic"
         in="result2"
         id="feComposite2101"
         in2="SourceGraphic"
         k1="0"
         k2="1"
         k3="1"
         k4="0"/>
    </filter>
  </defs>
  <g>
    <circle
       r="100"
       cy="100"
       cx="100"
       id="circle2113"
       style="fill:#ff0000;stroke:#000000;stroke-width:10.754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter2103)" />
  </g>
</svg>
diff --git a/svgio/source/svgreader/svgfeblendnode.cxx b/svgio/source/svgreader/svgfeblendnode.cxx
index af6406e..a5109aa 100644
--- a/svgio/source/svgreader/svgfeblendnode.cxx
+++ b/svgio/source/svgreader/svgfeblendnode.cxx
@@ -134,12 +134,8 @@ void SvgFeBlendNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTar
            aRange2 = pSource2->getB2DRange(aViewInformation2D);
        }

        const sal_Int32 nX1 = std::min(aRange.getMinX(), aRange2.getMinX());
        const sal_Int32 nY1 = std::min(aRange.getMinY(), aRange2.getMinY());
        const sal_Int32 nX2 = std::max(aRange.getMaxX(), aRange2.getMaxX());
        const sal_Int32 nY2 = std::max(aRange.getMaxY(), aRange2.getMaxY());

        const basegfx::B2DRange aBaseRange(nX1, nY1, nX1 + nX2, nY1 + nY2);
        const basegfx::B2DRange aBaseRange(0, 0, std::max(aRange.getMaxX(), aRange2.getMaxX()),
                                           std::max(aRange.getMaxY(), aRange2.getMaxY()));

        BitmapEx aBmpEx, aBmpEx2;

@@ -147,28 +143,28 @@ void SvgFeBlendNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTar
        {
            drawinglayer::primitive2d::Primitive2DContainer aSource(*pSource);
            aBmpEx = drawinglayer::convertToBitmapEx(
                std::move(aSource), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(aSource), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }
        else
        {
            aBmpEx = drawinglayer::convertToBitmapEx(
                std::move(rTarget), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(rTarget), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }

        if (pSource2)
        {
            drawinglayer::primitive2d::Primitive2DContainer aSource(*pSource2);
            aBmpEx2 = drawinglayer::convertToBitmapEx(
                std::move(aSource), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(aSource), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }
        else
        {
            aBmpEx2 = drawinglayer::convertToBitmapEx(
                std::move(rTarget), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(rTarget), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }

        BitmapEx aResBmpEx;
diff --git a/svgio/source/svgreader/svgfecompositenode.cxx b/svgio/source/svgreader/svgfecompositenode.cxx
index 9136436..0dea908 100644
--- a/svgio/source/svgreader/svgfecompositenode.cxx
+++ b/svgio/source/svgreader/svgfecompositenode.cxx
@@ -223,12 +223,8 @@ void SvgFeCompositeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& 
            aRange2 = pSource2->getB2DRange(aViewInformation2D);
        }

        const sal_uInt32 nX1 = std::min(aRange.getMinX(), aRange2.getMinX());
        const sal_uInt32 nY1 = std::min(aRange.getMinY(), aRange2.getMinY());
        const sal_uInt32 nX2 = std::max(aRange.getMaxX(), aRange2.getMaxX());
        const sal_uInt32 nY2 = std::max(aRange.getMaxY(), aRange2.getMaxY());

        const basegfx::B2DRange aBaseRange(nX1, nY1, nX1 + nX2, nY1 + nY2);
        const basegfx::B2DRange aBaseRange(0, 0, std::max(aRange.getMaxX(), aRange2.getMaxX()),
                                           std::max(aRange.getMaxY(), aRange2.getMaxY()));

        BitmapEx aBmpEx, aBmpEx2;

@@ -236,28 +232,28 @@ void SvgFeCompositeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& 
        {
            drawinglayer::primitive2d::Primitive2DContainer aSource(*pSource);
            aBmpEx = drawinglayer::convertToBitmapEx(
                std::move(aSource), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(aSource), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }
        else
        {
            aBmpEx = drawinglayer::convertToBitmapEx(
                std::move(rTarget), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(rTarget), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }

        if (pSource2)
        {
            drawinglayer::primitive2d::Primitive2DContainer aSource(*pSource2);
            aBmpEx2 = drawinglayer::convertToBitmapEx(
                std::move(aSource), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(aSource), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }
        else
        {
            aBmpEx2 = drawinglayer::convertToBitmapEx(
                std::move(rTarget), aViewInformation2D, aBaseRange,
                aBaseRange.getWidth() * aBaseRange.getHeight());
                std::move(rTarget), aViewInformation2D, aBaseRange.getWidth(),
                aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight());
        }

        BitmapArithmeticBlendFilter aArithmeticFilter(aBmpEx, aBmpEx2);