1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir // bootstrap stuff 28cdf0e10cSrcweir #include <sal/main.h> 29cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 30cdf0e10cSrcweir #include <rtl/ref.hxx> 31cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 32cdf0e10cSrcweir #include <comphelper/regpathhelper.hxx> 33cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx> 34cdf0e10cSrcweir #include <cppuhelper/bootstrap.hxx> 35cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 36cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp> 37cdf0e10cSrcweir #include <com/sun/star/registry/XSimpleRegistry.hpp> 38cdf0e10cSrcweir #include <com/sun/star/util/Endianness.hpp> 39cdf0e10cSrcweir #include <com/sun/star/rendering/ColorComponentTag.hpp> 40cdf0e10cSrcweir #include <com/sun/star/rendering/ColorSpaceType.hpp> 41cdf0e10cSrcweir #include <com/sun/star/rendering/RenderingIntent.hpp> 42cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp> 43cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp> 44cdf0e10cSrcweir #include <com/sun/star/rendering/XBitmapPalette.hpp> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include <ucbhelper/contentbroker.hxx> 47cdf0e10cSrcweir #include <ucbhelper/configurationkeys.hxx> 48cdf0e10cSrcweir #include <cppuhelper/compbase3.hxx> 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include <tools/diagnose_ex.h> 51cdf0e10cSrcweir #include <tools/extendapplicationenvironment.hxx> 52cdf0e10cSrcweir 53cdf0e10cSrcweir #include "vcl/svapp.hxx" 54cdf0e10cSrcweir #include "vcl/canvastools.hxx" 55cdf0e10cSrcweir #include "vcl/canvasbitmap.hxx" 56cdf0e10cSrcweir #include "vcl/dialog.hxx" 57cdf0e10cSrcweir #include "vcl/outdev.hxx" 58cdf0e10cSrcweir #include "vcl/bmpacc.hxx" 59cdf0e10cSrcweir #include "vcl/virdev.hxx" 60cdf0e10cSrcweir #include "vcl/bitmapex.hxx" 61cdf0e10cSrcweir 62cdf0e10cSrcweir 63cdf0e10cSrcweir using namespace ::com::sun::star; 64cdf0e10cSrcweir using namespace ::vcl::unotools; 65cdf0e10cSrcweir 66cdf0e10cSrcweir // ----------------------------------------------------------------------- 67cdf0e10cSrcweir 68cdf0e10cSrcweir void Main(); 69cdf0e10cSrcweir 70cdf0e10cSrcweir // ----------------------------------------------------------------------- 71cdf0e10cSrcweir 72cdf0e10cSrcweir SAL_IMPLEMENT_MAIN() 73cdf0e10cSrcweir { 74cdf0e10cSrcweir tools::extendApplicationEnvironment(); 75cdf0e10cSrcweir 76cdf0e10cSrcweir uno::Reference< lang::XMultiServiceFactory > xMS; 77cdf0e10cSrcweir xMS = cppu::createRegistryServiceFactory( 78cdf0e10cSrcweir rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), 79cdf0e10cSrcweir sal_True ); 80cdf0e10cSrcweir 81cdf0e10cSrcweir InitVCL( xMS ); 82cdf0e10cSrcweir ::Main(); 83cdf0e10cSrcweir DeInitVCL(); 84cdf0e10cSrcweir 85cdf0e10cSrcweir return 0; 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir // ----------------------------------------------------------------------- 89cdf0e10cSrcweir 90cdf0e10cSrcweir namespace com { namespace sun { namespace star { namespace rendering 91cdf0e10cSrcweir { 92cdf0e10cSrcweir 93cdf0e10cSrcweir bool operator==( const RGBColor& rLHS, const ARGBColor& rRHS ) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue; 96cdf0e10cSrcweir } 97cdf0e10cSrcweir bool operator==( const ARGBColor& rLHS, const RGBColor& rRHS ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir } } } } 103cdf0e10cSrcweir 104cdf0e10cSrcweir //---------------------------------------------------------------------------------- 105cdf0e10cSrcweir 106cdf0e10cSrcweir namespace 107cdf0e10cSrcweir { 108cdf0e10cSrcweir 109cdf0e10cSrcweir class TestApp : public Application 110cdf0e10cSrcweir { 111cdf0e10cSrcweir public: 112cdf0e10cSrcweir virtual void Main(); 113cdf0e10cSrcweir virtual USHORT Exception( USHORT nError ); 114cdf0e10cSrcweir }; 115cdf0e10cSrcweir 116cdf0e10cSrcweir class TestWindow : public Dialog 117cdf0e10cSrcweir { 118cdf0e10cSrcweir public: 119cdf0e10cSrcweir TestWindow() : Dialog( (Window *) NULL ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir SetText( rtl::OUString::createFromAscii( "CanvasBitmap test harness" ) ); 122cdf0e10cSrcweir SetSizePixel( Size( 1024, 1024 ) ); 123cdf0e10cSrcweir EnablePaint( true ); 124cdf0e10cSrcweir Show(); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir virtual ~TestWindow() {} 128cdf0e10cSrcweir virtual void Paint( const Rectangle& rRect ); 129cdf0e10cSrcweir }; 130cdf0e10cSrcweir 131cdf0e10cSrcweir //---------------------------------------------------------------------------------- 132cdf0e10cSrcweir 133cdf0e10cSrcweir static bool g_failure=false; 134cdf0e10cSrcweir 135cdf0e10cSrcweir void test( bool bResult, const char* msg ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir if( bResult ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir OSL_TRACE("Testing: %s - PASSED", msg); 140cdf0e10cSrcweir } 141cdf0e10cSrcweir else 142cdf0e10cSrcweir { 143cdf0e10cSrcweir g_failure = true; 144cdf0e10cSrcweir OSL_TRACE("Testing: %s - FAILED", msg); 145cdf0e10cSrcweir } 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir //---------------------------------------------------------------------------------- 149cdf0e10cSrcweir 150cdf0e10cSrcweir bool rangeCheck( const rendering::RGBColor& rColor ) 151cdf0e10cSrcweir { 152cdf0e10cSrcweir return rColor.Red < 0.0 || rColor.Red > 1.0 || 153cdf0e10cSrcweir rColor.Green < 0.0 || rColor.Green > 1.0 || 154cdf0e10cSrcweir rColor.Blue < 0.0 || rColor.Blue > 1.0; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir //---------------------------------------------------------------------------------- 158cdf0e10cSrcweir 159cdf0e10cSrcweir void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, 160cdf0e10cSrcweir const char* msg, 161cdf0e10cSrcweir int nOriginalDepth ) 162cdf0e10cSrcweir { 163cdf0e10cSrcweir OSL_TRACE("-------------------------"); 164cdf0e10cSrcweir OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth); 165cdf0e10cSrcweir 166cdf0e10cSrcweir BitmapEx aContainedBmpEx( xBmp->getBitmapEx() ); 167cdf0e10cSrcweir Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() ); 168cdf0e10cSrcweir int nDepth = nOriginalDepth; 169cdf0e10cSrcweir 170cdf0e10cSrcweir { 171cdf0e10cSrcweir ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(), 172cdf0e10cSrcweir aContainedBmp ); 173cdf0e10cSrcweir nDepth = pAcc->GetBitCount(); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir 176cdf0e10cSrcweir test( aContainedBmp.GetSizePixel() == Size(200,200), 177cdf0e10cSrcweir "Original bitmap size" ); 178cdf0e10cSrcweir 179cdf0e10cSrcweir test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200, 180cdf0e10cSrcweir "Original bitmap size via API" ); 181cdf0e10cSrcweir 182cdf0e10cSrcweir test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(), 183cdf0e10cSrcweir "Correct alpha state" ); 184cdf0e10cSrcweir 185cdf0e10cSrcweir test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(), 186cdf0e10cSrcweir "getScaledBitmap()" ); 187cdf0e10cSrcweir 188cdf0e10cSrcweir rendering::IntegerBitmapLayout aLayout; 189cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1)); 190cdf0e10cSrcweir 191cdf0e10cSrcweir const sal_Int32 nExpectedBitsPerPixel( 192cdf0e10cSrcweir aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth); 193cdf0e10cSrcweir test( aLayout.ScanLines == 1, 194cdf0e10cSrcweir "# scanlines" ); 195cdf0e10cSrcweir test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8, 196cdf0e10cSrcweir "# scanline bytes" ); 197cdf0e10cSrcweir test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 || 198cdf0e10cSrcweir aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8, 199cdf0e10cSrcweir "# scanline stride" ); 200cdf0e10cSrcweir test( aLayout.PlaneStride == 0, 201cdf0e10cSrcweir "# plane stride" ); 202cdf0e10cSrcweir 203cdf0e10cSrcweir test( aLayout.ColorSpace.is(), 204cdf0e10cSrcweir "Color space there" ); 205cdf0e10cSrcweir 206cdf0e10cSrcweir test( aLayout.Palette.is() == (nDepth <= 8), 207cdf0e10cSrcweir "Palette existance conforms to bitmap" ); 208cdf0e10cSrcweir 209cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) ); 210cdf0e10cSrcweir 211cdf0e10cSrcweir test( aPixelData2.getLength() == aPixelData.getLength(), 212cdf0e10cSrcweir "getData and getPixel return same amount of data" ); 213cdf0e10cSrcweir 214cdf0e10cSrcweir aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1)); 215cdf0e10cSrcweir test( aLayout.ScanLines == 1, 216cdf0e10cSrcweir "# scanlines" ); 217cdf0e10cSrcweir test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8, 218cdf0e10cSrcweir "# scanline bytes" ); 219cdf0e10cSrcweir test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 || 220cdf0e10cSrcweir aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8, 221cdf0e10cSrcweir "# scanline stride" ); 222cdf0e10cSrcweir 223cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData ); 224cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData ); 225cdf0e10cSrcweir 226cdf0e10cSrcweir const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() ); 227cdf0e10cSrcweir const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() ); 228cdf0e10cSrcweir const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() ); 229cdf0e10cSrcweir std::pair<const rendering::RGBColor*, 230cdf0e10cSrcweir const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart ); 231cdf0e10cSrcweir test( aRes.first == pRGBEnd, 232cdf0e10cSrcweir "argb and rgb colors are equal" ); 233cdf0e10cSrcweir 234cdf0e10cSrcweir test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd, 235cdf0e10cSrcweir "rgb colors are within [0,1] range" ); 236cdf0e10cSrcweir 237cdf0e10cSrcweir test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0, 238cdf0e10cSrcweir "First pixel is white" ); 239cdf0e10cSrcweir test( pARGBStart[1].Alpha == 1.0, 240cdf0e10cSrcweir "Second pixel is opaque" ); 241cdf0e10cSrcweir if( aContainedBmpEx.IsTransparent() ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir test( pARGBStart[0].Alpha == 0.0, 244cdf0e10cSrcweir "First pixel is fully transparent" ); 245cdf0e10cSrcweir } 246cdf0e10cSrcweir 247cdf0e10cSrcweir test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0, 248cdf0e10cSrcweir "Second pixel is black" ); 249cdf0e10cSrcweir 250cdf0e10cSrcweir if( nOriginalDepth > 8 ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir const Color aCol(COL_GREEN); 253cdf0e10cSrcweir test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) && 254cdf0e10cSrcweir pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) && 255cdf0e10cSrcweir pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()), 256cdf0e10cSrcweir "Sixth pixel is green" ); 257cdf0e10cSrcweir } 258cdf0e10cSrcweir else if( nDepth <= 8 ) 259cdf0e10cSrcweir { 260cdf0e10cSrcweir uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette(); 261cdf0e10cSrcweir test( xPal.is(), 262cdf0e10cSrcweir "8bit or less: needs palette" ); 263cdf0e10cSrcweir test( xPal->getNumberOfEntries() == 1L << nOriginalDepth, 264cdf0e10cSrcweir "Palette has correct entry count" ); 265cdf0e10cSrcweir uno::Sequence<double> aIndex; 266cdf0e10cSrcweir test( xPal->setIndex(aIndex,sal_True,0) == sal_False, 267cdf0e10cSrcweir "Palette is read-only" ); 268cdf0e10cSrcweir test( xPal->getIndex(aIndex,0), 269cdf0e10cSrcweir "Palette entry 0 is opaque" ); 270cdf0e10cSrcweir test( xPal->getColorSpace().is(), 271cdf0e10cSrcweir "Palette has a valid color space" ); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0, 275cdf0e10cSrcweir "150th pixel is white" ); 276cdf0e10cSrcweir 277cdf0e10cSrcweir if( nOriginalDepth > 8 ) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() ); 280cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aARGBColor(1); 281cdf0e10cSrcweir uno::Sequence<rendering::RGBColor> aRGBColor(1); 282cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixel3, aPixel4; 283cdf0e10cSrcweir 284cdf0e10cSrcweir const Color aCol(COL_GREEN); 285cdf0e10cSrcweir aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); 286cdf0e10cSrcweir aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); 287cdf0e10cSrcweir aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); 288cdf0e10cSrcweir aARGBColor[0].Alpha = 1.0; 289cdf0e10cSrcweir 290cdf0e10cSrcweir aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); 291cdf0e10cSrcweir aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); 292cdf0e10cSrcweir aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); 293cdf0e10cSrcweir 294cdf0e10cSrcweir aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor ); 295cdf0e10cSrcweir aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) ); 296cdf0e10cSrcweir test( aPixel3 == aPixel4, 297cdf0e10cSrcweir "Green pixel from bitmap matches with manually converted green pixel" ); 298cdf0e10cSrcweir 299cdf0e10cSrcweir if( !aContainedBmpEx.IsTransparent() ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor ); 302cdf0e10cSrcweir test( aPixel3 == aPixel4, 303cdf0e10cSrcweir "Green pixel from bitmap matches with manually RGB-converted green pixel" ); 304cdf0e10cSrcweir } 305cdf0e10cSrcweir } 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir //---------------------------------------------------------------------------------- 309cdf0e10cSrcweir 310cdf0e10cSrcweir void checkBitmapImport( const rtl::Reference<VclCanvasBitmap>& xBmp, 311cdf0e10cSrcweir const char* msg, 312cdf0e10cSrcweir int nOriginalDepth ) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir OSL_TRACE("-------------------------"); 315cdf0e10cSrcweir OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth); 316cdf0e10cSrcweir 317cdf0e10cSrcweir BitmapEx aContainedBmpEx( xBmp->getBitmapEx() ); 318cdf0e10cSrcweir Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() ); 319cdf0e10cSrcweir int nDepth = nOriginalDepth; 320cdf0e10cSrcweir 321cdf0e10cSrcweir { 322cdf0e10cSrcweir ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(), 323cdf0e10cSrcweir aContainedBmp ); 324cdf0e10cSrcweir nDepth = pAcc->GetBitCount(); 325cdf0e10cSrcweir } 326cdf0e10cSrcweir 327cdf0e10cSrcweir test( aContainedBmp.GetSizePixel() == Size(200,200), 328cdf0e10cSrcweir "Original bitmap size" ); 329cdf0e10cSrcweir 330cdf0e10cSrcweir test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200, 331cdf0e10cSrcweir "Original bitmap size via API" ); 332cdf0e10cSrcweir 333cdf0e10cSrcweir test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(), 334cdf0e10cSrcweir "Correct alpha state" ); 335cdf0e10cSrcweir 336cdf0e10cSrcweir test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(), 337cdf0e10cSrcweir "getScaledBitmap()" ); 338cdf0e10cSrcweir 339cdf0e10cSrcweir rendering::IntegerBitmapLayout aLayout; 340cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1)); 341cdf0e10cSrcweir 342cdf0e10cSrcweir const sal_Int32 nExpectedBitsPerPixel( 343cdf0e10cSrcweir aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth); 344cdf0e10cSrcweir test( aLayout.ScanLines == 1, 345cdf0e10cSrcweir "# scanlines" ); 346cdf0e10cSrcweir test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8, 347cdf0e10cSrcweir "# scanline bytes" ); 348cdf0e10cSrcweir test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 || 349cdf0e10cSrcweir aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8, 350cdf0e10cSrcweir "# scanline stride" ); 351cdf0e10cSrcweir test( aLayout.PlaneStride == 0, 352cdf0e10cSrcweir "# plane stride" ); 353cdf0e10cSrcweir 354cdf0e10cSrcweir test( aLayout.ColorSpace.is(), 355cdf0e10cSrcweir "Color space there" ); 356cdf0e10cSrcweir 357cdf0e10cSrcweir test( aLayout.Palette.is() == (nDepth <= 8), 358cdf0e10cSrcweir "Palette existance conforms to bitmap" ); 359cdf0e10cSrcweir 360cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) ); 361cdf0e10cSrcweir 362cdf0e10cSrcweir test( aPixelData2.getLength() == aPixelData.getLength(), 363cdf0e10cSrcweir "getData and getPixel return same amount of data" ); 364cdf0e10cSrcweir 365cdf0e10cSrcweir aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1)); 366cdf0e10cSrcweir test( aLayout.ScanLines == 1, 367cdf0e10cSrcweir "# scanlines" ); 368cdf0e10cSrcweir test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8, 369cdf0e10cSrcweir "# scanline bytes" ); 370cdf0e10cSrcweir test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 || 371cdf0e10cSrcweir aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8, 372cdf0e10cSrcweir "# scanline stride" ); 373cdf0e10cSrcweir 374cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData ); 375cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData ); 376cdf0e10cSrcweir 377cdf0e10cSrcweir const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() ); 378cdf0e10cSrcweir const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() ); 379cdf0e10cSrcweir const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() ); 380cdf0e10cSrcweir std::pair<const rendering::RGBColor*, 381cdf0e10cSrcweir const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart ); 382cdf0e10cSrcweir test( aRes.first == pRGBEnd, 383cdf0e10cSrcweir "argb and rgb colors are equal" ); 384cdf0e10cSrcweir 385cdf0e10cSrcweir test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd, 386cdf0e10cSrcweir "rgb colors are within [0,1] range" ); 387cdf0e10cSrcweir 388cdf0e10cSrcweir test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0, 389cdf0e10cSrcweir "First pixel is white" ); 390cdf0e10cSrcweir test( pARGBStart[1].Alpha == 1.0, 391cdf0e10cSrcweir "Second pixel is opaque" ); 392cdf0e10cSrcweir if( aContainedBmpEx.IsTransparent() ) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir test( pARGBStart[0].Alpha == 0.0, 395cdf0e10cSrcweir "First pixel is fully transparent" ); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0, 399cdf0e10cSrcweir "Second pixel is black" ); 400cdf0e10cSrcweir 401cdf0e10cSrcweir if( nOriginalDepth > 8 ) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir const Color aCol(COL_GREEN); 404cdf0e10cSrcweir test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) && 405cdf0e10cSrcweir pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) && 406cdf0e10cSrcweir pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()), 407cdf0e10cSrcweir "Sixth pixel is green" ); 408cdf0e10cSrcweir } 409cdf0e10cSrcweir else if( nDepth <= 8 ) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette(); 412cdf0e10cSrcweir test( xPal.is(), 413cdf0e10cSrcweir "8bit or less: needs palette" ); 414cdf0e10cSrcweir test( xPal->getNumberOfEntries() == 1L << nOriginalDepth, 415cdf0e10cSrcweir "Palette has correct entry count" ); 416cdf0e10cSrcweir uno::Sequence<double> aIndex; 417cdf0e10cSrcweir test( xPal->setIndex(aIndex,sal_True,0) == sal_False, 418cdf0e10cSrcweir "Palette is read-only" ); 419cdf0e10cSrcweir test( xPal->getIndex(aIndex,0), 420cdf0e10cSrcweir "Palette entry 0 is opaque" ); 421cdf0e10cSrcweir test( xPal->getColorSpace().is(), 422cdf0e10cSrcweir "Palette has a valid color space" ); 423cdf0e10cSrcweir } 424cdf0e10cSrcweir 425cdf0e10cSrcweir test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0, 426cdf0e10cSrcweir "150th pixel is white" ); 427cdf0e10cSrcweir 428cdf0e10cSrcweir if( nOriginalDepth > 8 ) 429cdf0e10cSrcweir { 430cdf0e10cSrcweir const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() ); 431cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aARGBColor(1); 432cdf0e10cSrcweir uno::Sequence<rendering::RGBColor> aRGBColor(1); 433cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixel3, aPixel4; 434cdf0e10cSrcweir 435cdf0e10cSrcweir const Color aCol(COL_GREEN); 436cdf0e10cSrcweir aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); 437cdf0e10cSrcweir aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); 438cdf0e10cSrcweir aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); 439cdf0e10cSrcweir aARGBColor[0].Alpha = 1.0; 440cdf0e10cSrcweir 441cdf0e10cSrcweir aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed()); 442cdf0e10cSrcweir aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen()); 443cdf0e10cSrcweir aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue()); 444cdf0e10cSrcweir 445cdf0e10cSrcweir aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor ); 446cdf0e10cSrcweir aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) ); 447cdf0e10cSrcweir test( aPixel3 == aPixel4, 448cdf0e10cSrcweir "Green pixel from bitmap matches with manually converted green pixel" ); 449cdf0e10cSrcweir 450cdf0e10cSrcweir if( !aContainedBmpEx.IsTransparent() ) 451cdf0e10cSrcweir { 452cdf0e10cSrcweir aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor ); 453cdf0e10cSrcweir test( aPixel3 == aPixel4, 454cdf0e10cSrcweir "Green pixel from bitmap matches with manually RGB-converted green pixel" ); 455cdf0e10cSrcweir } 456cdf0e10cSrcweir } 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir //---------------------------------------------------------------------------------- 460cdf0e10cSrcweir 461cdf0e10cSrcweir class TestBitmap : public cppu::WeakImplHelper3< rendering::XIntegerReadOnlyBitmap, 462cdf0e10cSrcweir rendering::XBitmapPalette, 463cdf0e10cSrcweir rendering::XIntegerBitmapColorSpace > 464cdf0e10cSrcweir { 465cdf0e10cSrcweir private: 466cdf0e10cSrcweir geometry::IntegerSize2D maSize; 467cdf0e10cSrcweir uno::Sequence<sal_Int8> maComponentTags; 468cdf0e10cSrcweir uno::Sequence<sal_Int32> maComponentBitCounts; 469cdf0e10cSrcweir rendering::IntegerBitmapLayout maLayout; 470cdf0e10cSrcweir const sal_Int32 mnBitsPerPixel; 471cdf0e10cSrcweir 472cdf0e10cSrcweir // XBitmap 473cdf0e10cSrcweir virtual geometry::IntegerSize2D SAL_CALL getSize() throw (uno::RuntimeException) { return maSize; } 474cdf0e10cSrcweir virtual ::sal_Bool SAL_CALL hasAlpha( ) throw (uno::RuntimeException) { return mnBitsPerPixel != 8; } 475cdf0e10cSrcweir virtual uno::Reference< rendering::XBitmap > SAL_CALL getScaledBitmap( const geometry::RealSize2D&, 476cdf0e10cSrcweir sal_Bool ) throw (uno::RuntimeException) { return this; } 477cdf0e10cSrcweir 478cdf0e10cSrcweir // XIntegerReadOnlyBitmap 479cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL getData( rendering::IntegerBitmapLayout& bitmapLayout, 480cdf0e10cSrcweir const geometry::IntegerRectangle2D& rect ) throw (lang::IndexOutOfBoundsException, 481cdf0e10cSrcweir rendering::VolatileContentDestroyedException, uno::RuntimeException) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir test( rect.X1 >= 0, "X1 within bounds" ); 484cdf0e10cSrcweir test( rect.Y1 >= 0, "Y1 within bounds" ); 485cdf0e10cSrcweir test( rect.X2 <= maSize.Width, "X2 within bounds" ); 486cdf0e10cSrcweir test( rect.Y2 <= maSize.Height, "Y2 within bounds" ); 487cdf0e10cSrcweir 488cdf0e10cSrcweir bitmapLayout = getMemoryLayout(); 489cdf0e10cSrcweir 490cdf0e10cSrcweir const sal_Int32 nWidth = rect.X2-rect.X1; 491cdf0e10cSrcweir const sal_Int32 nHeight = rect.Y2-rect.Y1; 492cdf0e10cSrcweir const sal_Int32 nScanlineLen = (nWidth * mnBitsPerPixel + 7)/8; 493cdf0e10cSrcweir uno::Sequence<sal_Int8> aRes( nScanlineLen * nHeight ); 494cdf0e10cSrcweir sal_Int8* pOut = aRes.getArray(); 495cdf0e10cSrcweir 496cdf0e10cSrcweir bitmapLayout.ScanLines = nHeight; 497cdf0e10cSrcweir bitmapLayout.ScanLineBytes = 498cdf0e10cSrcweir bitmapLayout.ScanLineStride= nScanlineLen; 499cdf0e10cSrcweir 500cdf0e10cSrcweir if( mnBitsPerPixel == 8 ) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir for( sal_Int32 y=0; y<nHeight; ++y ) 503cdf0e10cSrcweir { 504cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 505cdf0e10cSrcweir pOut[ y*nScanlineLen + x ] = sal_Int8(x); 506cdf0e10cSrcweir } 507cdf0e10cSrcweir } 508cdf0e10cSrcweir else 509cdf0e10cSrcweir { 510cdf0e10cSrcweir for( sal_Int32 y=0; y<nHeight; ++y ) 511cdf0e10cSrcweir { 512cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 513cdf0e10cSrcweir { 514cdf0e10cSrcweir pOut[ y*nScanlineLen + 4*x ] = sal_Int8(rect.X1); 515cdf0e10cSrcweir pOut[ y*nScanlineLen + 4*x + 1 ] = sal_Int8(rect.Y2); 516cdf0e10cSrcweir pOut[ y*nScanlineLen + 4*x + 2 ] = sal_Int8(x); 517cdf0e10cSrcweir pOut[ y*nScanlineLen + 4*x + 3 ] = sal_Int8(rect.Y1); 518cdf0e10cSrcweir } 519cdf0e10cSrcweir } 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir return aRes; 523cdf0e10cSrcweir } 524cdf0e10cSrcweir 525cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL getPixel( rendering::IntegerBitmapLayout&, 526cdf0e10cSrcweir const geometry::IntegerPoint2D& ) throw (lang::IndexOutOfBoundsException, 527cdf0e10cSrcweir rendering::VolatileContentDestroyedException, uno::RuntimeException) 528cdf0e10cSrcweir { 529cdf0e10cSrcweir test(false, "Method not implemented"); 530cdf0e10cSrcweir return uno::Sequence< sal_Int8 >(); 531cdf0e10cSrcweir } 532cdf0e10cSrcweir 533cdf0e10cSrcweir virtual uno::Reference< rendering::XBitmapPalette > SAL_CALL getPalette( ) throw (uno::RuntimeException) 534cdf0e10cSrcweir { 535cdf0e10cSrcweir uno::Reference< XBitmapPalette > aRet; 536cdf0e10cSrcweir if( mnBitsPerPixel == 8 ) 537cdf0e10cSrcweir aRet.set(this); 538cdf0e10cSrcweir return aRet; 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir virtual rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout( ) throw (uno::RuntimeException) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir rendering::IntegerBitmapLayout aLayout( maLayout ); 544cdf0e10cSrcweir 545cdf0e10cSrcweir const sal_Int32 nScanlineLen = (maSize.Width * mnBitsPerPixel + 7)/8; 546cdf0e10cSrcweir 547cdf0e10cSrcweir aLayout.ScanLines = maSize.Height; 548cdf0e10cSrcweir aLayout.ScanLineBytes = 549cdf0e10cSrcweir aLayout.ScanLineStride= nScanlineLen; 550cdf0e10cSrcweir aLayout.Palette = getPalette(); 551cdf0e10cSrcweir aLayout.ColorSpace.set( this ); 552cdf0e10cSrcweir 553cdf0e10cSrcweir return aLayout; 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir // XBitmapPalette 557cdf0e10cSrcweir virtual sal_Int32 SAL_CALL getNumberOfEntries() throw (uno::RuntimeException) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir test( getPalette().is(), 560cdf0e10cSrcweir "Got palette interface call without handing out palette?!" ); 561cdf0e10cSrcweir 562cdf0e10cSrcweir return 255; 563cdf0e10cSrcweir } 564cdf0e10cSrcweir 565cdf0e10cSrcweir virtual ::sal_Bool SAL_CALL getIndex( uno::Sequence< double >& entry, 566cdf0e10cSrcweir ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, 567cdf0e10cSrcweir uno::RuntimeException) 568cdf0e10cSrcweir { 569cdf0e10cSrcweir test( getPalette().is(), 570cdf0e10cSrcweir "Got palette interface call without handing out palette?!" ); 571cdf0e10cSrcweir test( nIndex >= 0 && nIndex < 256, 572cdf0e10cSrcweir "Index out of range" ); 573cdf0e10cSrcweir entry = colorToStdColorSpaceSequence( 574cdf0e10cSrcweir Color(UINT8(nIndex), 575cdf0e10cSrcweir UINT8(nIndex), 576cdf0e10cSrcweir UINT8(nIndex)) ); 577cdf0e10cSrcweir 578cdf0e10cSrcweir return sal_True; // no palette transparency here. 579cdf0e10cSrcweir } 580cdf0e10cSrcweir 581cdf0e10cSrcweir virtual ::sal_Bool SAL_CALL setIndex( const uno::Sequence< double >&, 582cdf0e10cSrcweir ::sal_Bool, 583cdf0e10cSrcweir ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, 584cdf0e10cSrcweir lang::IllegalArgumentException, 585cdf0e10cSrcweir uno::RuntimeException) 586cdf0e10cSrcweir { 587cdf0e10cSrcweir test( getPalette().is(), 588cdf0e10cSrcweir "Got palette interface call without handing out palette?!" ); 589cdf0e10cSrcweir test( nIndex >= 0 && nIndex < 256, 590cdf0e10cSrcweir "Index out of range" ); 591cdf0e10cSrcweir return sal_False; 592cdf0e10cSrcweir } 593cdf0e10cSrcweir 594cdf0e10cSrcweir struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, 595cdf0e10cSrcweir PaletteColorSpaceHolder> 596cdf0e10cSrcweir { 597cdf0e10cSrcweir uno::Reference<rendering::XColorSpace> operator()() 598cdf0e10cSrcweir { 599cdf0e10cSrcweir return vcl::unotools::createStandardColorSpace(); 600cdf0e10cSrcweir } 601cdf0e10cSrcweir }; 602cdf0e10cSrcweir 603cdf0e10cSrcweir virtual uno::Reference< rendering::XColorSpace > SAL_CALL getColorSpace( ) throw (uno::RuntimeException) 604cdf0e10cSrcweir { 605cdf0e10cSrcweir // this is the method from XBitmapPalette. Return palette color 606cdf0e10cSrcweir // space here 607cdf0e10cSrcweir return PaletteColorSpaceHolder::get(); 608cdf0e10cSrcweir } 609cdf0e10cSrcweir 610cdf0e10cSrcweir // XIntegerBitmapColorSpace 611cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException) 612cdf0e10cSrcweir { 613cdf0e10cSrcweir return rendering::ColorSpaceType::RGB; 614cdf0e10cSrcweir } 615cdf0e10cSrcweir 616cdf0e10cSrcweir virtual uno::Sequence< sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir return maComponentTags; 619cdf0e10cSrcweir } 620cdf0e10cSrcweir 621cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException) 622cdf0e10cSrcweir { 623cdf0e10cSrcweir return rendering::RenderingIntent::PERCEPTUAL; 624cdf0e10cSrcweir } 625cdf0e10cSrcweir 626cdf0e10cSrcweir virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException) 627cdf0e10cSrcweir { 628cdf0e10cSrcweir test(false, "Method not implemented"); 629cdf0e10cSrcweir return uno::Sequence< ::beans::PropertyValue >(); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir 632cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >&, 633cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& ) throw (uno::RuntimeException) 634cdf0e10cSrcweir { 635cdf0e10cSrcweir test(false, "Method not implemented"); 636cdf0e10cSrcweir return uno::Sequence< double >(); 637cdf0e10cSrcweir } 638cdf0e10cSrcweir 639cdf0e10cSrcweir virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, 640cdf0e10cSrcweir uno::RuntimeException) 641cdf0e10cSrcweir { 642cdf0e10cSrcweir test(false, "Method not implemented"); 643cdf0e10cSrcweir return uno::Sequence< rendering::RGBColor >(); 644cdf0e10cSrcweir } 645cdf0e10cSrcweir 646cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, 647cdf0e10cSrcweir uno::RuntimeException) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir test(false, "Method not implemented"); 650cdf0e10cSrcweir return uno::Sequence< rendering::ARGBColor >(); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException, 654cdf0e10cSrcweir uno::RuntimeException) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir test(false, "Method not implemented"); 657cdf0e10cSrcweir return uno::Sequence< rendering::ARGBColor >(); 658cdf0e10cSrcweir } 659cdf0e10cSrcweir 660cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException, 661cdf0e10cSrcweir uno::RuntimeException) 662cdf0e10cSrcweir { 663cdf0e10cSrcweir test(false, "Method not implemented"); 664cdf0e10cSrcweir return uno::Sequence< double >(); 665cdf0e10cSrcweir } 666cdf0e10cSrcweir 667cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, 668cdf0e10cSrcweir uno::RuntimeException) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir test(false, "This method is not expected to be called!"); 671cdf0e10cSrcweir return uno::Sequence< double >(); 672cdf0e10cSrcweir } 673cdf0e10cSrcweir 674cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, 675cdf0e10cSrcweir uno::RuntimeException) 676cdf0e10cSrcweir { 677cdf0e10cSrcweir test(false, "This method is not expected to be called!"); 678cdf0e10cSrcweir return uno::Sequence< double >(); 679cdf0e10cSrcweir } 680cdf0e10cSrcweir 681cdf0e10cSrcweir virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException) 682cdf0e10cSrcweir { 683cdf0e10cSrcweir return mnBitsPerPixel; 684cdf0e10cSrcweir } 685cdf0e10cSrcweir 686cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException) 687cdf0e10cSrcweir { 688cdf0e10cSrcweir return maComponentBitCounts; 689cdf0e10cSrcweir } 690cdf0e10cSrcweir 691cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException) 692cdf0e10cSrcweir { 693cdf0e10cSrcweir return util::Endianness::LITTLE; 694cdf0e10cSrcweir } 695cdf0e10cSrcweir 696cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& , 697cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& ) throw (lang::IllegalArgumentException, 698cdf0e10cSrcweir uno::RuntimeException) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir test(false, "Method not implemented"); 701cdf0e10cSrcweir return uno::Sequence< double >(); 702cdf0e10cSrcweir } 703cdf0e10cSrcweir 704cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& , 705cdf0e10cSrcweir const uno::Reference< rendering::XIntegerBitmapColorSpace >& ) throw (lang::IllegalArgumentException, 706cdf0e10cSrcweir uno::RuntimeException) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir test(false, "Method not implemented"); 709cdf0e10cSrcweir return uno::Sequence< sal_Int8 >(); 710cdf0e10cSrcweir } 711cdf0e10cSrcweir 712cdf0e10cSrcweir virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, 713cdf0e10cSrcweir uno::RuntimeException) 714cdf0e10cSrcweir { 715cdf0e10cSrcweir const uno::Sequence< rendering::ARGBColor > aTemp( convertIntegerToARGB(deviceColor) ); 716cdf0e10cSrcweir const sal_Size nLen(aTemp.getLength()); 717cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRes( nLen ); 718cdf0e10cSrcweir rendering::RGBColor* pOut = aRes.getArray(); 719cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 720cdf0e10cSrcweir { 721cdf0e10cSrcweir *pOut++ = rendering::RGBColor(aTemp[i].Red, 722cdf0e10cSrcweir aTemp[i].Green, 723cdf0e10cSrcweir aTemp[i].Blue); 724cdf0e10cSrcweir } 725cdf0e10cSrcweir 726cdf0e10cSrcweir return aRes; 727cdf0e10cSrcweir } 728cdf0e10cSrcweir 729cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, 730cdf0e10cSrcweir uno::RuntimeException) 731cdf0e10cSrcweir { 732cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 733cdf0e10cSrcweir const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4); 734cdf0e10cSrcweir test(nLen%nBytesPerPixel==0, 735cdf0e10cSrcweir "number of channels no multiple of pixel element count"); 736cdf0e10cSrcweir 737cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel ); 738cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 739cdf0e10cSrcweir 740cdf0e10cSrcweir if( getPalette().is() ) 741cdf0e10cSrcweir { 742cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 745cdf0e10cSrcweir 1.0, 746cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i]), 747cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i]), 748cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i])); 749cdf0e10cSrcweir } 750cdf0e10cSrcweir } 751cdf0e10cSrcweir else 752cdf0e10cSrcweir { 753cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 756cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i+3]), 757cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i+0]), 758cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i+1]), 759cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i+2])); 760cdf0e10cSrcweir } 761cdf0e10cSrcweir } 762cdf0e10cSrcweir 763cdf0e10cSrcweir return aRes; 764cdf0e10cSrcweir } 765cdf0e10cSrcweir 766cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, 767cdf0e10cSrcweir uno::RuntimeException) 768cdf0e10cSrcweir { 769cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 770cdf0e10cSrcweir const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4); 771cdf0e10cSrcweir test(nLen%nBytesPerPixel==0, 772cdf0e10cSrcweir "number of channels no multiple of pixel element count"); 773cdf0e10cSrcweir 774cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel ); 775cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 776cdf0e10cSrcweir 777cdf0e10cSrcweir if( getPalette().is() ) 778cdf0e10cSrcweir { 779cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 780cdf0e10cSrcweir { 781cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 782cdf0e10cSrcweir 1.0, 783cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i]), 784cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i]), 785cdf0e10cSrcweir vcl::unotools::toDoubleColor(deviceColor[i])); 786cdf0e10cSrcweir } 787cdf0e10cSrcweir } 788cdf0e10cSrcweir else 789cdf0e10cSrcweir { 790cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 791cdf0e10cSrcweir { 792cdf0e10cSrcweir const double fAlpha=vcl::unotools::toDoubleColor(deviceColor[i+3]); 793cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 794cdf0e10cSrcweir fAlpha, 795cdf0e10cSrcweir fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+0]), 796cdf0e10cSrcweir fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+1]), 797cdf0e10cSrcweir fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+2])); 798cdf0e10cSrcweir } 799cdf0e10cSrcweir } 800cdf0e10cSrcweir 801cdf0e10cSrcweir return aRes; 802cdf0e10cSrcweir } 803cdf0e10cSrcweir 804cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException, 805cdf0e10cSrcweir uno::RuntimeException) 806cdf0e10cSrcweir { 807cdf0e10cSrcweir test(false, "Method not implemented"); 808cdf0e10cSrcweir return uno::Sequence< sal_Int8 >(); 809cdf0e10cSrcweir } 810cdf0e10cSrcweir 811cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, 812cdf0e10cSrcweir uno::RuntimeException) 813cdf0e10cSrcweir { 814cdf0e10cSrcweir test(false, "Method not implemented"); 815cdf0e10cSrcweir return uno::Sequence< sal_Int8 >(); 816cdf0e10cSrcweir } 817cdf0e10cSrcweir 818cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException, 819cdf0e10cSrcweir uno::RuntimeException) 820cdf0e10cSrcweir { 821cdf0e10cSrcweir test(false, "Method not implemented"); 822cdf0e10cSrcweir return uno::Sequence< sal_Int8 >(); 823cdf0e10cSrcweir } 824cdf0e10cSrcweir 825cdf0e10cSrcweir public: 826cdf0e10cSrcweir TestBitmap( const geometry::IntegerSize2D& rSize, bool bPalette ) : 827cdf0e10cSrcweir maSize(rSize), 828cdf0e10cSrcweir maComponentTags(), 829cdf0e10cSrcweir maComponentBitCounts(), 830cdf0e10cSrcweir maLayout(), 831cdf0e10cSrcweir mnBitsPerPixel( bPalette ? 8 : 32 ) 832cdf0e10cSrcweir { 833cdf0e10cSrcweir if( bPalette ) 834cdf0e10cSrcweir { 835cdf0e10cSrcweir maComponentTags.realloc(1); 836cdf0e10cSrcweir maComponentTags[0] = rendering::ColorComponentTag::INDEX; 837cdf0e10cSrcweir 838cdf0e10cSrcweir maComponentBitCounts.realloc(1); 839cdf0e10cSrcweir maComponentBitCounts[0] = 8; 840cdf0e10cSrcweir } 841cdf0e10cSrcweir else 842cdf0e10cSrcweir { 843cdf0e10cSrcweir maComponentTags.realloc(4); 844cdf0e10cSrcweir sal_Int8* pTags = maComponentTags.getArray(); 845cdf0e10cSrcweir pTags[0] = rendering::ColorComponentTag::RGB_BLUE; 846cdf0e10cSrcweir pTags[1] = rendering::ColorComponentTag::RGB_GREEN; 847cdf0e10cSrcweir pTags[2] = rendering::ColorComponentTag::RGB_RED; 848cdf0e10cSrcweir pTags[3] = rendering::ColorComponentTag::ALPHA; 849cdf0e10cSrcweir 850cdf0e10cSrcweir maComponentBitCounts.realloc(4); 851cdf0e10cSrcweir sal_Int32* pCounts = maComponentBitCounts.getArray(); 852cdf0e10cSrcweir pCounts[0] = 8; 853cdf0e10cSrcweir pCounts[1] = 8; 854cdf0e10cSrcweir pCounts[2] = 8; 855cdf0e10cSrcweir pCounts[3] = 8; 856cdf0e10cSrcweir } 857cdf0e10cSrcweir 858cdf0e10cSrcweir maLayout.ScanLines = 0; 859cdf0e10cSrcweir maLayout.ScanLineBytes = 0; 860cdf0e10cSrcweir maLayout.ScanLineStride = 0; 861cdf0e10cSrcweir maLayout.PlaneStride = 0; 862cdf0e10cSrcweir maLayout.ColorSpace.clear(); 863cdf0e10cSrcweir maLayout.Palette.clear(); 864cdf0e10cSrcweir maLayout.IsMsbFirst = sal_False; 865cdf0e10cSrcweir } 866cdf0e10cSrcweir }; 867cdf0e10cSrcweir 868cdf0e10cSrcweir 869cdf0e10cSrcweir //---------------------------------------------------------------------------------- 870cdf0e10cSrcweir 871cdf0e10cSrcweir void TestWindow::Paint( const Rectangle& ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir static sal_Int8 lcl_depths[]={1,4,8,16,24}; 874cdf0e10cSrcweir 875cdf0e10cSrcweir try 876cdf0e10cSrcweir { 877cdf0e10cSrcweir // Testing VclCanvasBitmap wrapper 878cdf0e10cSrcweir // =============================== 879cdf0e10cSrcweir 880cdf0e10cSrcweir for( unsigned int i=0; i<sizeof(lcl_depths)/sizeof(*lcl_depths); ++i ) 881cdf0e10cSrcweir { 882cdf0e10cSrcweir const sal_Int8 nDepth( lcl_depths[i] ); 883cdf0e10cSrcweir Bitmap aBitmap(Size(200,200),nDepth); 884cdf0e10cSrcweir aBitmap.Erase(COL_WHITE); 885cdf0e10cSrcweir { 886cdf0e10cSrcweir ScopedBitmapWriteAccess pAcc(aBitmap.AcquireWriteAccess(), 887cdf0e10cSrcweir aBitmap); 888cdf0e10cSrcweir if( pAcc.get() ) 889cdf0e10cSrcweir { 890cdf0e10cSrcweir BitmapColor aBlack(0); 891cdf0e10cSrcweir BitmapColor aWhite(0); 892cdf0e10cSrcweir if( pAcc->HasPalette() ) 893cdf0e10cSrcweir { 894cdf0e10cSrcweir aBlack.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(0,0,0))) ); 895cdf0e10cSrcweir aWhite.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(255,255,255))) ); 896cdf0e10cSrcweir } 897cdf0e10cSrcweir else 898cdf0e10cSrcweir { 899cdf0e10cSrcweir aBlack = Color(COL_BLACK); 900cdf0e10cSrcweir aWhite = Color(COL_WHITE); 901cdf0e10cSrcweir } 902cdf0e10cSrcweir pAcc->SetFillColor(COL_GREEN); 903cdf0e10cSrcweir pAcc->FillRect(Rectangle(0,0,100,100)); 904cdf0e10cSrcweir pAcc->SetPixel(0,0,aWhite); 905cdf0e10cSrcweir pAcc->SetPixel(0,1,aBlack); 906cdf0e10cSrcweir pAcc->SetPixel(0,2,aWhite); 907cdf0e10cSrcweir } 908cdf0e10cSrcweir } 909cdf0e10cSrcweir 910cdf0e10cSrcweir rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(aBitmap) ); 911cdf0e10cSrcweir 912cdf0e10cSrcweir checkCanvasBitmap( xBmp, "single bitmap", nDepth ); 913cdf0e10cSrcweir 914cdf0e10cSrcweir Bitmap aMask(Size(200,200),1); 915cdf0e10cSrcweir aMask.Erase(COL_WHITE); 916cdf0e10cSrcweir { 917cdf0e10cSrcweir ScopedBitmapWriteAccess pAcc(aMask.AcquireWriteAccess(), 918cdf0e10cSrcweir aMask); 919cdf0e10cSrcweir if( pAcc.get() ) 920cdf0e10cSrcweir { 921cdf0e10cSrcweir pAcc->SetFillColor(COL_BLACK); 922cdf0e10cSrcweir pAcc->FillRect(Rectangle(0,0,100,100)); 923cdf0e10cSrcweir pAcc->SetPixel(0,0,BitmapColor(1)); 924cdf0e10cSrcweir pAcc->SetPixel(0,1,BitmapColor(0)); 925cdf0e10cSrcweir pAcc->SetPixel(0,2,BitmapColor(1)); 926cdf0e10cSrcweir } 927cdf0e10cSrcweir } 928cdf0e10cSrcweir 929cdf0e10cSrcweir xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aMask)) ); 930cdf0e10cSrcweir 931cdf0e10cSrcweir checkCanvasBitmap( xBmp, "masked bitmap", nDepth ); 932cdf0e10cSrcweir 933cdf0e10cSrcweir AlphaMask aAlpha(Size(200,200)); 934cdf0e10cSrcweir aAlpha.Erase(255); 935cdf0e10cSrcweir { 936cdf0e10cSrcweir BitmapWriteAccess* pAcc = aAlpha.AcquireWriteAccess(); 937cdf0e10cSrcweir if( pAcc ) 938cdf0e10cSrcweir { 939cdf0e10cSrcweir pAcc->SetFillColor(COL_BLACK); 940cdf0e10cSrcweir pAcc->FillRect(Rectangle(0,0,100,100)); 941cdf0e10cSrcweir pAcc->SetPixel(0,0,BitmapColor(255)); 942cdf0e10cSrcweir pAcc->SetPixel(0,1,BitmapColor(0)); 943cdf0e10cSrcweir pAcc->SetPixel(0,2,BitmapColor(255)); 944cdf0e10cSrcweir aAlpha.ReleaseAccess(pAcc); 945cdf0e10cSrcweir } 946cdf0e10cSrcweir } 947cdf0e10cSrcweir 948cdf0e10cSrcweir xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aAlpha)) ); 949cdf0e10cSrcweir 950cdf0e10cSrcweir checkCanvasBitmap( xBmp, "alpha bitmap", nDepth ); 951cdf0e10cSrcweir } 952cdf0e10cSrcweir 953cdf0e10cSrcweir // Testing XBitmap import 954cdf0e10cSrcweir // ====================== 955cdf0e10cSrcweir uno::Reference< rendering::XIntegerReadOnlyBitmap > xTestBmp( 956cdf0e10cSrcweir new TestBitmap( geometry::IntegerSize2D(10,10), true )); 957cdf0e10cSrcweir 958cdf0e10cSrcweir BitmapEx aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); 959cdf0e10cSrcweir test( aBmp.IsTransparent() == false, 960cdf0e10cSrcweir "Palette bitmap is not transparent" ); 961cdf0e10cSrcweir test( aBmp.GetSizePixel() == Size(10,10), 962cdf0e10cSrcweir "Bitmap has size (10,10)" ); 963cdf0e10cSrcweir test( aBmp.GetBitCount() == 8, 964cdf0e10cSrcweir "Bitmap has bitcount of 8" ); 965cdf0e10cSrcweir { 966cdf0e10cSrcweir BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess(); 967cdf0e10cSrcweir 968cdf0e10cSrcweir test( pBmpAcc, 969cdf0e10cSrcweir "Bitmap has valid BitmapReadAccess" ); 970cdf0e10cSrcweir 971cdf0e10cSrcweir test(pBmpAcc->GetPixel(0,0) == BitmapColor(0), 972cdf0e10cSrcweir "(0,0) correct content"); 973cdf0e10cSrcweir test(pBmpAcc->GetPixel(2,2) == BitmapColor(2), 974cdf0e10cSrcweir "(2,2) correct content"); 975cdf0e10cSrcweir test(pBmpAcc->GetPixel(2,9) == BitmapColor(9), 976cdf0e10cSrcweir "(9,2) correct content"); 977cdf0e10cSrcweir 978cdf0e10cSrcweir aBmp.GetBitmap().ReleaseAccess(pBmpAcc); 979cdf0e10cSrcweir } 980cdf0e10cSrcweir 981cdf0e10cSrcweir xTestBmp.set( new TestBitmap( geometry::IntegerSize2D(10,10), false )); 982cdf0e10cSrcweir 983cdf0e10cSrcweir aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); 984cdf0e10cSrcweir test( aBmp.IsTransparent() == TRUE, 985cdf0e10cSrcweir "Palette bitmap is transparent" ); 986cdf0e10cSrcweir test( aBmp.IsAlpha() == TRUE, 987cdf0e10cSrcweir "Palette bitmap has alpha" ); 988cdf0e10cSrcweir test( aBmp.GetSizePixel() == Size(10,10), 989cdf0e10cSrcweir "Bitmap has size (10,10)" ); 990cdf0e10cSrcweir test( aBmp.GetBitCount() == 24, 991cdf0e10cSrcweir "Bitmap has bitcount of 24" ); 992cdf0e10cSrcweir { 993cdf0e10cSrcweir BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess(); 994cdf0e10cSrcweir BitmapReadAccess* pAlphaAcc = aBmp.GetAlpha().AcquireReadAccess(); 995cdf0e10cSrcweir 996cdf0e10cSrcweir test( pBmpAcc, 997cdf0e10cSrcweir "Bitmap has valid BitmapReadAccess" ); 998cdf0e10cSrcweir test( pAlphaAcc, 999cdf0e10cSrcweir "Bitmap has valid alpha BitmapReadAccess" ); 1000cdf0e10cSrcweir 1001cdf0e10cSrcweir test(pBmpAcc->GetPixel(0,0) == BitmapColor(0,1,0), 1002cdf0e10cSrcweir "(0,0) correct content"); 1003cdf0e10cSrcweir test(pAlphaAcc->GetPixel(0,0) == BitmapColor(255), 1004cdf0e10cSrcweir "(0,0) correct alpha content"); 1005cdf0e10cSrcweir test(pBmpAcc->GetPixel(2,2) == BitmapColor(0,3,2), 1006cdf0e10cSrcweir "(2,2) correct content"); 1007cdf0e10cSrcweir test(pAlphaAcc->GetPixel(2,2) == BitmapColor(253), 1008cdf0e10cSrcweir "(2,2) correct alpha content"); 1009cdf0e10cSrcweir test(pBmpAcc->GetPixel(2,9) == BitmapColor(0,3,9), 1010cdf0e10cSrcweir "(9,2) correct content"); 1011cdf0e10cSrcweir test(pAlphaAcc->GetPixel(2,9) == BitmapColor(253), 1012cdf0e10cSrcweir "(9,2) correct alpha content"); 1013cdf0e10cSrcweir 1014cdf0e10cSrcweir aBmp.GetAlpha().ReleaseAccess(pAlphaAcc); 1015cdf0e10cSrcweir aBmp.GetBitmap().ReleaseAccess(pBmpAcc); 1016cdf0e10cSrcweir } 1017cdf0e10cSrcweir } 1018cdf0e10cSrcweir catch( uno::Exception& ) 1019cdf0e10cSrcweir { 1020cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 1021cdf0e10cSrcweir exit(2); 1022cdf0e10cSrcweir } 1023cdf0e10cSrcweir catch( std::exception& ) 1024cdf0e10cSrcweir { 1025cdf0e10cSrcweir OSL_TRACE( "Caught std exception!" ); 1026cdf0e10cSrcweir } 1027cdf0e10cSrcweir 1028cdf0e10cSrcweir if( g_failure ) 1029cdf0e10cSrcweir exit(2); 1030cdf0e10cSrcweir } 1031cdf0e10cSrcweir 1032cdf0e10cSrcweir } // namespace 1033cdf0e10cSrcweir 1034cdf0e10cSrcweir void Main() 1035cdf0e10cSrcweir { 1036cdf0e10cSrcweir TestWindow aWindow; 1037cdf0e10cSrcweir aWindow.Execute(); 1038cdf0e10cSrcweir aWindow.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL - canvasbitmaptest" ) ) ); 1039cdf0e10cSrcweir 1040cdf0e10cSrcweir Application::Execute(); 1041cdf0e10cSrcweir } 1042cdf0e10cSrcweir 1043