[Libreoffice-commits] core.git: 6 commits - include/vcl svx/inc svx/Library_svxcore.mk svx/source vcl/CppunitTest_vcl_bitmap_test.mk vcl/inc vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/qa vcl/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Thu Mar 26 23:29:07 PDT 2015


 include/vcl/BitmapFilterStackBlur.hxx       |   34 +
 include/vcl/bmpacc.hxx                      |  381 +++++++++---------
 include/vcl/pngwrite.hxx                    |   15 
 svx/Library_svxcore.mk                      |    1 
 svx/inc/sdr/overlay/overlayhandle.hxx       |   42 +
 svx/inc/sdr/overlay/overlaytools.hxx        |   36 +
 svx/source/sdr/overlay/overlayhandle.cxx    |   63 ++
 svx/source/sdr/overlay/overlaytools.cxx     |   89 ++++
 svx/source/svdraw/svdhdl.cxx                |   54 ++
 vcl/CppunitTest_vcl_bitmap_test.mk          |   57 ++
 vcl/Library_vcl.mk                          |    2 
 vcl/Module_vcl.mk                           |    1 
 vcl/inc/BitmapSymmetryCheck.hxx             |   31 +
 vcl/qa/cppunit/BitmapFilterTest.cxx         |  175 ++++++++
 vcl/qa/cppunit/BitmapTest.cxx               |   88 ++++
 vcl/source/bitmap/BitmapFilterStackBlur.cxx |  590 ++++++++++++++++++++++++++++
 vcl/source/bitmap/BitmapSymmetryCheck.cxx   |   81 +++
 vcl/source/gdi/bmpacc.cxx                   |  122 ++++-
 vcl/source/gdi/bmpacc2.cxx                  |   65 +--
 vcl/source/gdi/bmpacc3.cxx                  |  177 ++++----
 vcl/source/gdi/pngwrite.cxx                 |  539 ++++++++++++++-----------
 21 files changed, 2078 insertions(+), 565 deletions(-)

New commits:
commit 28c61871e876e6a2cac47439f768504b1a4c94a0
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Mar 26 22:44:32 2015 +0900

    vcl: stack blur implementation + basic test & performance test
    
    Change-Id: I793ed80a07d9488c5f75b3abdca6db344d80d3d8

diff --git a/include/vcl/BitmapFilterStackBlur.hxx b/include/vcl/BitmapFilterStackBlur.hxx
new file mode 100644
index 0000000..9b400c8
--- /dev/null
+++ b/include/vcl/BitmapFilterStackBlur.hxx
@@ -0,0 +1,34 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+#define INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/bitmapfilter.hxx>
+
+class VCL_DLLPUBLIC BitmapFilterStackBlur : BitmapFilter
+{
+    sal_Int32 mnRadius;
+    bool mbExtend;
+
+public:
+    BitmapFilterStackBlur(sal_Int32 nRadius, bool bExtend = true);
+    virtual ~BitmapFilterStackBlur();
+
+    virtual bool filter(Bitmap& rBitmap) SAL_OVERRIDE;
+
+    bool filter(BitmapEx& rBitmap);
+};
+
+#endif // INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/CppunitTest_vcl_bitmap_test.mk b/vcl/CppunitTest_vcl_bitmap_test.mk
index 527f5ef..5927b69 100644
--- a/vcl/CppunitTest_vcl_bitmap_test.mk
+++ b/vcl/CppunitTest_vcl_bitmap_test.mk
@@ -11,6 +11,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,vcl_bitmap_test))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,vcl_bitmap_test, \
     vcl/qa/cppunit/BitmapTest \
+    vcl/qa/cppunit/BitmapFilterTest \
 ))
 
 $(eval $(call gb_CppunitTest_use_externals,vcl_bitmap_test,\
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 4507f5e..89ed3bb 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -316,6 +316,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/bitmap/bitmapfilter \
     vcl/source/bitmap/bitmapscalesuper \
     vcl/source/bitmap/BitmapSymmetryCheck \
+    vcl/source/bitmap/BitmapFilterStackBlur \
     vcl/source/helper/canvasbitmap \
     vcl/source/helper/canvastools \
     vcl/source/helper/evntpost \
diff --git a/vcl/qa/cppunit/BitmapFilterTest.cxx b/vcl/qa/cppunit/BitmapFilterTest.cxx
new file mode 100644
index 0000000..e0cf3ef
--- /dev/null
+++ b/vcl/qa/cppunit/BitmapFilterTest.cxx
@@ -0,0 +1,175 @@
+/* -*- 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 <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <tools/stream.hxx>
+#include <vcl/graphicfilter.hxx>
+
+#include <vcl/BitmapFilterStackBlur.hxx>
+#include "BitmapSymmetryCheck.hxx"
+
+#include <chrono>
+
+namespace
+{
+
+const bool constWriteResultBitmap(false);
+const bool constEnablePerformanceTest(false);
+
+class BitmapFilterTest : public CppUnit::TestFixture
+{
+
+    void testBlurCorrectness();
+    void testPerformance();
+
+    CPPUNIT_TEST_SUITE(BitmapFilterTest);
+    CPPUNIT_TEST(testBlurCorrectness);
+    CPPUNIT_TEST(testPerformance);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void BitmapFilterTest::testBlurCorrectness()
+{
+    // Setup test bitmap
+    Size aSize(41, 31);
+    Bitmap aBitmap24Bit(aSize, 24);
+
+    sal_uLong nScanlineFormat = 0;
+    sal_uInt16 nBPP = aBitmap24Bit.GetBitCount();
+
+    {
+        long aMargin1 = 1;
+        long aMargin2 = 3;
+        Bitmap::ScopedWriteAccess aWriteAccess(aBitmap24Bit);
+        nScanlineFormat = aWriteAccess->GetScanlineFormat();
+        aWriteAccess->Erase(COL_WHITE);
+        aWriteAccess->SetLineColor(COL_BLACK);
+
+        Rectangle aRectangle1(
+                    aMargin1,
+                    aMargin1,
+                    aSize.Width() - 1 - aMargin1,
+                    aSize.Height() - 1 - aMargin1);
+
+        Rectangle aRectangle2(
+                    aMargin2,
+                    aMargin2,
+                    aSize.Width() - 1 - aMargin2,
+                    aSize.Height() - 1 - aMargin2);
+
+        Rectangle aRectangle3(
+                    aSize.Width()  / 2,
+                    aSize.Height() / 2,
+                    aSize.Width()  / 2,
+                    aSize.Height() / 2);
+
+        aWriteAccess->DrawRect(aRectangle1);
+        aWriteAccess->DrawRect(aRectangle2);
+        aWriteAccess->DrawRect(aRectangle3);
+    }
+
+    if (constWriteResultBitmap)
+    {
+        SvFileStream aStream(OUString("~/blurBefore.png"), StreamMode::WRITE | StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream, 1);
+    }
+
+    // Perform blur
+    BitmapFilterStackBlur aBlurFilter(2);
+    aBlurFilter.filter(aBitmap24Bit);
+
+    // Check the result
+
+    if (constWriteResultBitmap)
+    {
+        SvFileStream aStream(OUString("~/blurAfter.png"), StreamMode::WRITE | StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream, 1);
+    }
+
+    // Check blurred bitmap parameters
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(45), aBitmap24Bit.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(35), aBitmap24Bit.GetSizePixel().Height());
+
+    CPPUNIT_ASSERT_EQUAL(nBPP, aBitmap24Bit.GetBitCount());
+
+    // Check that the bitmap is horizontally and vertically symmetrical
+    BitmapSymmetryCheck symmetryCheck;
+    CPPUNIT_ASSERT(symmetryCheck.check(aBitmap24Bit));
+
+    {
+        Bitmap::ScopedReadAccess aReadAccess(aBitmap24Bit);
+        CPPUNIT_ASSERT_EQUAL(nScanlineFormat, aReadAccess->GetScanlineFormat());
+    }
+}
+
+void BitmapFilterTest::testPerformance()
+{
+    if (!constEnablePerformanceTest)
+        return;
+
+    Size aSize(4000, 3000); // A rather common picture size
+
+    // Prepare bitmap
+    Bitmap aBigBitmap(aSize, 24);
+    {
+        long aMargin = 500;
+        Bitmap::ScopedWriteAccess aWriteAccess(aBigBitmap);
+        aWriteAccess->Erase(COL_WHITE);
+        aWriteAccess->SetLineColor(COL_BLACK);
+        aWriteAccess->SetFillColor(COL_BLACK);
+        Rectangle aRectangle(
+                    aMargin,
+                    aMargin,
+                    aSize.Width() - 1 - aMargin,
+                    aSize.Height() - 1 - aMargin);
+
+        aWriteAccess->DrawRect(aRectangle);
+    }
+
+    int nIterations = 10;
+    auto start = std::chrono::high_resolution_clock::now();
+    for (int i = 0; i < nIterations; i++)
+    {
+        {
+            BitmapFilterStackBlur aBlurFilter(250, false); // don't extend the image
+            aBlurFilter.filter(aBigBitmap);
+        }
+    }
+    auto end = std::chrono::high_resolution_clock::now();
+    auto elapsed = (end - start) / nIterations;
+
+    if (constWriteResultBitmap)
+    {
+        std::unique_ptr<SvFileStream> pStream(
+            new SvFileStream(OUString("~/BlurBigPerformance.png"), StreamMode::WRITE | StreamMode::TRUNC));
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBigBitmap, *pStream, 1);
+
+        pStream.reset(
+            new SvFileStream(OUString("~/BlurBigPerformance.txt"), StreamMode::WRITE));
+        pStream->WriteOString(OString("Blur average time: "));
+        pStream->WriteOString(OString::number(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()));
+        pStream->WriteOString(OString("\n"));
+    }
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BitmapFilterTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/bitmap/BitmapFilterStackBlur.cxx b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
new file mode 100644
index 0000000..126eee0
--- /dev/null
+++ b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
@@ -0,0 +1,590 @@
+/* -*- 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 <vcl/BitmapFilterStackBlur.hxx>
+#include <vcl/bmpacc.hxx>
+
+namespace
+{
+
+static const sal_Int16 constMultiplyTable[255] =
+{
+    512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512,
+    454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512,
+    482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456,
+    437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512,
+    497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328,
+    320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456,
+    446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335,
+    329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512,
+    505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405,
+    399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328,
+    324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271,
+    268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456,
+    451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388,
+    385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335,
+    332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292,
+    289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259
+};
+
+static const sal_Int16 constShiftTable[255] =
+{
+     9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
+    17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
+    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
+    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
+    22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+    22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+    23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
+};
+
+class BlurSharedData
+{
+public:
+    long mnRadius;
+    long mnComponentWidth;
+    long mnColorChannels;
+    long mnDiv;
+    std::vector<sal_uInt8> maStackBuffer;
+    std::vector<long> maPositionTable;
+    std::vector<long> maWeightTable;
+
+    std::vector<long> mnSumVector;
+    std::vector<long> mnInSumVector;
+    std::vector<long> mnOutSumVector;
+
+    BlurSharedData(long aRadius, long nComponentWidth, long nColorChannels)
+        : mnRadius(aRadius)
+        , mnComponentWidth(nComponentWidth)
+        , mnColorChannels(nColorChannels)
+        , mnDiv(aRadius + aRadius + 1)
+        , maStackBuffer(mnDiv * mnComponentWidth)
+        , maPositionTable(mnDiv)
+        , maWeightTable(mnDiv)
+        , mnSumVector(mnColorChannels)
+        , mnInSumVector(mnColorChannels)
+        , mnOutSumVector(mnColorChannels)
+    {
+    }
+
+    void calculateWeightAndPositions(long nLastIndex)
+    {
+        for (long i = 0; i < mnDiv; i++)
+        {
+            maPositionTable[i] = std::min(nLastIndex, std::max(0L, i - mnRadius));
+            maWeightTable[i] = mnRadius + 1 - std::abs(i - mnRadius);
+        }
+    }
+
+    long getMultiplyValue()
+    {
+        return static_cast<long>(constMultiplyTable[mnRadius]);
+    }
+
+    long getShiftValue()
+    {
+        return static_cast<long>(constShiftTable[mnRadius]);
+    }
+};
+
+struct SumFunction24
+{
+    static inline void add(long*& pValue1, long nConstant)
+    {
+        pValue1[0] += nConstant;
+        pValue1[1] += nConstant;
+        pValue1[2] += nConstant;
+    }
+
+    static inline void set(long*& pValue1, long nConstant)
+    {
+        pValue1[0] = nConstant;
+        pValue1[1] = nConstant;
+        pValue1[2] = nConstant;
+    }
+
+    static inline void add(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+        pValue1[1] += pValue2[1];
+        pValue1[2] += pValue2[2];
+    }
+
+    static inline void add(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+        pValue1[1] += pValue2[1];
+        pValue1[2] += pValue2[2];
+    }
+
+    static inline void sub(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+        pValue1[1] -= pValue2[1];
+        pValue1[2] -= pValue2[2];
+    }
+
+    static inline void sub(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+        pValue1[1] -= pValue2[1];
+        pValue1[2] -= pValue2[2];
+    }
+
+    static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] = pValue2[0];
+        pValue1[1] = pValue2[1];
+        pValue1[2] = pValue2[2];
+    }
+
+    static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long multiply, long shift)
+    {
+        result[0] = (multiply * sum[0]) >> shift;
+        result[1] = (multiply * sum[1]) >> shift;
+        result[2] = (multiply * sum[2]) >> shift;
+    }
+};
+
+struct SumFunction8
+{
+    static inline void add(long*& pValue1, long nConstant)
+    {
+        pValue1[0] += nConstant;
+    }
+
+    static inline void set(long*& pValue1, long nConstant)
+    {
+        pValue1[0] = nConstant;
+    }
+
+    static inline void add(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+    }
+
+    static inline void add(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+    }
+
+    static inline void sub(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+    }
+
+    static inline void sub(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+    }
+
+    static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] = pValue2[0];
+    }
+
+    static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long multiply, long shift)
+    {
+        result[0] = (multiply * sum[0]) >> shift;
+    }
+};
+
+template<typename SumFunction>
+void stackBlurHorizontal(
+        BitmapReadAccess* pReadAccess,
+        BitmapWriteAccess* pWriteAccess,
+        BlurSharedData& rShared)
+{
+    long nWidth = pReadAccess->Width();
+    long nHeight = pReadAccess->Height();
+
+    sal_uInt8* pStack = rShared.maStackBuffer.data();
+    sal_uInt8* pStackPtr;
+
+    long nLastIndexX = nWidth - 1;
+
+    long nMultiplyValue = rShared.getMultiplyValue();
+    long nShiftValue = rShared.getShiftValue();
+
+    long nRadius = rShared.mnRadius;
+    long nComponentWidth = rShared.mnComponentWidth;
+    long nDiv = rShared.mnDiv;
+
+    Scanline pSourcePointer;
+    Scanline pDestinationPointer;
+
+    long nXPosition;
+    long nStackIndex;
+    long nStackIndexStart;
+    long nWeight;
+
+    long* nSum = rShared.mnSumVector.data();
+    long* nInSum = rShared.mnInSumVector.data();
+    long* nOutSum = rShared.mnOutSumVector.data();
+
+    rShared.calculateWeightAndPositions(nLastIndexX);
+    long* pPositionPointer = rShared.maPositionTable.data();
+    long* pWeightPointer = rShared.maWeightTable.data();
+
+    for (long y = 0; y < nHeight; y++)
+    {
+        SumFunction::set(nSum, 0L);
+        SumFunction::set(nInSum, 0L);
+        SumFunction::set(nOutSum, 0L);
+
+        for (long i = 0; i < nDiv; i++)
+        {
+            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+
+            pStackPtr = &pStack[nComponentWidth * i];
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            nWeight = pWeightPointer[i];
+
+            SumFunction::add(nSum, pSourcePointer[0] * nWeight);
+
+            if (i - nRadius > 0)
+            {
+                SumFunction::add(nInSum, pSourcePointer);
+            }
+            else
+            {
+                SumFunction::add(nOutSum, pSourcePointer);
+            }
+        }
+
+        nStackIndex = nRadius;
+        nXPosition = std::min(nRadius, nLastIndexX);
+
+        pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * nXPosition;
+
+        for (long x = 0; x < nWidth; x++)
+        {
+            pDestinationPointer = pWriteAccess->GetScanline(y) + nComponentWidth * x;
+
+            SumFunction::assignMulAndShr(pDestinationPointer, nSum, nMultiplyValue, nShiftValue);
+
+            SumFunction::sub(nSum, nOutSum);
+
+            nStackIndexStart = nStackIndex + nDiv - nRadius;
+            if (nStackIndexStart >= nDiv)
+            {
+                nStackIndexStart -= nDiv;
+            }
+            pStackPtr = &pStack[nComponentWidth * nStackIndexStart];
+
+            SumFunction::sub(nOutSum, pStackPtr);
+
+            if (nXPosition < nLastIndexX)
+            {
+                nXPosition++;
+                pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * nXPosition;
+            }
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            SumFunction::add(nInSum, pSourcePointer);
+
+            SumFunction::add(nSum, nInSum);
+
+            nStackIndex++;
+            if (nStackIndex >= nDiv)
+            {
+                nStackIndex = 0;
+            }
+
+            pStackPtr = &pStack[nStackIndex * nComponentWidth];
+
+            SumFunction::add(nOutSum, pStackPtr);
+            SumFunction::sub(nInSum, pStackPtr);
+        }
+    }
+}
+
+template<typename SumFunction>
+void stackBlurVertical(
+        BitmapReadAccess* pReadAccess,
+        BitmapWriteAccess* pWriteAccess,
+        BlurSharedData& rShared)
+{
+    long nWidth = pReadAccess->Width();
+    long nHeight = pReadAccess->Height();
+
+    sal_uInt8* pStack = rShared.maStackBuffer.data();
+    sal_uInt8* pStackPtr;
+
+    long nLastIndexY = nHeight - 1;
+
+    long nMultiplyValue = rShared.getMultiplyValue();
+    long nShiftValue = rShared.getShiftValue();
+
+    long nRadius = rShared.mnRadius;
+    long nComponentWidth = rShared.mnComponentWidth;
+    long nDiv = rShared.mnDiv;
+
+    Scanline pSourcePointer;
+    Scanline pDestinationPointer;
+
+    long nYPosition;
+    long nStackIndex;
+    long nStackIndexStart;
+    long nWeight;
+
+    long* nSum = rShared.mnSumVector.data();
+    long* nInSum = rShared.mnInSumVector.data();
+    long* nOutSum = rShared.mnOutSumVector.data();
+
+    rShared.calculateWeightAndPositions(nLastIndexY);
+    long* pPositionPointer = rShared.maPositionTable.data();
+    long* pWeightPointer = rShared.maWeightTable.data();
+
+    for (long x = 0; x < nWidth; x++)
+    {
+        SumFunction::set(nSum, 0L);
+        SumFunction::set(nInSum, 0L);
+        SumFunction::set(nOutSum, 0L);
+
+        for (long i = 0; i < nDiv; i++)
+        {
+            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+
+            pStackPtr = &pStack[nComponentWidth * i];
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            nWeight = pWeightPointer[i];
+
+            SumFunction::add(nSum, pSourcePointer[0] * nWeight);
+
+            if (i - nRadius > 0)
+            {
+                SumFunction::add(nInSum, pSourcePointer);
+            }
+            else
+            {
+                SumFunction::add(nOutSum, pSourcePointer);
+            }
+        }
+
+        nStackIndex = nRadius;
+        nYPosition = std::min(nRadius, nLastIndexY);
+
+        pSourcePointer = pReadAccess->GetScanline(nYPosition) + nComponentWidth * x;
+
+        for (long y = 0; y < nHeight; y++)
+        {
+            pDestinationPointer = pWriteAccess->GetScanline(y) + nComponentWidth * x;
+
+            SumFunction::assignMulAndShr(pDestinationPointer, nSum, nMultiplyValue, nShiftValue);
+
+            SumFunction::sub(nSum, nOutSum);
+
+
+            nStackIndexStart = nStackIndex + nDiv - nRadius;
+            if (nStackIndexStart >= nDiv)
+            {
+                nStackIndexStart -= nDiv;
+            }
+            pStackPtr = &pStack[nComponentWidth * nStackIndexStart];
+
+            SumFunction::sub(nOutSum, pStackPtr);
+
+            if (nYPosition < nLastIndexY)
+            {
+                nYPosition++;
+                pSourcePointer = pReadAccess->GetScanline(nYPosition) + nComponentWidth * x;
+            }
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            SumFunction::add(nInSum, pSourcePointer);
+
+            SumFunction::add(nSum, nInSum);
+
+            nStackIndex++;
+            if (nStackIndex >= nDiv)
+            {
+                nStackIndex = 0;
+            }
+
+            pStackPtr = &pStack[nStackIndex * nComponentWidth];
+
+            SumFunction::add(nOutSum, pStackPtr);
+
+            SumFunction::sub(nInSum, pStackPtr);
+        }
+    }
+}
+
+void stackBlur24(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth)
+{
+    // Limit radius
+    nRadius = std::min(254, std::max(2, nRadius));
+    const long nColorChannels = 3; // 3 color channel
+    BlurSharedData aData(nRadius, nComponentWidth, nColorChannels);
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        Bitmap::ScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurHorizontal<SumFunction24>(pReadAccess.get(), pWriteAccess.get(), aData);
+    }
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        Bitmap::ScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurVertical<SumFunction24>(pReadAccess.get(), pWriteAccess.get(), aData);
+    }
+}
+
+void stackBlur8(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth)
+{
+    // Limit radius
+    nRadius = std::min(254, std::max(2, nRadius));
+    const long nColorChannels = 1; // 1 color channel
+    BlurSharedData aData(nRadius, nComponentWidth, nColorChannels);
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        Bitmap::ScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurHorizontal<SumFunction8>(pReadAccess.get(), pWriteAccess.get(), aData);
+    }
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        Bitmap::ScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurVertical<SumFunction8>(pReadAccess.get(), pWriteAccess.get(), aData);
+    }
+}
+
+void centerExtendBitmap(Bitmap& rBitmap, sal_Int32 nExtendSize, Color aColor)
+{
+    const Size& rSize = rBitmap.GetSizePixel();
+    const Size aNewSize(rSize.Width()  + nExtendSize * 2,
+                        rSize.Height() + nExtendSize * 2);
+
+    Bitmap aNewBitmap(aNewSize, rBitmap.GetBitCount());
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        Bitmap::ScopedWriteAccess pWriteAccess(aNewBitmap);
+
+        long nWidthBorder  = nExtendSize + rSize.Width();
+        long nHeightBorder = nExtendSize + rSize.Height();
+
+        for (int y = 0; y < aNewSize.Height(); y++)
+        {
+            for (int x = 0; x < aNewSize.Width(); x++)
+            {
+                if (y < nExtendSize || y >= nHeightBorder
+                 || x < nExtendSize || x >= nWidthBorder)
+                {
+                    pWriteAccess->SetPixel(y, x, aColor);
+                }
+                else
+                {
+                    pWriteAccess->SetPixel(y, x, pReadAccess->GetPixel(y - nExtendSize, x - nExtendSize));
+                }
+            }
+        }
+    }
+    rBitmap = aNewBitmap;
+}
+
+} // end anonymous namespace
+
+/**
+ * Implementation of stack blur - a fast Gaussian blur approximation.
+ * nRadius - blur radious, valid values are between 2 and 254
+ * bExtend - extend the bitmap in all directions by the radius
+ *
+ * Stack Blur Algorithm by Mario Klingemann <mario at quasimondo.com>
+ * (http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html)
+ *
+ * Additionally eferences and implementations:
+ * - Blur.js by Jacob Kelley
+ *   (http://www.blurjs.com)
+ * - BlurEffectForAndroidDesign by Nicolas Pomepuy
+ *   (https://github.com/PomepuyN/BlurEffectForAndroidDesign)
+ * - StackBluriOS by Thomas Landspurg
+ *   (https://github.com/tomsoft1/StackBluriOS)
+ * - stackblur.cpp by Benjamin Yates
+ *   (https://gist.github.com/benjamin9999/3809142)
+ * - stack blur in fog 2D graphic library by Petr Kobalicek
+ *   (https://code.google.com/p/fog/)
+ *
+ */
+BitmapFilterStackBlur::BitmapFilterStackBlur(sal_Int32 nRadius, bool bExtend)
+    : mnRadius(nRadius)
+    , mbExtend(bExtend)
+{}
+
+BitmapFilterStackBlur::~BitmapFilterStackBlur()
+{}
+
+bool BitmapFilterStackBlur::filter(Bitmap& rBitmap)
+{
+    sal_uLong nScanlineFormat;
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        nScanlineFormat = pReadAccess->GetScanlineFormat();
+    }
+
+    if (nScanlineFormat == BMP_FORMAT_24BIT_TC_RGB ||
+        nScanlineFormat == BMP_FORMAT_24BIT_TC_BGR ||
+        nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK)
+    {
+        int nComponentWidth = (nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK) ? 4 : 3;
+
+        if (mbExtend)
+        {
+            centerExtendBitmap(rBitmap, mnRadius, COL_WHITE);
+        }
+
+        stackBlur24(rBitmap, mnRadius, nComponentWidth);
+    }
+    else if (nScanlineFormat == BMP_FORMAT_8BIT_PAL)
+    {
+        int nComponentWidth = 1;
+
+        if (mbExtend)
+        {
+            centerExtendBitmap(rBitmap, mnRadius, COL_WHITE);
+        }
+
+        stackBlur8(rBitmap, mnRadius, nComponentWidth);
+    }
+
+    return true;
+}
+
+bool BitmapFilterStackBlur::filter(BitmapEx& rBitmapEx)
+{
+    Bitmap aBitmap = rBitmapEx.GetBitmap();
+    filter(aBitmap);
+    rBitmapEx = BitmapEx(aBitmap);
+
+    return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 913b3a648117206d21821b0cea40ff15a0e8e5cf
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Mar 25 15:42:41 2015 +0900

    Experimental: draw handles instead of getting them from bitmap
    
    Currently object handles are defined in the bitmap which is a pain
    when using in HiDPI as they have to be scaled and don't look
    pretty. They are also hard to change and non theme-able (change
    of color needs a change the bitmap). This commit experimentaly
    enables the drawn handles (enable with environment variable
    SVX_DRAW_HANDLES) which currently exchanges the default some
    basic handles.
    
    Change-Id: If80aa7fe756a6d8d6991e9515f2951ee21b31b72

diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 04b05f5..1586bd5 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -227,6 +227,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
     svx/source/sdr/overlay/overlayobject \
     svx/source/sdr/overlay/overlaymanager \
     svx/source/sdr/overlay/overlayobjectlist \
+    svx/source/sdr/overlay/overlayhandle \
     svx/source/sdr/primitive2d/sdrellipseprimitive2d \
     svx/source/sdr/primitive2d/sdrprimitivetools \
     svx/source/sdr/primitive2d/sdrtextprimitive2d \
diff --git a/svx/inc/sdr/overlay/overlayhandle.hxx b/svx/inc/sdr/overlay/overlayhandle.hxx
new file mode 100644
index 0000000..60d7e54
--- /dev/null
+++ b/svx/inc/sdr/overlay/overlayhandle.hxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_SVX_SDR_OVERLAY_OVERLAYHANDLE_HXX
+#define INCLUDED_SVX_SDR_OVERLAY_OVERLAYHANDLE_HXX
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+
+namespace sdr { namespace overlay {
+
+
+class SVX_DLLPUBLIC OverlayHandle : public OverlayObjectWithBasePosition
+{
+protected:
+    basegfx::B2DSize maSize;
+    Color maStrokeColor;
+
+    // geometry creation for OverlayObject
+    virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;
+
+public:
+    OverlayHandle(const basegfx::B2DPoint& rBasePos,
+                  const basegfx::B2DSize& rSize,
+                  Color& rStrokeColor,
+                  Color& rFillColor);
+
+    virtual ~OverlayHandle();
+};
+
+}} // end of namespace sdr::overlay
+
+#endif // INCLUDED_SVX_SDR_OVERLAY_OVERLAYHANDLE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/inc/sdr/overlay/overlaytools.hxx b/svx/inc/sdr/overlay/overlaytools.hxx
index 095c411..9a6f9fe 100644
--- a/svx/inc/sdr/overlay/overlaytools.hxx
+++ b/svx/inc/sdr/overlay/overlaytools.hxx
@@ -22,7 +22,43 @@
 
 #include <drawinglayer/primitive2d/primitivetools2d.hxx>
 #include <vcl/bitmapex.hxx>
+#include <basegfx/vector/b2dsize.hxx>
 
+namespace drawinglayer { namespace primitive2d {
+
+class OverlayStaticRectanglePrimitive : public DiscreteMetricDependentPrimitive2D
+{
+private:
+    basegfx::B2DPoint maPosition;
+    basegfx::B2DSize maSize;
+
+    // the graphic definition
+    basegfx::BColor maStrokeColor;
+    basegfx::BColor maFillColor;
+    double mfTransparence;
+
+    // the rotation of the primitive itself
+    double mfRotation;
+
+protected:
+    virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
+
+public:
+    OverlayStaticRectanglePrimitive(
+        const basegfx::B2DPoint& rPosition,
+        const basegfx::B2DSize& rSize,
+        const basegfx::BColor& rStrokeColor,
+        const basegfx::BColor& rFillColor,
+        double fTransparence,
+        double fRotation);
+
+    // compare operator
+    virtual bool operator==( const BasePrimitive2D& rPrimitive ) const SAL_OVERRIDE;
+
+    DeclPrimitive2DIDBlock()
+};
+
+}} // end of namespace drawinglayer::primitive2d
 
 // Overlay helper class which holds a BotmapEx which is to be visualized
 // at the given logic position with the Bitmap's pixel size, unscaled and
diff --git a/svx/source/sdr/overlay/overlayhandle.cxx b/svx/source/sdr/overlay/overlayhandle.cxx
new file mode 100644
index 0000000..8cd47ff
--- /dev/null
+++ b/svx/source/sdr/overlay/overlayhandle.cxx
@@ -0,0 +1,63 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sdr/overlay/overlayhandle.hxx>
+#include <sdr/overlay/overlaytools.hxx>
+#include <tools/poly.hxx>
+#include <vcl/outdev.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+
+namespace sdr { namespace overlay {
+
+using namespace drawinglayer::primitive2d;
+using namespace basegfx;
+
+Primitive2DSequence OverlayHandle::createOverlayObjectPrimitive2DSequence()
+{
+    basegfx::BColor aStrokeColor = maStrokeColor.getBColor();
+    basegfx::BColor aFillColor = getBaseColor().getBColor();
+
+    const Primitive2DReference aReference(
+        new OverlayStaticRectanglePrimitive(maBasePosition, maSize, aStrokeColor, aFillColor, 0.3f, 0.0f));
+
+    return Primitive2DSequence(&aReference, 1);
+}
+
+OverlayHandle::OverlayHandle(const B2DPoint& rBasePos,
+                             const B2DSize& rSize,
+                             Color& rStrokeColor,
+                             Color& rFillColor)
+    : OverlayObjectWithBasePosition(rBasePos, rFillColor)
+    , maSize(rSize)
+    , maStrokeColor(rStrokeColor)
+{
+}
+
+OverlayHandle::~OverlayHandle()
+{
+}
+
+}} // end of namespace sdr::overlay
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/overlay/overlaytools.cxx b/svx/source/sdr/overlay/overlaytools.cxx
index ea0cab6..b333ce2 100644
--- a/svx/source/sdr/overlay/overlaytools.cxx
+++ b/svx/source/sdr/overlay/overlaytools.cxx
@@ -33,6 +33,95 @@
 #include <vcl/settings.hxx>
 
 
+namespace drawinglayer
+{
+namespace primitive2d
+{
+
+OverlayStaticRectanglePrimitive::OverlayStaticRectanglePrimitive(
+                                    const basegfx::B2DPoint& rPosition,
+                                    const basegfx::B2DSize& rSize,
+                                    const basegfx::BColor& rStrokeColor,
+                                    const basegfx::BColor& rFillColor,
+                                    double fTransparence,
+                                    double fRotation)
+    : DiscreteMetricDependentPrimitive2D()
+    , maPosition(rPosition)
+    , maSize(rSize)
+    , maStrokeColor(rStrokeColor)
+    , maFillColor(rFillColor)
+    , mfTransparence(fTransparence)
+    , mfRotation(fRotation)
+{}
+
+Primitive2DSequence OverlayStaticRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+    Primitive2DSequence aPrimitive2DSequence;
+    const double fHalfWidth = maSize.getX() * getDiscreteUnit() / 2.0;
+    const double fHalfHeight = maSize.getY() * getDiscreteUnit() / 2.0;
+
+    basegfx::B2DRange aRange(
+        maPosition.getX() - fHalfWidth, maPosition.getY() - fHalfHeight,
+        maPosition.getX() + fHalfWidth, maPosition.getY() + fHalfHeight);
+
+    if (basegfx::fTools::more(getDiscreteUnit(), 0.0) && mfTransparence <= 1.0)
+    {
+        basegfx::B2DPolygon aPolygon(
+            basegfx::tools::createPolygonFromRect(aRange));
+
+        // create filled primitive
+        basegfx::B2DPolyPolygon aPolyPolygon;
+        aPolyPolygon.append(aPolygon);
+
+        const attribute::LineAttribute aLineAttribute(maStrokeColor, 1.0);
+
+        // create data
+        const Primitive2DReference aStroke(
+            new PolyPolygonStrokePrimitive2D(aPolyPolygon, aLineAttribute));
+
+        // create fill primitive
+        const Primitive2DReference aFill(
+            new PolyPolygonColorPrimitive2D(aPolyPolygon, maFillColor));
+
+        aPrimitive2DSequence = Primitive2DSequence(2);
+        aPrimitive2DSequence[0] = aFill;
+        aPrimitive2DSequence[1] = aStroke;
+
+        // embed filled to transparency (if used)
+        if (mfTransparence > 0.0)
+        {
+            const Primitive2DReference aFillTransparent(
+                new UnifiedTransparencePrimitive2D(
+                    aPrimitive2DSequence,
+                    mfTransparence));
+
+            aPrimitive2DSequence = Primitive2DSequence(&aFillTransparent, 1);
+        }
+    }
+
+    return aPrimitive2DSequence;
+}
+
+bool OverlayStaticRectanglePrimitive::operator==(const BasePrimitive2D& rPrimitive) const
+{
+    if (DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+    {
+        const OverlayStaticRectanglePrimitive& rCompare = static_cast<const OverlayStaticRectanglePrimitive&>(rPrimitive);
+
+        return (maPosition == rCompare.maPosition
+            && maSize == rCompare.maSize
+            && maStrokeColor == rCompare.maStrokeColor
+            && maFillColor == rCompare.maFillColor
+            && mfTransparence == rCompare.mfTransparence
+            && mfRotation == rCompare.mfRotation);
+    }
+
+    return false;
+}
+
+ImplPrimitive2DIDBlock(OverlayStaticRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYRECTANGLEPRIMITIVE)
+
+}} // end of namespace drawinglayer::primitive2d
 
 namespace drawinglayer
 {
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
index 4e25127..6f7a078 100644
--- a/svx/source/svdraw/svdhdl.cxx
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -50,6 +50,7 @@
 #include <svx/sdr/overlay/overlaybitmapex.hxx>
 #include <sdr/overlay/overlayline.hxx>
 #include <svx/sdr/overlay/overlaytriangle.hxx>
+#include <sdr/overlay/overlayhandle.hxx>
 #include <sdr/overlay/overlayrectangle.hxx>
 #include <svx/sdrpagewindow.hxx>
 #include <svx/sdrpaintwindow.hxx>
@@ -577,13 +578,54 @@ void SdrHdl::CreateB2dIAObject()
                     if (xManager.is())
                     {
                         basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
-                        sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
-                            aPosition,
-                            eColIndex,
-                            eKindOfMarker,
-                            rOutDev,
-                            aMoveOutsideOffset);
+                        sdr::overlay::OverlayObject* pNewOverlayObject = NULL;
+                        if (getenv ("SVX_DRAW_HANDLES") && (eKindOfMarker == Rect_7x7 || eKindOfMarker == Rect_9x9 || eKindOfMarker == Rect_11x11))
+                        {
+                            double fSize = 7.0;
+                            switch (eKindOfMarker)
+                            {
+                                case Rect_9x9:
+                                    fSize = 9.0;
+                                    break;
+                                case Rect_11x11:
+                                    fSize = 11.0;
+                                    break;
+                                default:
+                                    break;
+                            }
+                            sal_Int32 nScaleFactor = rOutDev.GetDPIScaleFactor();
+                            basegfx::B2DSize aB2DSize(fSize * nScaleFactor, fSize * nScaleFactor);
 
+                            Color aHandleStrokeColor(COL_BLACK);
+                            Color aHandleFillColor(COL_LIGHTGREEN);
+                            switch (eColIndex)
+                            {
+                                case Cyan:
+                                    aHandleFillColor = Color(COL_CYAN);
+                                    break;
+                                case LightCyan:
+                                    aHandleFillColor = Color(COL_LIGHTCYAN);
+                                    break;
+                                case Red:
+                                    aHandleFillColor = Color(COL_RED);
+                                    break;
+                                case LightRed:
+                                    aHandleFillColor = Color(COL_LIGHTRED);
+                                    break;
+                                case Yellow:
+                                    aHandleFillColor = Color(COL_YELLOW);
+                                    break;
+                                default:
+                                    break;
+                            }
+                            pNewOverlayObject = new sdr::overlay::OverlayHandle(aPosition, aB2DSize, aHandleStrokeColor, aHandleFillColor);
+                        }
+                        else
+                        {
+                            pNewOverlayObject = CreateOverlayObject(
+                                                    aPosition, eColIndex, eKindOfMarker,
+                                                    rOutDev, aMoveOutsideOffset);
+                        }
                         // OVERLAYMANAGER
                         if (pNewOverlayObject)
                         {
commit 33094a542fbcdcdaf14d5d7304e79f2e5b8cd4de
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Mar 25 14:42:42 2015 +0900

    vcl: use unique_ptr for fillcolor, linecolor in bmpacc
    
    Change-Id: I09d00c4492d2866aeb79d1a4818a55f9cdfdc4f0

diff --git a/include/vcl/bmpacc.hxx b/include/vcl/bmpacc.hxx
index f0ab33b..ebc00c7 100644
--- a/include/vcl/bmpacc.hxx
+++ b/include/vcl/bmpacc.hxx
@@ -221,8 +221,8 @@ public:
 
 private:
 
-    BitmapColor* mpLineColor;
-    BitmapColor* mpFillColor;
+    std::unique_ptr<BitmapColor> mpLineColor;
+    std::unique_ptr<BitmapColor> mpFillColor;
 
     BitmapWriteAccess()
     {}
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
index cdda5dc..2e7982f 100644
--- a/vcl/source/gdi/bmpacc.cxx
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -491,17 +491,15 @@ BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const
     return rFallback;
 }
 
-BitmapWriteAccess::BitmapWriteAccess( Bitmap& rBitmap ) :
-            BitmapReadAccess( rBitmap, BITMAP_WRITE_ACCESS ),
-            mpLineColor     ( NULL ),
-            mpFillColor     ( NULL )
+BitmapWriteAccess::BitmapWriteAccess(Bitmap& rBitmap)
+    : BitmapReadAccess(rBitmap, BITMAP_WRITE_ACCESS)
+    , mpLineColor()
+    , mpFillColor()
 {
 }
 
 BitmapWriteAccess::~BitmapWriteAccess()
 {
-    delete mpLineColor;
-    delete mpFillColor;
 }
 
 void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
diff --git a/vcl/source/gdi/bmpacc3.cxx b/vcl/source/gdi/bmpacc3.cxx
index 70f23c6..c94fb00 100644
--- a/vcl/source/gdi/bmpacc3.cxx
+++ b/vcl/source/gdi/bmpacc3.cxx
@@ -28,28 +28,45 @@
 
 void BitmapWriteAccess::SetLineColor( const Color& rColor )
 {
-    delete mpLineColor;
-
-    if( rColor.GetTransparency() == 255 )
-        mpLineColor = NULL;
+    if (rColor.GetTransparency() == 255)
+    {
+        mpLineColor.reset();
+    }
     else
-        mpLineColor = ( HasPalette() ? new BitmapColor(  (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
+    {
+        if (HasPalette())
+        {
+            mpLineColor.reset(new BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor))));
+        }
+        else
+        {
+            mpLineColor.reset(new BitmapColor(rColor));
+        }
+    }
 }
 
 void BitmapWriteAccess::SetFillColor()
 {
-    delete mpFillColor;
-    mpFillColor = NULL;
+    mpFillColor.reset();
 }
 
 void BitmapWriteAccess::SetFillColor( const Color& rColor )
 {
-    delete mpFillColor;
-
-    if( rColor.GetTransparency() == 255 )
-        mpFillColor = NULL;
+    if (rColor.GetTransparency() == 255)
+    {
+        mpFillColor.reset();
+    }
     else
-        mpFillColor = ( HasPalette() ? new BitmapColor(  (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
+    {
+        if (HasPalette())
+        {
+            mpFillColor.reset(new BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor))));
+        }
+        else
+        {
+            mpFillColor.reset(new BitmapColor(rColor));
+        }
+    }
 }
 
 void BitmapWriteAccess::Erase( const Color& rColor )
@@ -57,31 +74,33 @@ void BitmapWriteAccess::Erase( const Color& rColor )
     // convert the color format from RGB to palette index if needed
     // TODO: provide and use Erase( BitmapColor& method)
     BitmapColor aColor = rColor;
-    if( HasPalette() )
-        aColor = BitmapColor( (sal_uInt8)GetBestPaletteIndex( rColor) );
+    if (HasPalette())
+    {
+        aColor = BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor)));
+    }
     // try fast bitmap method first
-    if( ImplFastEraseBitmap( *mpBuffer, aColor ) )
+    if (ImplFastEraseBitmap(*mpBuffer, aColor))
         return;
 
     // use the canonical method to clear the bitmap
-    BitmapColor*    pOldFillColor = mpFillColor ? new BitmapColor( *mpFillColor ) : NULL;
-    const Point     aPoint;
-    const Rectangle aRect( aPoint, maBitmap.GetSizePixel() );
-
-    SetFillColor( rColor );
-    FillRect( aRect );
-    delete mpFillColor;
-    mpFillColor = pOldFillColor;
+    BitmapColor* pOldFillColor = mpFillColor ? new BitmapColor(*mpFillColor) : NULL;
+    const Point aPoint;
+    const Rectangle aRect(aPoint, maBitmap.GetSizePixel());
+
+    SetFillColor(rColor);
+    FillRect(aRect);
+
+    mpFillColor.reset(pOldFillColor);
 }
 
 void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
 {
-    if( mpLineColor )
+    if (mpLineColor)
     {
-        const BitmapColor&  rLineColor = *mpLineColor;
-        long                nX, nY;
+        const BitmapColor& rLineColor = *mpLineColor.get();
+        long nX, nY;
 
-        if ( rStart.X() == rEnd.X() )
+        if (rStart.X() == rEnd.X())
         {
             // Vertical Line
             const long nEndY = rEnd.Y();
@@ -89,7 +108,7 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
             nX = rStart.X();
             nY = rStart.Y();
 
-            if ( nEndY > nY )
+            if (nEndY > nY)
             {
                 for (; nY <= nEndY; nY++ )
                     SetPixel( nY, nX, rLineColor );
@@ -100,7 +119,7 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
                     SetPixel( nY, nX, rLineColor );
             }
         }
-        else if ( rStart.Y() == rEnd.Y() )
+        else if (rStart.Y() == rEnd.Y())
         {
             // Horizontal Line
             const long nEndX = rEnd.X();
@@ -108,29 +127,29 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
             nX = rStart.X();
             nY = rStart.Y();
 
-            if ( nEndX > nX )
+            if (nEndX > nX)
             {
-                for (; nX <= nEndX; nX++ )
-                    SetPixel( nY, nX, rLineColor );
+                for (; nX <= nEndX; nX++)
+                    SetPixel(nY, nX, rLineColor);
             }
             else
             {
-                for (; nX >= nEndX; nX-- )
-                    SetPixel( nY, nX, rLineColor );
+                for (; nX >= nEndX; nX--)
+                    SetPixel(nY, nX, rLineColor);
             }
         }
         else
         {
             const long  nDX = labs( rEnd.X() - rStart.X() );
             const long  nDY = labs( rEnd.Y() - rStart.Y() );
-            long        nX1;
-            long        nY1;
-            long        nX2;
-            long        nY2;
+            long nX1;
+            long nY1;
+            long nX2;
+            long nY2;
 
-            if ( nDX >= nDY )
+            if (nDX >= nDY)
             {
-                if ( rStart.X() < rEnd.X() )
+                if (rStart.X() < rEnd.X())
                 {
                     nX1 = rStart.X();
                     nY1 = rStart.Y();
@@ -145,22 +164,22 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
                     nY2 = rStart.Y();
                 }
 
-                const long  nDYX = ( nDY - nDX ) << 1;
-                const long  nDY2 = nDY << 1;
-                long        nD = nDY2 - nDX;
-                bool        bPos = nY1 < nY2;
+                const long nDYX = (nDY - nDX) << 1;
+                const long nDY2 = nDY << 1;
+                long nD = nDY2 - nDX;
+                bool bPos = nY1 < nY2;
 
-                for ( nX = nX1, nY = nY1; nX <= nX2; nX++ )
+                for (nX = nX1, nY = nY1; nX <= nX2; nX++)
                 {
-                    SetPixel( nY, nX, rLineColor );
+                    SetPixel(nY, nX, rLineColor);
 
-                    if ( nD < 0 )
+                    if (nD < 0)
                         nD += nDY2;
                     else
                     {
                         nD += nDYX;
 
-                        if ( bPos )
+                        if (bPos)
                             nY++;
                         else
                             nY--;
@@ -169,7 +188,7 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
             }
             else
             {
-                if ( rStart.Y() < rEnd.Y() )
+                if (rStart.Y() < rEnd.Y())
                 {
                     nX1 = rStart.X();
                     nY1 = rStart.Y();
@@ -184,22 +203,22 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
                     nY2 = rStart.Y();
                 }
 
-                const long  nDYX = ( nDX - nDY ) << 1;
+                const long  nDYX = (nDX - nDY) << 1;
                 const long  nDY2 = nDX << 1;
-                long        nD = nDY2 - nDY;
-                bool        bPos = nX1 < nX2;
+                long nD = nDY2 - nDY;
+                bool bPos = nX1 < nX2;
 
-                for ( nX = nX1, nY = nY1; nY <= nY2; nY++ )
+                for (nX = nX1, nY = nY1; nY <= nY2; nY++)
                 {
-                    SetPixel( nY, nX, rLineColor );
+                    SetPixel(nY, nX, rLineColor);
 
-                    if ( nD < 0 )
+                    if (nD < 0)
                         nD += nDY2;
                     else
                     {
                         nD += nDYX;
 
-                        if ( bPos )
+                        if (bPos)
                             nX++;
                         else
                             nX--;
@@ -212,39 +231,43 @@ void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
 
 void BitmapWriteAccess::FillRect( const Rectangle& rRect )
 {
-    if( mpFillColor )
+    if (mpFillColor)
     {
-        const BitmapColor&  rFillColor = *mpFillColor;
-        Point               aPoint;
-        Rectangle           aRect( aPoint, maBitmap.GetSizePixel() );
+        const BitmapColor& rFillColor = *mpFillColor.get();
+        Point aPoint;
+        Rectangle aRect(aPoint, maBitmap.GetSizePixel());
 
-        aRect.Intersection( rRect );
+        aRect.Intersection(rRect);
 
-        if( !aRect.IsEmpty() )
+        if (!aRect.IsEmpty())
         {
-            const long  nStartX = rRect.Left();
-            const long  nStartY = rRect.Top();
-            const long  nEndX = rRect.Right();
-            const long  nEndY = rRect.Bottom();
-
-            for( long nY = nStartY; nY <= nEndY; nY++ )
-                for( long nX = nStartX; nX <= nEndX; nX++ )
-                    SetPixel( nY, nX, rFillColor );
+            const long nStartX = rRect.Left();
+            const long nStartY = rRect.Top();
+            const long nEndX = rRect.Right();
+            const long nEndY = rRect.Bottom();
+
+            for (long nY = nStartY; nY <= nEndY; nY++)
+            {
+                for (long nX = nStartX; nX <= nEndX; nX++)
+                {
+                    SetPixel(nY, nX, rFillColor);
+                }
+            }
         }
     }
 }
 
 void BitmapWriteAccess::DrawRect( const Rectangle& rRect )
 {
-    if( mpFillColor )
-        FillRect( rRect );
+    if (mpFillColor)
+        FillRect(rRect);
 
-    if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
+    if (mpLineColor && (!mpFillColor || ( *mpFillColor.get() != *mpLineColor.get())))
     {
-        DrawLine( rRect.TopLeft(), rRect.TopRight() );
-        DrawLine( rRect.TopRight(), rRect.BottomRight() );
-        DrawLine( rRect.BottomRight(), rRect.BottomLeft() );
-        DrawLine( rRect.BottomLeft(), rRect.TopLeft() );
+        DrawLine(rRect.TopLeft(), rRect.TopRight());
+        DrawLine(rRect.TopRight(), rRect.BottomRight());
+        DrawLine(rRect.BottomRight(), rRect.BottomLeft());
+        DrawLine(rRect.BottomLeft(), rRect.TopLeft());
     }
 }
 
commit 132ad4f1416126a74f8b48f65da786a4e0ec8c1b
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Mar 25 12:06:21 2015 +0900

    vcl: get rid of macros for lazy people in bmpacc
    
    Change-Id: I4b64a70e185f061c7d7e1e895d85ffb47ee60101

diff --git a/include/vcl/bmpacc.hxx b/include/vcl/bmpacc.hxx
index f2f1399..f0ab33b 100644
--- a/include/vcl/bmpacc.hxx
+++ b/include/vcl/bmpacc.hxx
@@ -25,42 +25,9 @@
 #include <vcl/salbtype.hxx>
 #include <vcl/bitmap.hxx>
 
-
-// - Access defines -
-#define DECL_FORMAT_GETPIXEL( Format ) \
-static BitmapColor GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& rMask );
-
-#define DECL_FORMAT_SETPIXEL( Format ) \
-static void SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask );
-
-#define DECL_FORMAT( Format )   \
-DECL_FORMAT_GETPIXEL( Format )  \
-DECL_FORMAT_SETPIXEL( Format )
-
-#define IMPL_FORMAT_GETPIXEL( Format ) \
-BitmapColor BitmapReadAccess::GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& rMask )
-
-#define IMPL_FORMAT_GETPIXEL_NOMASK( Format ) \
-BitmapColor BitmapReadAccess::GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& )
-
-#define IMPL_FORMAT_SETPIXEL( Format ) \
-void BitmapReadAccess::SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask )
-
-#define IMPL_FORMAT_SETPIXEL_NOMASK( Format ) \
-void BitmapReadAccess::SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& )
-
-#define CASE_FORMAT( Format )           \
-case( BMP_FORMAT##Format ):            \
-{                                       \
-    mFncGetPixel = GetPixelFor##Format;\
-    mFncSetPixel = SetPixelFor##Format;\
-}                                       \
-break;
-
 // - Access functions -
-typedef BitmapColor (*FncGetPixel)( ConstScanline pScanline, long nX, const ColorMask& rMask );
-typedef void (*FncSetPixel)( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask );
-
+typedef BitmapColor (*FncGetPixel)(ConstScanline pScanline, long nX, const ColorMask& rMask);
+typedef void (*FncSetPixel)(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
 
 // - BitmapInfoAccess -
 class VCL_DLLPUBLIC BitmapInfoAccess
@@ -68,53 +35,58 @@ class VCL_DLLPUBLIC BitmapInfoAccess
     friend class BitmapReadAccess;
 
 public:
-                                BitmapInfoAccess( Bitmap& rBitmap );
-    virtual                     ~BitmapInfoAccess();
+    BitmapInfoAccess(Bitmap& rBitmap);
+    virtual ~BitmapInfoAccess();
 
-    inline bool                 operator!() const;
+    inline bool operator!() const;
 
-    inline long                 Width() const;
-    inline long                 Height() const;
-    inline Point                TopLeft() const;
-    inline Point                BottomRight() const;
+    inline long Width() const;
+    inline long Height() const;
+    inline Point TopLeft() const;
+    inline Point BottomRight() const;
 
-    inline bool                 IsTopDown() const;
-    inline bool                 IsBottomUp() const;
+    inline bool  IsTopDown() const;
+    inline bool  IsBottomUp() const;
 
-    inline sal_uLong            GetScanlineFormat() const;
-    inline sal_uLong            GetScanlineSize() const;
+    inline sal_uLong GetScanlineFormat() const;
+    inline sal_uLong GetScanlineSize() const;
 
-    inline sal_uInt16           GetBitCount() const;
-    inline BitmapColor          GetBestMatchingColor( const BitmapColor& rBitmapColor );
+    inline sal_uInt16 GetBitCount() const;
+    inline BitmapColor GetBestMatchingColor(const BitmapColor& rBitmapColor);
 
-    inline bool                 HasPalette() const;
+    inline bool HasPalette() const;
     inline const BitmapPalette& GetPalette() const;
-    inline sal_uInt16           GetPaletteEntryCount() const;
-    inline const BitmapColor&   GetPaletteColor( sal_uInt16 nColor ) const;
-    inline const BitmapColor&   GetBestPaletteColor( const BitmapColor& rBitmapColor ) const;
-    sal_uInt16                  GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const;
+    inline sal_uInt16 GetPaletteEntryCount() const;
+    inline const BitmapColor& GetPaletteColor(sal_uInt16 nColor) const;
+    inline const BitmapColor& GetBestPaletteColor(const BitmapColor& rBitmapColor) const;
+    sal_uInt16 GetBestPaletteIndex(const BitmapColor& rBitmapColor) const;
 
     inline bool                 HasColorMask() const;
     inline ColorMask&           GetColorMask() const;
 
 private:
+    BitmapInfoAccess()
+    {}
 
-                                BitmapInfoAccess() {}
-                                BitmapInfoAccess( const BitmapInfoAccess& ) {}
-    BitmapInfoAccess&           operator=( const BitmapInfoAccess& ) { return *this; }
+    BitmapInfoAccess(const BitmapInfoAccess&)
+    {}
+
+    BitmapInfoAccess& operator=(const BitmapInfoAccess&)
+    {
+        return *this;
+    }
 
 protected:
-    Bitmap                      maBitmap;
-    BitmapBuffer*               mpBuffer;
-    ColorMask                   maColorMask;
-    BitmapAccessMode            mnAccessMode;
+    Bitmap maBitmap;
+    BitmapBuffer* mpBuffer;
+    ColorMask maColorMask;
+    BitmapAccessMode mnAccessMode;
 
-    SAL_DLLPRIVATE  void        ImplCreate( Bitmap& rBitmap );
-    SAL_DLLPRIVATE  void        ImplDestroy();
+    SAL_DLLPRIVATE void ImplCreate(Bitmap& rBitmap);
+    SAL_DLLPRIVATE void ImplDestroy();
 
 protected:
-                                BitmapInfoAccess( Bitmap& rBitmap, BitmapAccessMode nMode );
-
+    BitmapInfoAccess(Bitmap& rBitmap, BitmapAccessMode nMode);
 };
 
 // - BitmapReadAccess -
@@ -123,126 +95,162 @@ class VCL_DLLPUBLIC BitmapReadAccess : public BitmapInfoAccess
     friend class BitmapWriteAccess;
 
 public:
-                                BitmapReadAccess( Bitmap& rBitmap );
-    virtual                     ~BitmapReadAccess();
+    BitmapReadAccess(Bitmap& rBitmap);
+    virtual ~BitmapReadAccess();
+
+    inline Scanline GetBuffer() const;
+    inline Scanline GetScanline( long nY ) const;
 
-    inline Scanline             GetBuffer() const;
-    inline Scanline             GetScanline( long nY ) const;
+    inline BitmapColor GetPixelFromData( const sal_uInt8* pData, long nX ) const;
+    inline void SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor );
 
-    inline BitmapColor          GetPixelFromData( const sal_uInt8* pData, long nX ) const;
-    inline void                 SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor );
-    inline BitmapColor          GetPixel( long nY, long nX ) const;
-    inline BitmapColor          GetColor( long nY, long nX ) const;
-    inline sal_uInt8            GetPixelIndex( long nY, long nX ) const;
-    inline sal_uInt8            GetLuminance( long nY, long nX ) const;
+    inline BitmapColor GetPixel( long nY, long nX ) const;
+    inline BitmapColor GetColor( long nY, long nX ) const;
+    inline sal_uInt8 GetPixelIndex( long nY, long nX ) const;
+    inline sal_uInt8 GetLuminance( long nY, long nX ) const;
 
     /** Get the interpolated color at coordinates fY, fX; if outside, return rFallback */
-    BitmapColor                 GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const;
+    BitmapColor GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const;
 
     /** Get the color at coordinates fY, fX; if outside, return rFallback. Automatically does the correct
         inside/outside checks, e.g. static_cast< sal_uInt32 >(-0.25) *is* 0, not -1 and has to be outside */
-    BitmapColor                 GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const;
+    BitmapColor GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const;
 
 private:
 
-                                BitmapReadAccess() {}
-                                BitmapReadAccess( const BitmapReadAccess& ) : BitmapInfoAccess() {}
-    BitmapReadAccess&           operator=( const BitmapReadAccess& ) { return *this; }
+    BitmapReadAccess()
+    {}
+
+    BitmapReadAccess(const BitmapReadAccess&)
+        : BitmapInfoAccess()
+    {}
+
+    BitmapReadAccess& operator=(const BitmapReadAccess&)
+    {
+        return *this;
+    }
 
 protected:
-    Scanline*                   mpScanBuf;
-    FncGetPixel                 mFncGetPixel;
-    FncSetPixel                 mFncSetPixel;
+    Scanline*   mpScanBuf;
+    FncGetPixel mFncGetPixel;
+    FncSetPixel mFncSetPixel;
 
-    SAL_DLLPRIVATE  void        ImplInitScanBuffer( Bitmap& rBitmap );
-    SAL_DLLPRIVATE  void        ImplClearScanBuffer();
-    SAL_DLLPRIVATE  bool        ImplSetAccessPointers( sal_uLong nFormat );
+    SAL_DLLPRIVATE void ImplInitScanBuffer( Bitmap& rBitmap );
+    SAL_DLLPRIVATE void ImplClearScanBuffer();
+    SAL_DLLPRIVATE bool ImplSetAccessPointers( sal_uLong nFormat );
 
 public:
 
-    SAL_DLLPRIVATE  void        ImplZeroInitUnusedBits();
-    SAL_DLLPRIVATE  BitmapBuffer*
-                                ImplGetBitmapBuffer() const { return mpBuffer; }
-
-                                DECL_FORMAT( _1BIT_MSB_PAL )
-                                DECL_FORMAT( _1BIT_LSB_PAL )
-                                DECL_FORMAT( _4BIT_MSN_PAL )
-                                DECL_FORMAT( _4BIT_LSN_PAL )
-                                DECL_FORMAT( _8BIT_PAL )
-                                DECL_FORMAT( _8BIT_TC_MASK )
-                                DECL_FORMAT( _16BIT_TC_MSB_MASK )
-                                DECL_FORMAT( _16BIT_TC_LSB_MASK )
-                                DECL_FORMAT( _24BIT_TC_BGR )
-                                DECL_FORMAT( _24BIT_TC_RGB )
-                                DECL_FORMAT( _24BIT_TC_MASK )
-                                DECL_FORMAT( _32BIT_TC_ABGR )
-                                DECL_FORMAT( _32BIT_TC_ARGB )
-                                DECL_FORMAT( _32BIT_TC_BGRA )
-                                DECL_FORMAT( _32BIT_TC_RGBA )
-                                DECL_FORMAT( _32BIT_TC_MASK )
+    SAL_DLLPRIVATE void ImplZeroInitUnusedBits();
+    SAL_DLLPRIVATE BitmapBuffer* ImplGetBitmapBuffer() const
+    {
+        return mpBuffer;
+    }
+
+    static BitmapColor GetPixelFor_1BIT_MSB_PAL(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_1BIT_LSB_PAL(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_4BIT_MSN_PAL(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_4BIT_LSN_PAL(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_8BIT_PAL(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_8BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_16BIT_TC_MSB_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_16BIT_TC_LSB_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_24BIT_TC_BGR(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_24BIT_TC_RGB(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_24BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_32BIT_TC_ABGR(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_32BIT_TC_ARGB(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_32BIT_TC_BGRA(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_32BIT_TC_RGBA(ConstScanline pScanline, long nX, const ColorMask& rMask);
+    static BitmapColor GetPixelFor_32BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask);
+
+    static void SetPixelFor_1BIT_MSB_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_1BIT_LSB_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_4BIT_MSN_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_4BIT_LSN_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_8BIT_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_8BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_16BIT_TC_MSB_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_16BIT_TC_LSB_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_24BIT_TC_BGR(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_24BIT_TC_RGB(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_24BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_32BIT_TC_ABGR(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_32BIT_TC_ARGB(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_32BIT_TC_BGRA(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_32BIT_TC_RGBA(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
+    static void SetPixelFor_32BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask);
 
 protected:
-                                BitmapReadAccess( Bitmap& rBitmap, BitmapAccessMode nMode );
-
+    BitmapReadAccess(Bitmap& rBitmap, BitmapAccessMode nMode);
 };
 
 // - BitmapWriteAccess -
 class VCL_DLLPUBLIC BitmapWriteAccess : public BitmapReadAccess
 {
 public:
+    BitmapWriteAccess(Bitmap& rBitmap);
+    virtual ~BitmapWriteAccess();
 
-                                BitmapWriteAccess( Bitmap& rBitmap );
-    virtual                     ~BitmapWriteAccess();
-
-    void                        CopyScanline( long nY, const BitmapReadAccess& rReadAcc );
-    void                        CopyScanline( long nY, ConstScanline aSrcScanline,
-                                              sal_uLong nSrcScanlineFormat, sal_uLong nSrcScanlineSize );
+    void CopyScanline(long nY, const BitmapReadAccess& rReadAcc);
+    void CopyScanline(long nY,
+                      ConstScanline aSrcScanline,
+                      sal_uLong nSrcScanlineFormat,
+                      sal_uLong nSrcScanlineSize);
 
-    void                        CopyBuffer( const BitmapReadAccess& rReadAcc );
+    void CopyBuffer( const BitmapReadAccess& rReadAcc );
 
-    inline void                 SetPalette( const BitmapPalette& rPalette );
-    inline void                 SetPaletteEntryCount( sal_uInt16 nCount );
-    inline void                 SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor );
+    inline void SetPalette(const BitmapPalette& rPalette);
+    inline void SetPaletteEntryCount(sal_uInt16 nCount);
+    inline void SetPaletteColor(sal_uInt16 nColor, const BitmapColor& rBitmapColor);
 
-    inline void                 SetPixel( long nY, long nX, const BitmapColor& rBitmapColor );
-    inline void                 SetPixelIndex( long nY, long nX, sal_uInt8 cIndex );
+    inline void SetPixel(long nY, long nX, const BitmapColor& rBitmapColor);
+    inline void SetPixelIndex(long nY, long nX, sal_uInt8 cIndex);
 
-    void                        SetLineColor( const Color& rColor );
+    void SetLineColor(const Color& rColor);
 
-    void                        SetFillColor();
-    void                        SetFillColor( const Color& rColor );
+    void SetFillColor();
+    void SetFillColor(const Color& rColor);
 
-    void                        Erase( const Color& rColor );
+    void Erase(const Color& rColor);
 
-    void                        DrawLine( const Point& rStart, const Point& rEnd );
+    void DrawLine(const Point& rStart, const Point& rEnd);
 
-    void                        FillRect( const Rectangle& rRect );
-    void                        DrawRect( const Rectangle& rRect );
+    void FillRect(const Rectangle& rRect);
+    void DrawRect(const Rectangle& rRect);
 
 private:
 
-    BitmapColor*                mpLineColor;
-    BitmapColor*                mpFillColor;
+    BitmapColor* mpLineColor;
+    BitmapColor* mpFillColor;
+
+    BitmapWriteAccess()
+    {}
+
+    BitmapWriteAccess(const BitmapWriteAccess&)
+        : BitmapReadAccess()
+    {}
 
-                                BitmapWriteAccess() {}
-                                BitmapWriteAccess( const BitmapWriteAccess& ) : BitmapReadAccess() {}
-    BitmapWriteAccess&          operator=( const BitmapWriteAccess& ) { return *this; }
+    BitmapWriteAccess& operator=(const BitmapWriteAccess&)
+    {
+        return *this;
+    }
 };
 
 // - Inlines -
 inline bool BitmapInfoAccess::operator!() const
 {
-    return( mpBuffer == NULL );
+    return mpBuffer == NULL;
 }
 
 inline long BitmapInfoAccess::Width() const
 {
-    return( mpBuffer ? mpBuffer->mnWidth : 0L );
+    return mpBuffer ? mpBuffer->mnWidth : 0L;
 }
 
 inline long BitmapInfoAccess::Height() const
 {
-    return( mpBuffer ? mpBuffer->mnHeight : 0L );
+    return mpBuffer ? mpBuffer->mnHeight : 0L;
 }
 
 inline Point BitmapInfoAccess::TopLeft() const
@@ -252,13 +260,14 @@ inline Point BitmapInfoAccess::TopLeft() const
 
 inline Point BitmapInfoAccess::BottomRight() const
 {
-    return Point( Width() - 1L, Height() - 1L );
+    return Point(Width() - 1L, Height() - 1L);
 }
 
 inline bool BitmapInfoAccess::IsTopDown() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return mpBuffer && ( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN );
+
+    return mpBuffer && (BMP_SCANLINE_ADJUSTMENT(mpBuffer->mnFormat) == BMP_FORMAT_TOP_DOWN);
 }
 
 inline bool BitmapInfoAccess::IsBottomUp() const
@@ -269,25 +278,28 @@ inline bool BitmapInfoAccess::IsBottomUp() const
 inline sal_uLong BitmapInfoAccess::GetScanlineFormat() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return( mpBuffer ? BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) : 0UL );
+
+    return mpBuffer ? BMP_SCANLINE_FORMAT(mpBuffer->mnFormat) : 0UL;
 }
 
 inline sal_uLong BitmapInfoAccess::GetScanlineSize() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return( mpBuffer ? mpBuffer->mnScanlineSize : 0UL );
+
+    return mpBuffer ? mpBuffer->mnScanlineSize : 0UL;
 }
 
 inline sal_uInt16  BitmapInfoAccess::GetBitCount() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return( mpBuffer ? mpBuffer->mnBitCount : 0 );
+
+    return mpBuffer ? mpBuffer->mnBitCount : 0;
 }
 
-inline BitmapColor BitmapInfoAccess::GetBestMatchingColor( const BitmapColor& rBitmapColor )
+inline BitmapColor BitmapInfoAccess::GetBestMatchingColor(const BitmapColor& rBitmapColor)
 {
-    if( HasPalette() )
-        return BitmapColor( (sal_uInt8) GetBestPaletteIndex( rBitmapColor ) );
+    if (HasPalette())
+        return BitmapColor((sal_uInt8) GetBestPaletteIndex(rBitmapColor));
     else
         return rBitmapColor;
 }
@@ -295,132 +307,147 @@ inline BitmapColor BitmapInfoAccess::GetBestMatchingColor( const BitmapColor& rB
 inline bool BitmapInfoAccess::HasPalette() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return( mpBuffer && !!mpBuffer->maPalette );
+
+    return mpBuffer && !!mpBuffer->maPalette;
 }
 
 inline const BitmapPalette& BitmapInfoAccess::GetPalette() const
 {
     assert(mpBuffer && "Access is not valid!");
+
     return mpBuffer->maPalette;
 }
 
 inline sal_uInt16 BitmapInfoAccess::GetPaletteEntryCount() const
 {
     assert(HasPalette() && "Bitmap has no palette!");
-    return( HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0 );
+
+    return HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0;
 }
 
 inline const BitmapColor& BitmapInfoAccess::GetPaletteColor( sal_uInt16 nColor ) const
 {
     assert(mpBuffer && "Access is not valid!");
     assert(HasPalette() && "Bitmap has no palette!");
-    return mpBuffer->maPalette[ nColor ];
+
+    return mpBuffer->maPalette[nColor];
 }
 
-inline const BitmapColor& BitmapInfoAccess::GetBestPaletteColor( const BitmapColor& rBitmapColor ) const
+inline const BitmapColor& BitmapInfoAccess::GetBestPaletteColor(const BitmapColor& rBitmapColor) const
 {
-    return GetPaletteColor( GetBestPaletteIndex( rBitmapColor ) );
+    return GetPaletteColor(GetBestPaletteIndex(rBitmapColor));
 }
 
 inline bool BitmapInfoAccess::HasColorMask() const
 {
     assert(mpBuffer && "Access is not valid!");
-    const sal_uLong nFormat = BMP_SCANLINE_FORMAT( mpBuffer->mnFormat );
 
-    return( nFormat == BMP_FORMAT_8BIT_TC_MASK  ||
-            nFormat == BMP_FORMAT_16BIT_TC_MSB_MASK ||
-            nFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ||
-            nFormat == BMP_FORMAT_24BIT_TC_MASK ||
-            nFormat == BMP_FORMAT_32BIT_TC_MASK );
+    const sal_uLong nFormat = BMP_SCANLINE_FORMAT(mpBuffer->mnFormat);
+
+    return nFormat == BMP_FORMAT_8BIT_TC_MASK  ||
+           nFormat == BMP_FORMAT_16BIT_TC_MSB_MASK ||
+           nFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ||
+           nFormat == BMP_FORMAT_24BIT_TC_MASK ||
+           nFormat == BMP_FORMAT_32BIT_TC_MASK;
 }
 
 inline ColorMask& BitmapInfoAccess::GetColorMask() const
 {
     assert(mpBuffer && "Access is not valid!");
+
     return mpBuffer->maColorMask;
 }
 
 inline Scanline BitmapReadAccess::GetBuffer() const
 {
     assert(mpBuffer && "Access is not valid!");
-    return( mpBuffer ? mpBuffer->mpBits : NULL );
+
+    return mpBuffer ? mpBuffer->mpBits : NULL;
 }
 
-inline Scanline BitmapReadAccess::GetScanline( long nY ) const
+inline Scanline BitmapReadAccess::GetScanline(long nY) const
 {
     assert(mpBuffer && mpScanBuf && "Access is not valid!");
     assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!");
+
     return mpScanBuf[nY];
 }
 
-inline BitmapColor BitmapReadAccess::GetPixel( long nY, long nX ) const
+inline BitmapColor BitmapReadAccess::GetPixel(long nY, long nX) const
 {
     assert(mpBuffer && mpScanBuf && "Access is not valid!");
     assert(nX < mpBuffer->mnWidth && "x-coordinate out of range!");
     assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!");
-    return mFncGetPixel( mpScanBuf[ nY ], nX, maColorMask );
+
+    return mFncGetPixel(mpScanBuf[nY], nX, maColorMask );
 }
 
-inline sal_uInt8 BitmapReadAccess::GetPixelIndex( long nY, long nX ) const
+inline sal_uInt8 BitmapReadAccess::GetPixelIndex(long nY, long nX) const
 {
-    return GetPixel( nY, nX ).GetBlueOrIndex();
+    return GetPixel(nY, nX).GetBlueOrIndex();
 }
 
-inline BitmapColor BitmapReadAccess::GetPixelFromData( const sal_uInt8* pData, long nX ) const
+inline BitmapColor BitmapReadAccess::GetPixelFromData(const sal_uInt8* pData, long nX) const
 {
     assert(pData && "Access is not valid!");
+
     return mFncGetPixel( pData, nX, maColorMask );
 }
 
-inline void BitmapReadAccess::SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor )
+inline void BitmapReadAccess::SetPixelOnData(sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor)
 {
     assert(pData && "Access is not valid!");
-    mFncSetPixel( pData, nX, rBitmapColor, maColorMask );
+
+    mFncSetPixel(pData, nX, rBitmapColor, maColorMask);
 }
 
-inline BitmapColor BitmapReadAccess::GetColor( long nY, long nX ) const
+inline BitmapColor BitmapReadAccess::GetColor(long nY, long nX) const
 {
-    if( HasPalette() )
-        return mpBuffer->maPalette[ GetPixelIndex( nY, nX ) ];
+    if (HasPalette())
+        return mpBuffer->maPalette[GetPixelIndex(nY, nX)];
     else
-        return GetPixel( nY, nX );
+        return GetPixel(nY, nX);
 }
 
-inline sal_uInt8 BitmapReadAccess::GetLuminance( long nY, long nX ) const
+inline sal_uInt8 BitmapReadAccess::GetLuminance(long nY, long nX) const
 {
-    return GetColor( nY, nX ).GetLuminance();
+    return GetColor(nY, nX).GetLuminance();
 }
 
-inline void BitmapWriteAccess::SetPalette( const BitmapPalette& rPalette )
+inline void BitmapWriteAccess::SetPalette(const BitmapPalette& rPalette)
 {
     assert(mpBuffer && "Access is not valid!");
+
     mpBuffer->maPalette = rPalette;
 }
 
-inline void BitmapWriteAccess::SetPaletteEntryCount( sal_uInt16 nCount )
+inline void BitmapWriteAccess::SetPaletteEntryCount(sal_uInt16 nCount)
 {
     assert(mpBuffer && "Access is not valid!");
-    mpBuffer->maPalette.SetEntryCount( nCount );
+
+    mpBuffer->maPalette.SetEntryCount(nCount);
 }
 
-inline void BitmapWriteAccess::SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor )
+inline void BitmapWriteAccess::SetPaletteColor(sal_uInt16 nColor, const BitmapColor& rBitmapColor)
 {
     assert(mpBuffer && "Access is not valid!");
     assert(HasPalette() && "Bitmap has no palette!");
-    mpBuffer->maPalette[ nColor ] = rBitmapColor;
+
+    mpBuffer->maPalette[nColor] = rBitmapColor;
 }
 
-inline void BitmapWriteAccess::SetPixel( long nY, long nX, const BitmapColor& rBitmapColor )
+inline void BitmapWriteAccess::SetPixel(long nY, long nX, const BitmapColor& rBitmapColor)
 {
     assert(mpBuffer && "Access is not valid!");
     assert(nX < mpBuffer->mnWidth && "x-coordinate out of range!");
     assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!");
-    mFncSetPixel( mpScanBuf[ nY ], nX, rBitmapColor, maColorMask );
+
+    mFncSetPixel(mpScanBuf[nY], nX, rBitmapColor, maColorMask);
 }
 
-inline void BitmapWriteAccess::SetPixelIndex( long nY, long nX, sal_uInt8 cIndex )
+inline void BitmapWriteAccess::SetPixelIndex(long nY, long nX, sal_uInt8 cIndex)
 {
-    SetPixel( nY, nX, BitmapColor( cIndex ));
+    SetPixel(nY, nX, BitmapColor(cIndex));
 }
 
 #endif // INCLUDED_VCL_BMPACC_HXX
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
index 33e5038..cdda5dc 100644
--- a/vcl/source/gdi/bmpacc.cxx
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -171,22 +171,102 @@ bool BitmapReadAccess::ImplSetAccessPointers( sal_uLong nFormat )
 
     switch( nFormat )
     {
-        CASE_FORMAT( _1BIT_MSB_PAL )
-        CASE_FORMAT( _1BIT_LSB_PAL )
-        CASE_FORMAT( _4BIT_MSN_PAL )
-        CASE_FORMAT( _4BIT_LSN_PAL )
-        CASE_FORMAT( _8BIT_PAL )
-        CASE_FORMAT( _8BIT_TC_MASK )
-        CASE_FORMAT( _16BIT_TC_MSB_MASK )
-        CASE_FORMAT( _16BIT_TC_LSB_MASK )
-        CASE_FORMAT( _24BIT_TC_BGR )
-        CASE_FORMAT( _24BIT_TC_RGB )
-        CASE_FORMAT( _24BIT_TC_MASK )
-        CASE_FORMAT( _32BIT_TC_ABGR )
-        CASE_FORMAT( _32BIT_TC_ARGB )
-        CASE_FORMAT( _32BIT_TC_BGRA )
-        CASE_FORMAT( _32BIT_TC_RGBA )
-        CASE_FORMAT( _32BIT_TC_MASK )
+        case BMP_FORMAT_1BIT_MSB_PAL:
+        {
+            mFncGetPixel = GetPixelFor_1BIT_MSB_PAL;
+            mFncSetPixel = SetPixelFor_1BIT_MSB_PAL;
+        }
+        break;
+        case BMP_FORMAT_1BIT_LSB_PAL:
+        {
+            mFncGetPixel = GetPixelFor_1BIT_LSB_PAL;
+            mFncSetPixel = SetPixelFor_1BIT_LSB_PAL;
+        }
+        break;
+        case BMP_FORMAT_4BIT_MSN_PAL:
+        {
+            mFncGetPixel = GetPixelFor_4BIT_MSN_PAL;
+            mFncSetPixel = SetPixelFor_4BIT_MSN_PAL;
+        }
+        break;
+        case BMP_FORMAT_4BIT_LSN_PAL:
+        {
+            mFncGetPixel = GetPixelFor_4BIT_LSN_PAL;
+            mFncSetPixel = SetPixelFor_4BIT_LSN_PAL;
+        }
+        break;
+        case BMP_FORMAT_8BIT_PAL:
+        {
+            mFncGetPixel = GetPixelFor_8BIT_PAL;
+            mFncSetPixel = SetPixelFor_8BIT_PAL;
+        }
+        break;
+        case BMP_FORMAT_8BIT_TC_MASK:
+        {
+            mFncGetPixel = GetPixelFor_8BIT_TC_MASK;
+            mFncSetPixel = SetPixelFor_8BIT_TC_MASK;
+        }
+        break;
+        case BMP_FORMAT_16BIT_TC_MSB_MASK:
+        {
+            mFncGetPixel = GetPixelFor_16BIT_TC_MSB_MASK;
+            mFncSetPixel = SetPixelFor_16BIT_TC_MSB_MASK;
+        }
+        break;
+        case BMP_FORMAT_16BIT_TC_LSB_MASK:
+        {
+            mFncGetPixel = GetPixelFor_16BIT_TC_LSB_MASK;
+            mFncSetPixel = SetPixelFor_16BIT_TC_LSB_MASK;
+        }
+        break;
+        case BMP_FORMAT_24BIT_TC_BGR:
+        {
+            mFncGetPixel = GetPixelFor_24BIT_TC_BGR;
+            mFncSetPixel = SetPixelFor_24BIT_TC_BGR;
+        }
+        break;
+        case BMP_FORMAT_24BIT_TC_RGB:
+        {
+            mFncGetPixel = GetPixelFor_24BIT_TC_RGB;
+            mFncSetPixel = SetPixelFor_24BIT_TC_RGB;
+        }
+        break;
+        case BMP_FORMAT_24BIT_TC_MASK:
+        {
+            mFncGetPixel = GetPixelFor_24BIT_TC_MASK;
+            mFncSetPixel = SetPixelFor_24BIT_TC_MASK;
+        }
+        break;
+        case BMP_FORMAT_32BIT_TC_ABGR:
+        {
+            mFncGetPixel = GetPixelFor_32BIT_TC_ABGR;
+            mFncSetPixel = SetPixelFor_32BIT_TC_ABGR;
+        }
+        break;
+        case BMP_FORMAT_32BIT_TC_ARGB:
+        {
+            mFncGetPixel = GetPixelFor_32BIT_TC_ARGB;
+            mFncSetPixel = SetPixelFor_32BIT_TC_ARGB;
+        }
+        break;
+        case BMP_FORMAT_32BIT_TC_BGRA:
+        {
+            mFncGetPixel = GetPixelFor_32BIT_TC_BGRA;
+            mFncSetPixel = SetPixelFor_32BIT_TC_BGRA;
+        }
+        break;
+        case BMP_FORMAT_32BIT_TC_RGBA:
+        {
+            mFncGetPixel = GetPixelFor_32BIT_TC_RGBA;
+            mFncSetPixel = SetPixelFor_32BIT_TC_RGBA;
+        }
+        break;
+        case BMP_FORMAT_32BIT_TC_MASK:
+        {
+            mFncGetPixel = GetPixelFor_32BIT_TC_MASK;
+            mFncSetPixel = SetPixelFor_32BIT_TC_MASK;
+        }
+        break;
 
         default:
             bRet = false;
diff --git a/vcl/source/gdi/bmpacc2.cxx b/vcl/source/gdi/bmpacc2.cxx
index 12b0c1d..d664c4b 100644
--- a/vcl/source/gdi/bmpacc2.cxx
+++ b/vcl/source/gdi/bmpacc2.cxx
@@ -20,12 +20,12 @@
 #include <vcl/salbtype.hxx>
 #include <vcl/bmpacc.hxx>
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _1BIT_MSB_PAL )
+BitmapColor BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL(ConstScanline pScanline, long nX, const ColorMask&)
 {
     return BitmapColor( pScanline[ nX >> 3 ] & ( 1 << ( 7 - ( nX & 7 ) ) ) ? 1 : 0 );
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _1BIT_MSB_PAL )
+void BitmapReadAccess::SetPixelFor_1BIT_MSB_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     sal_uInt8& rByte = pScanline[ nX >> 3 ];
 
@@ -33,12 +33,12 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _1BIT_MSB_PAL )
                                       ( rByte &= ~( 1 << ( 7 - ( nX & 7 ) ) ) );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _1BIT_LSB_PAL )
+BitmapColor BitmapReadAccess::GetPixelFor_1BIT_LSB_PAL(ConstScanline pScanline, long nX, const ColorMask&)
 {
     return BitmapColor( pScanline[ nX >> 3 ] & ( 1 << ( nX & 7 ) ) ? 1 : 0 );
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _1BIT_LSB_PAL )
+void BitmapReadAccess::SetPixelFor_1BIT_LSB_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     sal_uInt8& rByte = pScanline[ nX >> 3 ];
 
@@ -46,12 +46,12 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _1BIT_LSB_PAL )
                                       ( rByte &= ~( 1 << ( nX & 7 ) ) );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _4BIT_MSN_PAL )
+BitmapColor BitmapReadAccess::GetPixelFor_4BIT_MSN_PAL(ConstScanline pScanline, long nX, const ColorMask&)
 {
     return BitmapColor( ( pScanline[ nX >> 1 ] >> ( nX & 1 ? 0 : 4 ) ) & 0x0f );
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _4BIT_MSN_PAL )
+void BitmapReadAccess::SetPixelFor_4BIT_MSN_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     sal_uInt8& rByte = pScanline[ nX >> 1 ];
 
@@ -59,12 +59,12 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _4BIT_MSN_PAL )
                  ( rByte &= 0x0f, rByte |= ( rBitmapColor.GetIndex() << 4 ) );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _4BIT_LSN_PAL )
+BitmapColor BitmapReadAccess::GetPixelFor_4BIT_LSN_PAL(ConstScanline pScanline, long nX, const ColorMask&)
 {
     return BitmapColor( ( pScanline[ nX >> 1 ] >> ( nX & 1 ? 4 : 0 ) ) & 0x0f );
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _4BIT_LSN_PAL )
+void BitmapReadAccess::SetPixelFor_4BIT_LSN_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     sal_uInt8& rByte = pScanline[ nX >> 1 ];
 
@@ -72,53 +72,54 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _4BIT_LSN_PAL )
                  ( rByte &= 0xf0, rByte |= ( rBitmapColor.GetIndex() & 0x0f ) );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _8BIT_PAL )
+BitmapColor BitmapReadAccess::GetPixelFor_8BIT_PAL(ConstScanline pScanline, long nX, const ColorMask&)
 {
     return BitmapColor( pScanline[ nX ] );
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _8BIT_PAL )
+void BitmapReadAccess::SetPixelFor_8BIT_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     pScanline[ nX ] = rBitmapColor.GetIndex();
 }
 
-IMPL_FORMAT_GETPIXEL( _8BIT_TC_MASK )
+BitmapColor BitmapReadAccess::GetPixelFor_8BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask)
 {
     BitmapColor aColor;
     rMask.GetColorFor8Bit( aColor, pScanline + nX );
     return aColor;
 }
 
-IMPL_FORMAT_SETPIXEL( _8BIT_TC_MASK )
+void BitmapReadAccess::SetPixelFor_8BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask)
 {
     rMask.SetColorFor8Bit( rBitmapColor, pScanline + nX );
 }
 
-IMPL_FORMAT_GETPIXEL( _16BIT_TC_MSB_MASK )
+
+BitmapColor BitmapReadAccess::GetPixelFor_16BIT_TC_MSB_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask)
 {
     BitmapColor aColor;
     rMask.GetColorFor16BitMSB( aColor, pScanline + ( nX << 1UL ) );
     return aColor;
 }
 
-IMPL_FORMAT_SETPIXEL( _16BIT_TC_MSB_MASK )
+void BitmapReadAccess::SetPixelFor_16BIT_TC_MSB_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask)
 {
     rMask.SetColorFor16BitMSB( rBitmapColor, pScanline + ( nX << 1UL ) );
 }
 
-IMPL_FORMAT_GETPIXEL( _16BIT_TC_LSB_MASK )
+BitmapColor BitmapReadAccess::GetPixelFor_16BIT_TC_LSB_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask)
 {
     BitmapColor aColor;
     rMask.GetColorFor16BitLSB( aColor, pScanline + ( nX << 1UL ) );
     return aColor;
 }
 
-IMPL_FORMAT_SETPIXEL( _16BIT_TC_LSB_MASK )
+void BitmapReadAccess::SetPixelFor_16BIT_TC_LSB_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask)
 {
     rMask.SetColorFor16BitLSB( rBitmapColor, pScanline + ( nX << 1UL ) );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _24BIT_TC_BGR )
+BitmapColor BitmapReadAccess::GetPixelFor_24BIT_TC_BGR(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -129,14 +130,14 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _24BIT_TC_BGR )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _24BIT_TC_BGR )
+void BitmapReadAccess::SetPixelFor_24BIT_TC_BGR(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + nX * 3 )++ = rBitmapColor.GetBlue();
     *pScanline++ = rBitmapColor.GetGreen();
     *pScanline = rBitmapColor.GetRed();
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _24BIT_TC_RGB )
+BitmapColor BitmapReadAccess::GetPixelFor_24BIT_TC_RGB(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -147,26 +148,26 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _24BIT_TC_RGB )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _24BIT_TC_RGB )
+void BitmapReadAccess::SetPixelFor_24BIT_TC_RGB(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + nX * 3 )++ = rBitmapColor.GetRed();
     *pScanline++ = rBitmapColor.GetGreen();
     *pScanline = rBitmapColor.GetBlue();
 }
 
-IMPL_FORMAT_GETPIXEL( _24BIT_TC_MASK )
+BitmapColor BitmapReadAccess::GetPixelFor_24BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask)
 {
     BitmapColor aColor;
     rMask.GetColorFor24Bit( aColor, pScanline + nX * 3L );
     return aColor;
 }
 
-IMPL_FORMAT_SETPIXEL( _24BIT_TC_MASK )
+void BitmapReadAccess::SetPixelFor_24BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask)
 {
     rMask.SetColorFor24Bit( rBitmapColor, pScanline + nX * 3L );
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_ABGR )
+BitmapColor BitmapReadAccess::GetPixelFor_32BIT_TC_ABGR(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -177,7 +178,7 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_ABGR )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_ABGR )
+void BitmapReadAccess::SetPixelFor_32BIT_TC_ABGR(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + ( nX << 2 ) )++ = 0xFF;
     *pScanline++ = rBitmapColor.GetBlue();
@@ -185,7 +186,7 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_ABGR )
     *pScanline = rBitmapColor.GetRed();
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_ARGB )
+BitmapColor BitmapReadAccess::GetPixelFor_32BIT_TC_ARGB(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -196,7 +197,7 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_ARGB )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_ARGB )
+void BitmapReadAccess::SetPixelFor_32BIT_TC_ARGB(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + ( nX << 2 ) )++ = 0xFF;
     *pScanline++ = rBitmapColor.GetRed();
