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.vajng...@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 <ma...@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.vajng...@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.vajng...@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.vajng...@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.vajng...@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
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits