| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| // bootstrap stuff |
| #include <sal/main.h> |
| #include <rtl/bootstrap.hxx> |
| #include <rtl/ref.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/regpathhelper.hxx> |
| #include <cppuhelper/servicefactory.hxx> |
| #include <cppuhelper/bootstrap.hxx> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/registry/XSimpleRegistry.hpp> |
| #include <com/sun/star/util/Endianness.hpp> |
| #include <com/sun/star/rendering/ColorComponentTag.hpp> |
| #include <com/sun/star/rendering/ColorSpaceType.hpp> |
| #include <com/sun/star/rendering/RenderingIntent.hpp> |
| #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp> |
| #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp> |
| #include <com/sun/star/rendering/XBitmapPalette.hpp> |
| |
| #include <ucbhelper/contentbroker.hxx> |
| #include <ucbhelper/configurationkeys.hxx> |
| #include <cppuhelper/compbase3.hxx> |
| |
| #include <tools/diagnose_ex.h> |
| #include <tools/extendapplicationenvironment.hxx> |
| |
| #include "vcl/svapp.hxx" |
| #include "vcl/canvastools.hxx" |
| #include "vcl/canvasbitmap.hxx" |
| #include "vcl/dialog.hxx" |
| #include "vcl/outdev.hxx" |
| #include "vcl/bmpacc.hxx" |
| #include "vcl/virdev.hxx" |
| #include "vcl/bitmapex.hxx" |
| |
| |
| using namespace ::com::sun::star; |
| using namespace ::vcl::unotools; |
| |
| // ----------------------------------------------------------------------- |
| |
| void Main(); |
| |
| // ----------------------------------------------------------------------- |
| |
| SAL_IMPLEMENT_MAIN() |
| { |
| tools::extendApplicationEnvironment(); |
| |
| uno::Reference< lang::XMultiServiceFactory > xMS; |
| xMS = cppu::createRegistryServiceFactory( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), |
| sal_True ); |
| |
| InitVCL( xMS ); |
| ::Main(); |
| DeInitVCL(); |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| namespace com { namespace sun { namespace star { namespace rendering |
| { |
| |
| bool operator==( const RGBColor& rLHS, const ARGBColor& rRHS ) |
| { |
| return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue; |
| } |
| bool operator==( const ARGBColor& rLHS, const RGBColor& rRHS ) |
| { |
| return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue; |
| } |
| |
| } } } } |
| |
| //---------------------------------------------------------------------------------- |
| |
| namespace |
| { |
| |
| class TestApp : public Application |
| { |
| public: |
| virtual void Main(); |
| virtual USHORT Exception( USHORT nError ); |
| }; |
| |
| class TestWindow : public Dialog |
| { |
| public: |
| TestWindow() : Dialog( (Window *) NULL ) |
| { |
| SetText( rtl::OUString::createFromAscii( "CanvasBitmap test harness" ) ); |
| SetSizePixel( Size( 1024, 1024 ) ); |
| EnablePaint( true ); |
| Show(); |
| } |
| |
| virtual ~TestWindow() {} |
| virtual void Paint( const Rectangle& rRect ); |
| }; |
| |
| //---------------------------------------------------------------------------------- |
| |
| static bool g_failure=false; |
| |
| void test( bool bResult, const char* msg ) |
| { |
| if( bResult ) |
| { |
| OSL_TRACE("Testing: %s - PASSED", msg); |
| } |
| else |
| { |
| g_failure = true; |
| OSL_TRACE("Testing: %s - FAILED", msg); |
| } |
| } |
| |
| //---------------------------------------------------------------------------------- |
| |
| bool rangeCheck( const rendering::RGBColor& rColor ) |
| { |
| return rColor.Red < 0.0 || rColor.Red > 1.0 || |
| rColor.Green < 0.0 || rColor.Green > 1.0 || |
| rColor.Blue < 0.0 || rColor.Blue > 1.0; |
| } |
| |
| //---------------------------------------------------------------------------------- |
| |
| void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, |
| const char* msg, |
| int nOriginalDepth ) |
| { |
| OSL_TRACE("-------------------------"); |
| OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth); |
| |
| BitmapEx aContainedBmpEx( xBmp->getBitmapEx() ); |
| Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() ); |
| int nDepth = nOriginalDepth; |
| |
| { |
| ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(), |
| aContainedBmp ); |
| nDepth = pAcc->GetBitCount(); |
| } |
| |
| test( aContainedBmp.GetSizePixel() == Size(200,200), |
| "Original bitmap size" ); |
| |
| test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200, |
| "Original bitmap size via API" ); |
| |
| test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(), |
| "Correct alpha state" ); |
| |
| test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(), |
| "getScaledBitmap()" ); |
| |
| rendering::IntegerBitmapLayout aLayout; |
| uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1)); |
| |
| const sal_Int32 nExpectedBitsPerPixel( |
| aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth); |
| test( aLayout.ScanLines == 1, |
| "# scanlines" ); |
| test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8, |
| "# scanline bytes" ); |
| test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 || |
| aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8, |
| "# scanline stride" ); |
| test( aLayout.PlaneStride == 0, |
| "# plane stride" ); |
| |
| test( aLayout.ColorSpace.is(), |
| "Color space there" ); |
| |
| test( aLayout.Palette.is() == (nDepth <= 8), |
| "Palette existance conforms to bitmap" ); |
| |
| uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) ); |
| |
| test( aPixelData2.getLength() == aPixelData.getLength(), |
| "getData and getPixel return same amount of data" ); |
| |
| aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1)); |
| test( aLayout.ScanLines == 1, |
| "# scanlines" ); |
| test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8, |
| "# scanline bytes" ); |
| test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 || |
| aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8, |
| "# scanline stride" ); |
| |
| uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData ); |
| uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData ); |
| |
| const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() ); |
| const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() ); |
| const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() ); |
| std::pair<const rendering::RGBColor*, |
| const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart ); |
| test( aRes.first == pRGBEnd, |
| "argb and rgb colors are equal" ); |
| |
| test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd, |
| "rgb colors are within [0,1] range" ); |
| |
| test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0, |
| "First pixel is white" ); |
| test( pARGBStart[1].Alpha == 1.0, |
| "Second pixel is opaque" ); |
| if( aContainedBmpEx.IsTransparent() ) |
| { |
| test( pARGBStart[0].Alpha == 0.0, |
| "First pixel is fully transparent" ); |
| } |
| |
| test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0, |
| "Second pixel is black" ); |
| |
| if( nOriginalDepth > 8 ) |
| { |
| const Color aCol(COL_GREEN); |
| test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) && |
| pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) && |
| pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()), |
| "Sixth pixel is green" ); |
| } |
| else if( nDepth <= 8 ) |
| { |
| uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette(); |
| test( xPal.is(), |
| "8bit or less: needs palette" ); |
| test( xPal->getNumberOfEntries() == 1L << nOriginalDepth, |
| "Palette has correct entry count" ); |
| uno::Sequence<double> aIndex; |
| test( xPal->setIndex(aIndex,sal_True,0) == sal_False, |
| "Palette is read-only" ); |
| test( xPal->getIndex(aIndex,0), |
| "Palette entry 0 is opaque" ); |
| test( xPal->getColorSpace().is(), |
| "Palette has a valid color space" ); |
| } |
| |
| test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0, |
| "150th pixel is white" ); |
| |
| if( nOriginalDepth > 8 ) |
| { |
| const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() ); |
| uno::Sequence<rendering::ARGBColor> aARGBColor(1); |
| uno::Sequence<rendering::RGBColor> aRGBColor(1); |
| uno::Sequence<sal_Int8> aPixel3, aPixel4; |
| |
| const Color aCol(COL_GREEN); |
| aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); |
| aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); |
| aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); |
| aARGBColor[0].Alpha = 1.0; |
| |
| aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); |
| aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); |
| aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); |
| |
| aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor ); |
| aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) ); |
| test( aPixel3 == aPixel4, |
| "Green pixel from bitmap matches with manually converted green pixel" ); |
| |
| if( !aContainedBmpEx.IsTransparent() ) |
| { |
| aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor ); |
| test( aPixel3 == aPixel4, |
| "Green pixel from bitmap matches with manually RGB-converted green pixel" ); |
| } |
| } |
| } |
| |
| //---------------------------------------------------------------------------------- |
| |
| void checkBitmapImport( const rtl::Reference<VclCanvasBitmap>& xBmp, |
| const char* msg, |
| int nOriginalDepth ) |
| { |
| OSL_TRACE("-------------------------"); |
| OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth); |
| |
| BitmapEx aContainedBmpEx( xBmp->getBitmapEx() ); |
| Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() ); |
| int nDepth = nOriginalDepth; |
| |
| { |
| ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(), |
| aContainedBmp ); |
| nDepth = pAcc->GetBitCount(); |
| } |
| |
| test( aContainedBmp.GetSizePixel() == Size(200,200), |
| "Original bitmap size" ); |
| |
| test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200, |
| "Original bitmap size via API" ); |
| |
| test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(), |
| "Correct alpha state" ); |
| |
| test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(), |
| "getScaledBitmap()" ); |
| |
| rendering::IntegerBitmapLayout aLayout; |
| uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1)); |
| |
| const sal_Int32 nExpectedBitsPerPixel( |
| aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth); |
| test( aLayout.ScanLines == 1, |
| "# scanlines" ); |
| test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8, |
| "# scanline bytes" ); |
| test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 || |
| aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8, |
| "# scanline stride" ); |
| test( aLayout.PlaneStride == 0, |
| "# plane stride" ); |
| |
| test( aLayout.ColorSpace.is(), |
| "Color space there" ); |
| |
| test( aLayout.Palette.is() == (nDepth <= 8), |
| "Palette existance conforms to bitmap" ); |
| |
| uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) ); |
| |
| test( aPixelData2.getLength() == aPixelData.getLength(), |
| "getData and getPixel return same amount of data" ); |
| |
| aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1)); |
| test( aLayout.ScanLines == 1, |
| "# scanlines" ); |
| test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8, |
| "# scanline bytes" ); |
| test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 || |
| aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8, |
| "# scanline stride" ); |
| |
| uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData ); |
| uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData ); |
| |
| const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() ); |
| const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() ); |
| const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() ); |
| std::pair<const rendering::RGBColor*, |
| const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart ); |
| test( aRes.first == pRGBEnd, |
| "argb and rgb colors are equal" ); |
| |
| test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd, |
| "rgb colors are within [0,1] range" ); |
| |
| test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0, |
| "First pixel is white" ); |
| test( pARGBStart[1].Alpha == 1.0, |
| "Second pixel is opaque" ); |
| if( aContainedBmpEx.IsTransparent() ) |
| { |
| test( pARGBStart[0].Alpha == 0.0, |
| "First pixel is fully transparent" ); |
| } |
| |
| test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0, |
| "Second pixel is black" ); |
| |
| if( nOriginalDepth > 8 ) |
| { |
| const Color aCol(COL_GREEN); |
| test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) && |
| pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) && |
| pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()), |
| "Sixth pixel is green" ); |
| } |
| else if( nDepth <= 8 ) |
| { |
| uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette(); |
| test( xPal.is(), |
| "8bit or less: needs palette" ); |
| test( xPal->getNumberOfEntries() == 1L << nOriginalDepth, |
| "Palette has correct entry count" ); |
| uno::Sequence<double> aIndex; |
| test( xPal->setIndex(aIndex,sal_True,0) == sal_False, |
| "Palette is read-only" ); |
| test( xPal->getIndex(aIndex,0), |
| "Palette entry 0 is opaque" ); |
| test( xPal->getColorSpace().is(), |
| "Palette has a valid color space" ); |
| } |
| |
| test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0, |
| "150th pixel is white" ); |
| |
| if( nOriginalDepth > 8 ) |
| { |
| const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() ); |
| uno::Sequence<rendering::ARGBColor> aARGBColor(1); |
| uno::Sequence<rendering::RGBColor> aRGBColor(1); |
| uno::Sequence<sal_Int8> aPixel3, aPixel4; |
| |
| const Color aCol(COL_GREEN); |
| aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); |
| aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); |
| aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); |
| aARGBColor[0].Alpha = 1.0; |
| |
| aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); |
| aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); |
| aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); |
| |
| aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor ); |
| aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) ); |
| test( aPixel3 == aPixel4, |
| "Green pixel from bitmap matches with manually converted green pixel" ); |
| |
| if( !aContainedBmpEx.IsTransparent() ) |
| { |
| aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor ); |
| test( aPixel3 == aPixel4, |
| "Green pixel from bitmap matches with manually RGB-converted green pixel" ); |
| } |
| } |
| } |
| |
| //---------------------------------------------------------------------------------- |
| |
| class TestBitmap : public cppu::WeakImplHelper3< rendering::XIntegerReadOnlyBitmap, |
| rendering::XBitmapPalette, |
| rendering::XIntegerBitmapColorSpace > |
| { |
| private: |
| geometry::IntegerSize2D maSize; |
| uno::Sequence<sal_Int8> maComponentTags; |
| uno::Sequence<sal_Int32> maComponentBitCounts; |
| rendering::IntegerBitmapLayout maLayout; |
| const sal_Int32 mnBitsPerPixel; |
| |
| // XBitmap |
| virtual geometry::IntegerSize2D SAL_CALL getSize() throw (uno::RuntimeException) { return maSize; } |
| virtual ::sal_Bool SAL_CALL hasAlpha( ) throw (uno::RuntimeException) { return mnBitsPerPixel != 8; } |
| virtual uno::Reference< rendering::XBitmap > SAL_CALL getScaledBitmap( const geometry::RealSize2D&, |
| sal_Bool ) throw (uno::RuntimeException) { return this; } |
| |
| // XIntegerReadOnlyBitmap |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL getData( rendering::IntegerBitmapLayout& bitmapLayout, |
| const geometry::IntegerRectangle2D& rect ) throw (lang::IndexOutOfBoundsException, |
| rendering::VolatileContentDestroyedException, uno::RuntimeException) |
| { |
| test( rect.X1 >= 0, "X1 within bounds" ); |
| test( rect.Y1 >= 0, "Y1 within bounds" ); |
| test( rect.X2 <= maSize.Width, "X2 within bounds" ); |
| test( rect.Y2 <= maSize.Height, "Y2 within bounds" ); |
| |
| bitmapLayout = getMemoryLayout(); |
| |
| const sal_Int32 nWidth = rect.X2-rect.X1; |
| const sal_Int32 nHeight = rect.Y2-rect.Y1; |
| const sal_Int32 nScanlineLen = (nWidth * mnBitsPerPixel + 7)/8; |
| uno::Sequence<sal_Int8> aRes( nScanlineLen * nHeight ); |
| sal_Int8* pOut = aRes.getArray(); |
| |
| bitmapLayout.ScanLines = nHeight; |
| bitmapLayout.ScanLineBytes = |
| bitmapLayout.ScanLineStride= nScanlineLen; |
| |
| if( mnBitsPerPixel == 8 ) |
| { |
| for( sal_Int32 y=0; y<nHeight; ++y ) |
| { |
| for( sal_Int32 x=0; x<nWidth; ++x ) |
| pOut[ y*nScanlineLen + x ] = sal_Int8(x); |
| } |
| } |
| else |
| { |
| for( sal_Int32 y=0; y<nHeight; ++y ) |
| { |
| for( sal_Int32 x=0; x<nWidth; ++x ) |
| { |
| pOut[ y*nScanlineLen + 4*x ] = sal_Int8(rect.X1); |
| pOut[ y*nScanlineLen + 4*x + 1 ] = sal_Int8(rect.Y2); |
| pOut[ y*nScanlineLen + 4*x + 2 ] = sal_Int8(x); |
| pOut[ y*nScanlineLen + 4*x + 3 ] = sal_Int8(rect.Y1); |
| } |
| } |
| } |
| |
| return aRes; |
| } |
| |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL getPixel( rendering::IntegerBitmapLayout&, |
| const geometry::IntegerPoint2D& ) throw (lang::IndexOutOfBoundsException, |
| rendering::VolatileContentDestroyedException, uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| virtual uno::Reference< rendering::XBitmapPalette > SAL_CALL getPalette( ) throw (uno::RuntimeException) |
| { |
| uno::Reference< XBitmapPalette > aRet; |
| if( mnBitsPerPixel == 8 ) |
| aRet.set(this); |
| return aRet; |
| } |
| |
| virtual rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout( ) throw (uno::RuntimeException) |
| { |
| rendering::IntegerBitmapLayout aLayout( maLayout ); |
| |
| const sal_Int32 nScanlineLen = (maSize.Width * mnBitsPerPixel + 7)/8; |
| |
| aLayout.ScanLines = maSize.Height; |
| aLayout.ScanLineBytes = |
| aLayout.ScanLineStride= nScanlineLen; |
| aLayout.Palette = getPalette(); |
| aLayout.ColorSpace.set( this ); |
| |
| return aLayout; |
| } |
| |
| // XBitmapPalette |
| virtual sal_Int32 SAL_CALL getNumberOfEntries() throw (uno::RuntimeException) |
| { |
| test( getPalette().is(), |
| "Got palette interface call without handing out palette?!" ); |
| |
| return 255; |
| } |
| |
| virtual ::sal_Bool SAL_CALL getIndex( uno::Sequence< double >& entry, |
| ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, |
| uno::RuntimeException) |
| { |
| test( getPalette().is(), |
| "Got palette interface call without handing out palette?!" ); |
| test( nIndex >= 0 && nIndex < 256, |
| "Index out of range" ); |
| entry = colorToStdColorSpaceSequence( |
| Color(UINT8(nIndex), |
| UINT8(nIndex), |
| UINT8(nIndex)) ); |
| |
| return sal_True; // no palette transparency here. |
| } |
| |
| virtual ::sal_Bool SAL_CALL setIndex( const uno::Sequence< double >&, |
| ::sal_Bool, |
| ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, |
| lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test( getPalette().is(), |
| "Got palette interface call without handing out palette?!" ); |
| test( nIndex >= 0 && nIndex < 256, |
| "Index out of range" ); |
| return sal_False; |
| } |
| |
| struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, |
| PaletteColorSpaceHolder> |
| { |
| uno::Reference<rendering::XColorSpace> operator()() |
| { |
| return vcl::unotools::createStandardColorSpace(); |
| } |
| }; |
| |
| virtual uno::Reference< rendering::XColorSpace > SAL_CALL getColorSpace( ) throw (uno::RuntimeException) |
| { |
| // this is the method from XBitmapPalette. Return palette color |
| // space here |
| return PaletteColorSpaceHolder::get(); |
| } |
| |
| // XIntegerBitmapColorSpace |
| virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException) |
| { |
| return rendering::ColorSpaceType::RGB; |
| } |
| |
| virtual uno::Sequence< sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException) |
| { |
| return maComponentTags; |
| } |
| |
| virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException) |
| { |
| return rendering::RenderingIntent::PERCEPTUAL; |
| } |
| |
| virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< ::beans::PropertyValue >(); |
| } |
| |
| virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >&, |
| const uno::Reference< rendering::XColorSpace >& ) throw (uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< double >(); |
| } |
| |
| virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< rendering::RGBColor >(); |
| } |
| |
| virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< rendering::ARGBColor >(); |
| } |
| |
| virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< rendering::ARGBColor >(); |
| } |
| |
| virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< double >(); |
| } |
| |
| virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "This method is not expected to be called!"); |
| return uno::Sequence< double >(); |
| } |
| |
| virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "This method is not expected to be called!"); |
| return uno::Sequence< double >(); |
| } |
| |
| virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException) |
| { |
| return mnBitsPerPixel; |
| } |
| |
| virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException) |
| { |
| return maComponentBitCounts; |
| } |
| |
| virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException) |
| { |
| return util::Endianness::LITTLE; |
| } |
| |
| virtual uno::Sequence< double > SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& , |
| const uno::Reference< rendering::XColorSpace >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< double >(); |
| } |
| |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& , |
| const uno::Reference< rendering::XIntegerBitmapColorSpace >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| const uno::Sequence< rendering::ARGBColor > aTemp( convertIntegerToARGB(deviceColor) ); |
| const sal_Size nLen(aTemp.getLength()); |
| uno::Sequence< rendering::RGBColor > aRes( nLen ); |
| rendering::RGBColor* pOut = aRes.getArray(); |
| for( sal_Size i=0; i<nLen; ++i ) |
| { |
| *pOut++ = rendering::RGBColor(aTemp[i].Red, |
| aTemp[i].Green, |
| aTemp[i].Blue); |
| } |
| |
| return aRes; |
| } |
| |
| virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| const sal_Size nLen( deviceColor.getLength() ); |
| const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4); |
| test(nLen%nBytesPerPixel==0, |
| "number of channels no multiple of pixel element count"); |
| |
| uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel ); |
| rendering::ARGBColor* pOut( aRes.getArray() ); |
| |
| if( getPalette().is() ) |
| { |
| for( sal_Size i=0; i<nLen; ++i ) |
| { |
| *pOut++ = rendering::ARGBColor( |
| 1.0, |
| vcl::unotools::toDoubleColor(deviceColor[i]), |
| vcl::unotools::toDoubleColor(deviceColor[i]), |
| vcl::unotools::toDoubleColor(deviceColor[i])); |
| } |
| } |
| else |
| { |
| for( sal_Size i=0; i<nLen; i+=4 ) |
| { |
| *pOut++ = rendering::ARGBColor( |
| vcl::unotools::toDoubleColor(deviceColor[i+3]), |
| vcl::unotools::toDoubleColor(deviceColor[i+0]), |
| vcl::unotools::toDoubleColor(deviceColor[i+1]), |
| vcl::unotools::toDoubleColor(deviceColor[i+2])); |
| } |
| } |
| |
| return aRes; |
| } |
| |
| virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| const sal_Size nLen( deviceColor.getLength() ); |
| const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4); |
| test(nLen%nBytesPerPixel==0, |
| "number of channels no multiple of pixel element count"); |
| |
| uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel ); |
| rendering::ARGBColor* pOut( aRes.getArray() ); |
| |
| if( getPalette().is() ) |
| { |
| for( sal_Size i=0; i<nLen; ++i ) |
| { |
| *pOut++ = rendering::ARGBColor( |
| 1.0, |
| vcl::unotools::toDoubleColor(deviceColor[i]), |
| vcl::unotools::toDoubleColor(deviceColor[i]), |
| vcl::unotools::toDoubleColor(deviceColor[i])); |
| } |
| } |
| else |
| { |
| for( sal_Size i=0; i<nLen; i+=4 ) |
| { |
| const double fAlpha=vcl::unotools::toDoubleColor(deviceColor[i+3]); |
| *pOut++ = rendering::ARGBColor( |
| fAlpha, |
| fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+0]), |
| fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+1]), |
| fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+2])); |
| } |
| } |
| |
| return aRes; |
| } |
| |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| test(false, "Method not implemented"); |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| public: |
| TestBitmap( const geometry::IntegerSize2D& rSize, bool bPalette ) : |
| maSize(rSize), |
| maComponentTags(), |
| maComponentBitCounts(), |
| maLayout(), |
| mnBitsPerPixel( bPalette ? 8 : 32 ) |
| { |
| if( bPalette ) |
| { |
| maComponentTags.realloc(1); |
| maComponentTags[0] = rendering::ColorComponentTag::INDEX; |
| |
| maComponentBitCounts.realloc(1); |
| maComponentBitCounts[0] = 8; |
| } |
| else |
| { |
| maComponentTags.realloc(4); |
| sal_Int8* pTags = maComponentTags.getArray(); |
| pTags[0] = rendering::ColorComponentTag::RGB_BLUE; |
| pTags[1] = rendering::ColorComponentTag::RGB_GREEN; |
| pTags[2] = rendering::ColorComponentTag::RGB_RED; |
| pTags[3] = rendering::ColorComponentTag::ALPHA; |
| |
| maComponentBitCounts.realloc(4); |
| sal_Int32* pCounts = maComponentBitCounts.getArray(); |
| pCounts[0] = 8; |
| pCounts[1] = 8; |
| pCounts[2] = 8; |
| pCounts[3] = 8; |
| } |
| |
| maLayout.ScanLines = 0; |
| maLayout.ScanLineBytes = 0; |
| maLayout.ScanLineStride = 0; |
| maLayout.PlaneStride = 0; |
| maLayout.ColorSpace.clear(); |
| maLayout.Palette.clear(); |
| maLayout.IsMsbFirst = sal_False; |
| } |
| }; |
| |
| |
| //---------------------------------------------------------------------------------- |
| |
| void TestWindow::Paint( const Rectangle& ) |
| { |
| static sal_Int8 lcl_depths[]={1,4,8,16,24}; |
| |
| try |
| { |
| // Testing VclCanvasBitmap wrapper |
| // =============================== |
| |
| for( unsigned int i=0; i<sizeof(lcl_depths)/sizeof(*lcl_depths); ++i ) |
| { |
| const sal_Int8 nDepth( lcl_depths[i] ); |
| Bitmap aBitmap(Size(200,200),nDepth); |
| aBitmap.Erase(COL_WHITE); |
| { |
| ScopedBitmapWriteAccess pAcc(aBitmap.AcquireWriteAccess(), |
| aBitmap); |
| if( pAcc.get() ) |
| { |
| BitmapColor aBlack(0); |
| BitmapColor aWhite(0); |
| if( pAcc->HasPalette() ) |
| { |
| aBlack.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(0,0,0))) ); |
| aWhite.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(255,255,255))) ); |
| } |
| else |
| { |
| aBlack = Color(COL_BLACK); |
| aWhite = Color(COL_WHITE); |
| } |
| pAcc->SetFillColor(COL_GREEN); |
| pAcc->FillRect(Rectangle(0,0,100,100)); |
| pAcc->SetPixel(0,0,aWhite); |
| pAcc->SetPixel(0,1,aBlack); |
| pAcc->SetPixel(0,2,aWhite); |
| } |
| } |
| |
| rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(aBitmap) ); |
| |
| checkCanvasBitmap( xBmp, "single bitmap", nDepth ); |
| |
| Bitmap aMask(Size(200,200),1); |
| aMask.Erase(COL_WHITE); |
| { |
| ScopedBitmapWriteAccess pAcc(aMask.AcquireWriteAccess(), |
| aMask); |
| if( pAcc.get() ) |
| { |
| pAcc->SetFillColor(COL_BLACK); |
| pAcc->FillRect(Rectangle(0,0,100,100)); |
| pAcc->SetPixel(0,0,BitmapColor(1)); |
| pAcc->SetPixel(0,1,BitmapColor(0)); |
| pAcc->SetPixel(0,2,BitmapColor(1)); |
| } |
| } |
| |
| xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aMask)) ); |
| |
| checkCanvasBitmap( xBmp, "masked bitmap", nDepth ); |
| |
| AlphaMask aAlpha(Size(200,200)); |
| aAlpha.Erase(255); |
| { |
| BitmapWriteAccess* pAcc = aAlpha.AcquireWriteAccess(); |
| if( pAcc ) |
| { |
| pAcc->SetFillColor(COL_BLACK); |
| pAcc->FillRect(Rectangle(0,0,100,100)); |
| pAcc->SetPixel(0,0,BitmapColor(255)); |
| pAcc->SetPixel(0,1,BitmapColor(0)); |
| pAcc->SetPixel(0,2,BitmapColor(255)); |
| aAlpha.ReleaseAccess(pAcc); |
| } |
| } |
| |
| xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aAlpha)) ); |
| |
| checkCanvasBitmap( xBmp, "alpha bitmap", nDepth ); |
| } |
| |
| // Testing XBitmap import |
| // ====================== |
| uno::Reference< rendering::XIntegerReadOnlyBitmap > xTestBmp( |
| new TestBitmap( geometry::IntegerSize2D(10,10), true )); |
| |
| BitmapEx aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); |
| test( aBmp.IsTransparent() == false, |
| "Palette bitmap is not transparent" ); |
| test( aBmp.GetSizePixel() == Size(10,10), |
| "Bitmap has size (10,10)" ); |
| test( aBmp.GetBitCount() == 8, |
| "Bitmap has bitcount of 8" ); |
| { |
| BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess(); |
| |
| test( pBmpAcc, |
| "Bitmap has valid BitmapReadAccess" ); |
| |
| test(pBmpAcc->GetPixel(0,0) == BitmapColor(0), |
| "(0,0) correct content"); |
| test(pBmpAcc->GetPixel(2,2) == BitmapColor(2), |
| "(2,2) correct content"); |
| test(pBmpAcc->GetPixel(2,9) == BitmapColor(9), |
| "(9,2) correct content"); |
| |
| aBmp.GetBitmap().ReleaseAccess(pBmpAcc); |
| } |
| |
| xTestBmp.set( new TestBitmap( geometry::IntegerSize2D(10,10), false )); |
| |
| aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); |
| test( aBmp.IsTransparent() == TRUE, |
| "Palette bitmap is transparent" ); |
| test( aBmp.IsAlpha() == TRUE, |
| "Palette bitmap has alpha" ); |
| test( aBmp.GetSizePixel() == Size(10,10), |
| "Bitmap has size (10,10)" ); |
| test( aBmp.GetBitCount() == 24, |
| "Bitmap has bitcount of 24" ); |
| { |
| BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess(); |
| BitmapReadAccess* pAlphaAcc = aBmp.GetAlpha().AcquireReadAccess(); |
| |
| test( pBmpAcc, |
| "Bitmap has valid BitmapReadAccess" ); |
| test( pAlphaAcc, |
| "Bitmap has valid alpha BitmapReadAccess" ); |
| |
| test(pBmpAcc->GetPixel(0,0) == BitmapColor(0,1,0), |
| "(0,0) correct content"); |
| test(pAlphaAcc->GetPixel(0,0) == BitmapColor(255), |
| "(0,0) correct alpha content"); |
| test(pBmpAcc->GetPixel(2,2) == BitmapColor(0,3,2), |
| "(2,2) correct content"); |
| test(pAlphaAcc->GetPixel(2,2) == BitmapColor(253), |
| "(2,2) correct alpha content"); |
| test(pBmpAcc->GetPixel(2,9) == BitmapColor(0,3,9), |
| "(9,2) correct content"); |
| test(pAlphaAcc->GetPixel(2,9) == BitmapColor(253), |
| "(9,2) correct alpha content"); |
| |
| aBmp.GetAlpha().ReleaseAccess(pAlphaAcc); |
| aBmp.GetBitmap().ReleaseAccess(pBmpAcc); |
| } |
| } |
| catch( uno::Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| exit(2); |
| } |
| catch( std::exception& ) |
| { |
| OSL_TRACE( "Caught std exception!" ); |
| } |
| |
| if( g_failure ) |
| exit(2); |
| } |
| |
| } // namespace |
| |
| void Main() |
| { |
| TestWindow aWindow; |
| aWindow.Execute(); |
| aWindow.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL - canvasbitmaptest" ) ) ); |
| |
| Application::Execute(); |
| } |
| |