@@ -204,7 +205,7 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_ARGB )
     *pScanline = rBitmapColor.GetBlue();
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_BGRA )
+BitmapColor BitmapReadAccess::GetPixelFor_32BIT_TC_BGRA(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -215,7 +216,7 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_BGRA )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_BGRA )
+void BitmapReadAccess::SetPixelFor_32BIT_TC_BGRA(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + ( nX << 2 ) )++ = rBitmapColor.GetBlue();
     *pScanline++ = rBitmapColor.GetGreen();
@@ -223,7 +224,7 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_BGRA )
     *pScanline = 0xFF;
 }
 
-IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_RGBA )
+BitmapColor BitmapReadAccess::GetPixelFor_32BIT_TC_RGBA(ConstScanline pScanline, long nX, const ColorMask&)
 {
     BitmapColor aBitmapColor;
 
@@ -234,7 +235,7 @@ IMPL_FORMAT_GETPIXEL_NOMASK( _32BIT_TC_RGBA )
     return aBitmapColor;
 }
 
-IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_RGBA )
+void BitmapReadAccess::SetPixelFor_32BIT_TC_RGBA(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&)
 {
     *( pScanline = pScanline + ( nX << 2 ) )++ = rBitmapColor.GetRed();
     *pScanline++ = rBitmapColor.GetGreen();
@@ -242,14 +243,14 @@ IMPL_FORMAT_SETPIXEL_NOMASK( _32BIT_TC_RGBA )
     *pScanline = 0xFF;
 }
 
-IMPL_FORMAT_GETPIXEL( _32BIT_TC_MASK )
+BitmapColor BitmapReadAccess::GetPixelFor_32BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask)
 {
     BitmapColor aColor;
     rMask.GetColorFor32Bit( aColor, pScanline + ( nX << 2UL ) );
     return aColor;
 }
 
-IMPL_FORMAT_SETPIXEL( _32BIT_TC_MASK )
+void BitmapReadAccess::SetPixelFor_32BIT_TC_MASK(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask)
 {
     rMask.SetColorFor32Bit( rBitmapColor, pScanline + ( nX << 2UL ) );
 }
commit 44c6c4da9545d69ad02f5e8ea1314388e1eacec7
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Mar 25 11:35:55 2015 +0900

    vcl: tests for Bitmap, check for symmetry when scaling bitmaps
    
    Change-Id: I53d6e70018477abb9f98140a52697c1de0f90934

diff --git a/vcl/CppunitTest_vcl_bitmap_test.mk b/vcl/CppunitTest_vcl_bitmap_test.mk
new file mode 100644
index 0000000..527f5ef
--- /dev/null
+++ b/vcl/CppunitTest_vcl_bitmap_test.mk
@@ -0,0 +1,56 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_bitmap_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_bitmap_test, \
+    vcl/qa/cppunit/BitmapTest \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,vcl_bitmap_test,\
+	boost_headers \
+))
+
+$(eval $(call gb_CppunitTest_set_include,vcl_bitmap_test,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/vcl/inc \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,vcl_bitmap_test, \
+	comphelper \
+	cppu \
+	cppuhelper \
+	sal \
+    svt \
+	test \
+	tl \
+	unotest \
+	vcl \
+	utl \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,vcl_bitmap_test,\
+    udkapi \
+    offapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,vcl_bitmap_test))
+$(eval $(call gb_CppunitTest_use_vcl,vcl_bitmap_test))
+
+$(eval $(call gb_CppunitTest_use_components,vcl_bitmap_test,\
+    configmgr/source/configmgr \
+    i18npool/util/i18npool \
+    ucb/source/core/ucb1 \
+    unotools/util/utl \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,vcl_bitmap_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 4eaca9a..4507f5e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -315,6 +315,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/gdi/wall \
     vcl/source/bitmap/bitmapfilter \
     vcl/source/bitmap/bitmapscalesuper \
+    vcl/source/bitmap/BitmapSymmetryCheck \
     vcl/source/helper/canvasbitmap \
     vcl/source/helper/canvastools \
     vcl/source/helper/evntpost \
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 2cee438..f5be45e 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -99,6 +99,7 @@ $(eval $(call gb_Module_add_targets,vcl,\
 endif
 
 $(eval $(call gb_Module_add_check_targets,vcl,\
+	CppunitTest_vcl_bitmap_test \
 	CppunitTest_vcl_fontcharmap \
 	CppunitTest_vcl_complextext \
 	CppunitTest_vcl_filters_test \
diff --git a/vcl/inc/BitmapSymmetryCheck.hxx b/vcl/inc/BitmapSymmetryCheck.hxx
new file mode 100644
index 0000000..576a61c
--- /dev/null
+++ b/vcl/inc/BitmapSymmetryCheck.hxx
@@ -0,0 +1,31 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_INC_BITMAPSYMMETRYCHECK_HXX
+#define INCLUDED_VCL_INC_BITMAPSYMMETRYCHECK_HXX
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bmpacc.hxx>
+
+class VCL_DLLPUBLIC BitmapSymmetryCheck
+{
+public:
+    BitmapSymmetryCheck();
+    virtual ~BitmapSymmetryCheck();
+
+    bool check(Bitmap& rBitmap);
+
+protected:
+    virtual bool checkImpl(BitmapReadAccess* pReadAccess);
+};
+
+#endif // INCLUDED_VCL_INC_BITMAPSYMMETRYCHECK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/BitmapTest.cxx b/vcl/qa/cppunit/BitmapTest.cxx
new file mode 100644
index 0000000..cc8534f
--- /dev/null
+++ b/vcl/qa/cppunit/BitmapTest.cxx
@@ -0,0 +1,88 @@
+/* -*- 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 <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <tools/stream.hxx>
+#include <vcl/graphicfilter.hxx>
+
+#include "BitmapSymmetryCheck.hxx"
+
+namespace
+{
+
+class BitmapTest : public CppUnit::TestFixture
+{
+    void testScale();
+
+    CPPUNIT_TEST_SUITE(BitmapTest);
+    CPPUNIT_TEST(testScale);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void BitmapTest::testScale()
+{
+    bool bExportBitmap(false);
+
+    Bitmap aBitmap24Bit(Size(10, 10), 24);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(24), aBitmap24Bit.GetBitCount());
+
+    {
+        Bitmap::ScopedWriteAccess aWriteAccess(aBitmap24Bit);
+        aWriteAccess->Erase(COL_WHITE);
+        aWriteAccess->SetLineColor(COL_BLACK);
+        aWriteAccess->DrawRect(Rectangle(1, 1, 8, 8));
+        aWriteAccess->DrawRect(Rectangle(3, 3, 6, 6));
+    }
+
+    BitmapSymmetryCheck aBitmapSymmetryCheck;
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(10), aBitmap24Bit.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(10), aBitmap24Bit.GetSizePixel().Height());
+
+    // Check symmetry of the bitmap
+    CPPUNIT_ASSERT(aBitmapSymmetryCheck.check(aBitmap24Bit));
+
+    if (bExportBitmap)
+    {
+        SvFileStream aStream(OUString("~/scale_before.png"), StreamMode::WRITE | StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream, 9);
+    }
+
+    aBitmap24Bit.Scale(2, 2, BMP_SCALE_FAST);
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(20), aBitmap24Bit.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(20), aBitmap24Bit.GetSizePixel().Height());
+
+    // After scaling the bitmap should still be symmetrical. This check guarantees that
+    // scaling doesn't misalign the bitmap.
+    CPPUNIT_ASSERT(aBitmapSymmetryCheck.check(aBitmap24Bit));
+
+    if (bExportBitmap)
+    {
+        SvFileStream aStream(OUString("~/scale_after.png"), StreamMode::WRITE | StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream, 9);
+    }
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BitmapTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list