merge the formfield patch from ooo-build
[ooovba.git] / vcl / test / canvasbitmaptest.cxx
blobf0ba46c83644158564d8d6036e90bfea2d0e93b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: canvasbitmaptest.cxx,v $
10 * $Revision: 1.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 // bootstrap stuff
35 #include <sal/main.h>
36 #include <rtl/bootstrap.hxx>
37 #include <rtl/ref.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/regpathhelper.hxx>
40 #include <cppuhelper/servicefactory.hxx>
41 #include <cppuhelper/bootstrap.hxx>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/lang/XInitialization.hpp>
44 #include <com/sun/star/registry/XSimpleRegistry.hpp>
45 #include <com/sun/star/util/Endianness.hpp>
46 #include <com/sun/star/rendering/ColorComponentTag.hpp>
47 #include <com/sun/star/rendering/ColorSpaceType.hpp>
48 #include <com/sun/star/rendering/RenderingIntent.hpp>
49 #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
50 #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
51 #include <com/sun/star/rendering/XBitmapPalette.hpp>
53 #include <ucbhelper/contentbroker.hxx>
54 #include <ucbhelper/configurationkeys.hxx>
55 #include <cppuhelper/compbase3.hxx>
57 #include <tools/diagnose_ex.h>
58 #include <tools/extendapplicationenvironment.hxx>
60 #include "vcl/svapp.hxx"
61 #include "vcl/canvastools.hxx"
62 #include "vcl/canvasbitmap.hxx"
63 #include "vcl/dialog.hxx"
64 #include "vcl/outdev.hxx"
65 #include "vcl/bmpacc.hxx"
66 #include "vcl/virdev.hxx"
67 #include "vcl/bitmapex.hxx"
70 using namespace ::com::sun::star;
71 using namespace ::vcl::unotools;
73 // -----------------------------------------------------------------------
75 void Main();
77 // -----------------------------------------------------------------------
79 SAL_IMPLEMENT_MAIN()
81 tools::extendApplicationEnvironment();
83 uno::Reference< lang::XMultiServiceFactory > xMS;
84 xMS = cppu::createRegistryServiceFactory(
85 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ),
86 sal_True );
88 InitVCL( xMS );
89 ::Main();
90 DeInitVCL();
92 return 0;
95 // -----------------------------------------------------------------------
97 namespace com { namespace sun { namespace star { namespace rendering
100 bool operator==( const RGBColor& rLHS, const ARGBColor& rRHS )
102 return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue;
104 bool operator==( const ARGBColor& rLHS, const RGBColor& rRHS )
106 return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue;
109 } } } }
111 //----------------------------------------------------------------------------------
113 namespace
116 class TestApp : public Application
118 public:
119 virtual void Main();
120 virtual USHORT Exception( USHORT nError );
123 class TestWindow : public Dialog
125 public:
126 TestWindow() : Dialog( (Window *) NULL )
128 SetText( rtl::OUString::createFromAscii( "CanvasBitmap test harness" ) );
129 SetSizePixel( Size( 1024, 1024 ) );
130 EnablePaint( true );
131 Show();
134 virtual ~TestWindow() {}
135 virtual void Paint( const Rectangle& rRect );
138 //----------------------------------------------------------------------------------
140 static bool g_failure=false;
142 void test( bool bResult, const char* msg )
144 if( bResult )
146 OSL_TRACE("Testing: %s - PASSED", msg);
148 else
150 g_failure = true;
151 OSL_TRACE("Testing: %s - FAILED", msg);
155 //----------------------------------------------------------------------------------
157 bool rangeCheck( const rendering::RGBColor& rColor )
159 return rColor.Red < 0.0 || rColor.Red > 1.0 ||
160 rColor.Green < 0.0 || rColor.Green > 1.0 ||
161 rColor.Blue < 0.0 || rColor.Blue > 1.0;
164 //----------------------------------------------------------------------------------
166 void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp,
167 const char* msg,
168 int nOriginalDepth )
170 OSL_TRACE("-------------------------");
171 OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth);
173 BitmapEx aContainedBmpEx( xBmp->getBitmapEx() );
174 Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() );
175 int nDepth = nOriginalDepth;
178 ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(),
179 aContainedBmp );
180 nDepth = pAcc->GetBitCount();
183 test( aContainedBmp.GetSizePixel() == Size(200,200),
184 "Original bitmap size" );
186 test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200,
187 "Original bitmap size via API" );
189 test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(),
190 "Correct alpha state" );
192 test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(),
193 "getScaledBitmap()" );
195 rendering::IntegerBitmapLayout aLayout;
196 uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1));
198 const sal_Int32 nExpectedBitsPerPixel(
199 aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth);
200 test( aLayout.ScanLines == 1,
201 "# scanlines" );
202 test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8,
203 "# scanline bytes" );
204 test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 ||
205 aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8,
206 "# scanline stride" );
207 test( aLayout.PlaneStride == 0,
208 "# plane stride" );
210 test( aLayout.ColorSpace.is(),
211 "Color space there" );
213 test( aLayout.Palette.is() == (nDepth <= 8),
214 "Palette existance conforms to bitmap" );
216 uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) );
218 test( aPixelData2.getLength() == aPixelData.getLength(),
219 "getData and getPixel return same amount of data" );
221 aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1));
222 test( aLayout.ScanLines == 1,
223 "# scanlines" );
224 test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8,
225 "# scanline bytes" );
226 test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 ||
227 aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8,
228 "# scanline stride" );
230 uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData );
231 uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData );
233 const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() );
234 const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() );
235 const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() );
236 std::pair<const rendering::RGBColor*,
237 const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart );
238 test( aRes.first == pRGBEnd,
239 "argb and rgb colors are equal" );
241 test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd,
242 "rgb colors are within [0,1] range" );
244 test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0,
245 "First pixel is white" );
246 test( pARGBStart[1].Alpha == 1.0,
247 "Second pixel is opaque" );
248 if( aContainedBmpEx.IsTransparent() )
250 test( pARGBStart[0].Alpha == 0.0,
251 "First pixel is fully transparent" );
254 test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0,
255 "Second pixel is black" );
257 if( nOriginalDepth > 8 )
259 const Color aCol(COL_GREEN);
260 test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) &&
261 pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) &&
262 pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()),
263 "Sixth pixel is green" );
265 else if( nDepth <= 8 )
267 uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette();
268 test( xPal.is(),
269 "8bit or less: needs palette" );
270 test( xPal->getNumberOfEntries() == 1L << nOriginalDepth,
271 "Palette has correct entry count" );
272 uno::Sequence<double> aIndex;
273 test( xPal->setIndex(aIndex,sal_True,0) == sal_False,
274 "Palette is read-only" );
275 test( xPal->getIndex(aIndex,0),
276 "Palette entry 0 is opaque" );
277 test( xPal->getColorSpace().is(),
278 "Palette has a valid color space" );
281 test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0,
282 "150th pixel is white" );
284 if( nOriginalDepth > 8 )
286 const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() );
287 uno::Sequence<rendering::ARGBColor> aARGBColor(1);
288 uno::Sequence<rendering::RGBColor> aRGBColor(1);
289 uno::Sequence<sal_Int8> aPixel3, aPixel4;
291 const Color aCol(COL_GREEN);
292 aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed());
293 aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
294 aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue());
295 aARGBColor[0].Alpha = 1.0;
297 aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed());
298 aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
299 aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue());
301 aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor );
302 aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) );
303 test( aPixel3 == aPixel4,
304 "Green pixel from bitmap matches with manually converted green pixel" );
306 if( !aContainedBmpEx.IsTransparent() )
308 aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor );
309 test( aPixel3 == aPixel4,
310 "Green pixel from bitmap matches with manually RGB-converted green pixel" );
315 //----------------------------------------------------------------------------------
317 void checkBitmapImport( const rtl::Reference<VclCanvasBitmap>& xBmp,
318 const char* msg,
319 int nOriginalDepth )
321 OSL_TRACE("-------------------------");
322 OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth);
324 BitmapEx aContainedBmpEx( xBmp->getBitmapEx() );
325 Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() );
326 int nDepth = nOriginalDepth;
329 ScopedBitmapReadAccess pAcc( aContainedBmp.AcquireReadAccess(),
330 aContainedBmp );
331 nDepth = pAcc->GetBitCount();
334 test( aContainedBmp.GetSizePixel() == Size(200,200),
335 "Original bitmap size" );
337 test( xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200,
338 "Original bitmap size via API" );
340 test( xBmp->hasAlpha() == aContainedBmpEx.IsTransparent(),
341 "Correct alpha state" );
343 test( xBmp->getScaledBitmap( geometry::RealSize2D(500,500), sal_False ).is(),
344 "getScaledBitmap()" );
346 rendering::IntegerBitmapLayout aLayout;
347 uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1));
349 const sal_Int32 nExpectedBitsPerPixel(
350 aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth);
351 test( aLayout.ScanLines == 1,
352 "# scanlines" );
353 test( aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8,
354 "# scanline bytes" );
355 test( aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 ||
356 aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8,
357 "# scanline stride" );
358 test( aLayout.PlaneStride == 0,
359 "# plane stride" );
361 test( aLayout.ColorSpace.is(),
362 "Color space there" );
364 test( aLayout.Palette.is() == (nDepth <= 8),
365 "Palette existance conforms to bitmap" );
367 uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) );
369 test( aPixelData2.getLength() == aPixelData.getLength(),
370 "getData and getPixel return same amount of data" );
372 aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1));
373 test( aLayout.ScanLines == 1,
374 "# scanlines" );
375 test( aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8,
376 "# scanline bytes" );
377 test( aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 ||
378 aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8,
379 "# scanline stride" );
381 uno::Sequence< rendering::RGBColor > aRGBColors = xBmp->convertIntegerToRGB( aPixelData );
382 uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData );
384 const rendering::RGBColor* pRGBStart ( aRGBColors.getConstArray() );
385 const rendering::RGBColor* pRGBEnd ( aRGBColors.getConstArray()+aRGBColors.getLength() );
386 const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() );
387 std::pair<const rendering::RGBColor*,
388 const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart );
389 test( aRes.first == pRGBEnd,
390 "argb and rgb colors are equal" );
392 test( std::find_if(pRGBStart,pRGBEnd,&rangeCheck) == pRGBEnd,
393 "rgb colors are within [0,1] range" );
395 test( pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0,
396 "First pixel is white" );
397 test( pARGBStart[1].Alpha == 1.0,
398 "Second pixel is opaque" );
399 if( aContainedBmpEx.IsTransparent() )
401 test( pARGBStart[0].Alpha == 0.0,
402 "First pixel is fully transparent" );
405 test( pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0,
406 "Second pixel is black" );
408 if( nOriginalDepth > 8 )
410 const Color aCol(COL_GREEN);
411 test( pRGBStart[5].Red == vcl::unotools::toDoubleColor(aCol.GetRed()) &&
412 pRGBStart[5].Green == vcl::unotools::toDoubleColor(aCol.GetGreen()) &&
413 pRGBStart[5].Blue == vcl::unotools::toDoubleColor(aCol.GetBlue()),
414 "Sixth pixel is green" );
416 else if( nDepth <= 8 )
418 uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette();
419 test( xPal.is(),
420 "8bit or less: needs palette" );
421 test( xPal->getNumberOfEntries() == 1L << nOriginalDepth,
422 "Palette has correct entry count" );
423 uno::Sequence<double> aIndex;
424 test( xPal->setIndex(aIndex,sal_True,0) == sal_False,
425 "Palette is read-only" );
426 test( xPal->getIndex(aIndex,0),
427 "Palette entry 0 is opaque" );
428 test( xPal->getColorSpace().is(),
429 "Palette has a valid color space" );
432 test( pRGBStart[150].Red == 1.0 && pRGBStart[150].Green == 1.0 && pRGBStart[150].Blue == 1.0,
433 "150th pixel is white" );
435 if( nOriginalDepth > 8 )
437 const uno::Sequence<sal_Int8> aComponentTags( xBmp->getComponentTags() );
438 uno::Sequence<rendering::ARGBColor> aARGBColor(1);
439 uno::Sequence<rendering::RGBColor> aRGBColor(1);
440 uno::Sequence<sal_Int8> aPixel3, aPixel4;
442 const Color aCol(COL_GREEN);
443 aARGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed());
444 aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
445 aARGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue());
446 aARGBColor[0].Alpha = 1.0;
448 aRGBColor[0].Red = vcl::unotools::toDoubleColor(aCol.GetRed());
449 aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
450 aRGBColor[0].Blue = vcl::unotools::toDoubleColor(aCol.GetBlue());
452 aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor );
453 aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) );
454 test( aPixel3 == aPixel4,
455 "Green pixel from bitmap matches with manually converted green pixel" );
457 if( !aContainedBmpEx.IsTransparent() )
459 aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor );
460 test( aPixel3 == aPixel4,
461 "Green pixel from bitmap matches with manually RGB-converted green pixel" );
466 //----------------------------------------------------------------------------------
468 class TestBitmap : public cppu::WeakImplHelper3< rendering::XIntegerReadOnlyBitmap,
469 rendering::XBitmapPalette,
470 rendering::XIntegerBitmapColorSpace >
472 private:
473 geometry::IntegerSize2D maSize;
474 uno::Sequence<sal_Int8> maComponentTags;
475 uno::Sequence<sal_Int32> maComponentBitCounts;
476 rendering::IntegerBitmapLayout maLayout;
477 const sal_Int32 mnBitsPerPixel;
479 // XBitmap
480 virtual geometry::IntegerSize2D SAL_CALL getSize() throw (uno::RuntimeException) { return maSize; }
481 virtual ::sal_Bool SAL_CALL hasAlpha( ) throw (uno::RuntimeException) { return mnBitsPerPixel != 8; }
482 virtual uno::Reference< rendering::XBitmap > SAL_CALL getScaledBitmap( const geometry::RealSize2D&,
483 sal_Bool ) throw (uno::RuntimeException) { return this; }
485 // XIntegerReadOnlyBitmap
486 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getData( rendering::IntegerBitmapLayout& bitmapLayout,
487 const geometry::IntegerRectangle2D& rect ) throw (lang::IndexOutOfBoundsException,
488 rendering::VolatileContentDestroyedException, uno::RuntimeException)
490 test( rect.X1 >= 0, "X1 within bounds" );
491 test( rect.Y1 >= 0, "Y1 within bounds" );
492 test( rect.X2 <= maSize.Width, "X2 within bounds" );
493 test( rect.Y2 <= maSize.Height, "Y2 within bounds" );
495 bitmapLayout = getMemoryLayout();
497 const sal_Int32 nWidth = rect.X2-rect.X1;
498 const sal_Int32 nHeight = rect.Y2-rect.Y1;
499 const sal_Int32 nScanlineLen = (nWidth * mnBitsPerPixel + 7)/8;
500 uno::Sequence<sal_Int8> aRes( nScanlineLen * nHeight );
501 sal_Int8* pOut = aRes.getArray();
503 bitmapLayout.ScanLines = nHeight;
504 bitmapLayout.ScanLineBytes =
505 bitmapLayout.ScanLineStride= nScanlineLen;
507 if( mnBitsPerPixel == 8 )
509 for( sal_Int32 y=0; y<nHeight; ++y )
511 for( sal_Int32 x=0; x<nWidth; ++x )
512 pOut[ y*nScanlineLen + x ] = sal_Int8(x);
515 else
517 for( sal_Int32 y=0; y<nHeight; ++y )
519 for( sal_Int32 x=0; x<nWidth; ++x )
521 pOut[ y*nScanlineLen + 4*x ] = sal_Int8(rect.X1);
522 pOut[ y*nScanlineLen + 4*x + 1 ] = sal_Int8(rect.Y2);
523 pOut[ y*nScanlineLen + 4*x + 2 ] = sal_Int8(x);
524 pOut[ y*nScanlineLen + 4*x + 3 ] = sal_Int8(rect.Y1);
529 return aRes;
532 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getPixel( rendering::IntegerBitmapLayout&,
533 const geometry::IntegerPoint2D& ) throw (lang::IndexOutOfBoundsException,
534 rendering::VolatileContentDestroyedException, uno::RuntimeException)
536 test(false, "Method not implemented");
537 return uno::Sequence< sal_Int8 >();
540 virtual uno::Reference< rendering::XBitmapPalette > SAL_CALL getPalette( ) throw (uno::RuntimeException)
542 uno::Reference< XBitmapPalette > aRet;
543 if( mnBitsPerPixel == 8 )
544 aRet.set(this);
545 return aRet;
548 virtual rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout( ) throw (uno::RuntimeException)
550 rendering::IntegerBitmapLayout aLayout( maLayout );
552 const sal_Int32 nScanlineLen = (maSize.Width * mnBitsPerPixel + 7)/8;
554 aLayout.ScanLines = maSize.Height;
555 aLayout.ScanLineBytes =
556 aLayout.ScanLineStride= nScanlineLen;
557 aLayout.Palette = getPalette();
558 aLayout.ColorSpace.set( this );
560 return aLayout;
563 // XBitmapPalette
564 virtual sal_Int32 SAL_CALL getNumberOfEntries() throw (uno::RuntimeException)
566 test( getPalette().is(),
567 "Got palette interface call without handing out palette?!" );
569 return 255;
572 virtual ::sal_Bool SAL_CALL getIndex( uno::Sequence< double >& entry,
573 ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException,
574 uno::RuntimeException)
576 test( getPalette().is(),
577 "Got palette interface call without handing out palette?!" );
578 test( nIndex >= 0 && nIndex < 256,
579 "Index out of range" );
580 entry = colorToStdColorSpaceSequence(
581 Color(UINT8(nIndex),
582 UINT8(nIndex),
583 UINT8(nIndex)) );
585 return sal_True; // no palette transparency here.
588 virtual ::sal_Bool SAL_CALL setIndex( const uno::Sequence< double >&,
589 ::sal_Bool,
590 ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException,
591 lang::IllegalArgumentException,
592 uno::RuntimeException)
594 test( getPalette().is(),
595 "Got palette interface call without handing out palette?!" );
596 test( nIndex >= 0 && nIndex < 256,
597 "Index out of range" );
598 return sal_False;
601 struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
602 PaletteColorSpaceHolder>
604 uno::Reference<rendering::XColorSpace> operator()()
606 return vcl::unotools::createStandardColorSpace();
610 virtual uno::Reference< rendering::XColorSpace > SAL_CALL getColorSpace( ) throw (uno::RuntimeException)
612 // this is the method from XBitmapPalette. Return palette color
613 // space here
614 return PaletteColorSpaceHolder::get();
617 // XIntegerBitmapColorSpace
618 virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException)
620 return rendering::ColorSpaceType::RGB;
623 virtual uno::Sequence< sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException)
625 return maComponentTags;
628 virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException)
630 return rendering::RenderingIntent::PERCEPTUAL;
633 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException)
635 test(false, "Method not implemented");
636 return uno::Sequence< ::beans::PropertyValue >();
639 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >&,
640 const uno::Reference< rendering::XColorSpace >& ) throw (uno::RuntimeException)
642 test(false, "Method not implemented");
643 return uno::Sequence< double >();
646 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException,
647 uno::RuntimeException)
649 test(false, "Method not implemented");
650 return uno::Sequence< rendering::RGBColor >();
653 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException,
654 uno::RuntimeException)
656 test(false, "Method not implemented");
657 return uno::Sequence< rendering::ARGBColor >();
660 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& ) throw (lang::IllegalArgumentException,
661 uno::RuntimeException)
663 test(false, "Method not implemented");
664 return uno::Sequence< rendering::ARGBColor >();
667 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException,
668 uno::RuntimeException)
670 test(false, "Method not implemented");
671 return uno::Sequence< double >();
674 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException,
675 uno::RuntimeException)
677 test(false, "This method is not expected to be called!");
678 return uno::Sequence< double >();
681 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException,
682 uno::RuntimeException)
684 test(false, "This method is not expected to be called!");
685 return uno::Sequence< double >();
688 virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException)
690 return mnBitsPerPixel;
693 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException)
695 return maComponentBitCounts;
698 virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException)
700 return util::Endianness::LITTLE;
703 virtual uno::Sequence< double > SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& ,
704 const uno::Reference< rendering::XColorSpace >& ) throw (lang::IllegalArgumentException,
705 uno::RuntimeException)
707 test(false, "Method not implemented");
708 return uno::Sequence< double >();
711 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& ,
712 const uno::Reference< rendering::XIntegerBitmapColorSpace >& ) throw (lang::IllegalArgumentException,
713 uno::RuntimeException)
715 test(false, "Method not implemented");
716 return uno::Sequence< sal_Int8 >();
719 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,
720 uno::RuntimeException)
722 const uno::Sequence< rendering::ARGBColor > aTemp( convertIntegerToARGB(deviceColor) );
723 const sal_Size nLen(aTemp.getLength());
724 uno::Sequence< rendering::RGBColor > aRes( nLen );
725 rendering::RGBColor* pOut = aRes.getArray();
726 for( sal_Size i=0; i<nLen; ++i )
728 *pOut++ = rendering::RGBColor(aTemp[i].Red,
729 aTemp[i].Green,
730 aTemp[i].Blue);
733 return aRes;
736 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,
737 uno::RuntimeException)
739 const sal_Size nLen( deviceColor.getLength() );
740 const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4);
741 test(nLen%nBytesPerPixel==0,
742 "number of channels no multiple of pixel element count");
744 uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel );
745 rendering::ARGBColor* pOut( aRes.getArray() );
747 if( getPalette().is() )
749 for( sal_Size i=0; i<nLen; ++i )
751 *pOut++ = rendering::ARGBColor(
752 1.0,
753 vcl::unotools::toDoubleColor(deviceColor[i]),
754 vcl::unotools::toDoubleColor(deviceColor[i]),
755 vcl::unotools::toDoubleColor(deviceColor[i]));
758 else
760 for( sal_Size i=0; i<nLen; i+=4 )
762 *pOut++ = rendering::ARGBColor(
763 vcl::unotools::toDoubleColor(deviceColor[i+3]),
764 vcl::unotools::toDoubleColor(deviceColor[i+0]),
765 vcl::unotools::toDoubleColor(deviceColor[i+1]),
766 vcl::unotools::toDoubleColor(deviceColor[i+2]));
770 return aRes;
773 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,
774 uno::RuntimeException)
776 const sal_Size nLen( deviceColor.getLength() );
777 const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4);
778 test(nLen%nBytesPerPixel==0,
779 "number of channels no multiple of pixel element count");
781 uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel );
782 rendering::ARGBColor* pOut( aRes.getArray() );
784 if( getPalette().is() )
786 for( sal_Size i=0; i<nLen; ++i )
788 *pOut++ = rendering::ARGBColor(
789 1.0,
790 vcl::unotools::toDoubleColor(deviceColor[i]),
791 vcl::unotools::toDoubleColor(deviceColor[i]),
792 vcl::unotools::toDoubleColor(deviceColor[i]));
795 else
797 for( sal_Size i=0; i<nLen; i+=4 )
799 const double fAlpha=vcl::unotools::toDoubleColor(deviceColor[i+3]);
800 *pOut++ = rendering::ARGBColor(
801 fAlpha,
802 fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+0]),
803 fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+1]),
804 fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+2]));
808 return aRes;
811 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& ) throw (lang::IllegalArgumentException,
812 uno::RuntimeException)
814 test(false, "Method not implemented");
815 return uno::Sequence< sal_Int8 >();
818 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException,
819 uno::RuntimeException)
821 test(false, "Method not implemented");
822 return uno::Sequence< sal_Int8 >();
825 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException,
826 uno::RuntimeException)
828 test(false, "Method not implemented");
829 return uno::Sequence< sal_Int8 >();
832 public:
833 TestBitmap( const geometry::IntegerSize2D& rSize, bool bPalette ) :
834 maSize(rSize),
835 maComponentTags(),
836 maComponentBitCounts(),
837 maLayout(),
838 mnBitsPerPixel( bPalette ? 8 : 32 )
840 if( bPalette )
842 maComponentTags.realloc(1);
843 maComponentTags[0] = rendering::ColorComponentTag::INDEX;
845 maComponentBitCounts.realloc(1);
846 maComponentBitCounts[0] = 8;
848 else
850 maComponentTags.realloc(4);
851 sal_Int8* pTags = maComponentTags.getArray();
852 pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
853 pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
854 pTags[2] = rendering::ColorComponentTag::RGB_RED;
855 pTags[3] = rendering::ColorComponentTag::ALPHA;
857 maComponentBitCounts.realloc(4);
858 sal_Int32* pCounts = maComponentBitCounts.getArray();
859 pCounts[0] = 8;
860 pCounts[1] = 8;
861 pCounts[2] = 8;
862 pCounts[3] = 8;
865 maLayout.ScanLines = 0;
866 maLayout.ScanLineBytes = 0;
867 maLayout.ScanLineStride = 0;
868 maLayout.PlaneStride = 0;
869 maLayout.ColorSpace.clear();
870 maLayout.Palette.clear();
871 maLayout.IsMsbFirst = sal_False;
876 //----------------------------------------------------------------------------------
878 void TestWindow::Paint( const Rectangle& )
880 static sal_Int8 lcl_depths[]={1,4,8,16,24};
884 // Testing VclCanvasBitmap wrapper
885 // ===============================
887 for( unsigned int i=0; i<sizeof(lcl_depths)/sizeof(*lcl_depths); ++i )
889 const sal_Int8 nDepth( lcl_depths[i] );
890 Bitmap aBitmap(Size(200,200),nDepth);
891 aBitmap.Erase(COL_WHITE);
893 ScopedBitmapWriteAccess pAcc(aBitmap.AcquireWriteAccess(),
894 aBitmap);
895 if( pAcc.get() )
897 BitmapColor aBlack(0);
898 BitmapColor aWhite(0);
899 if( pAcc->HasPalette() )
901 aBlack.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(0,0,0))) );
902 aWhite.SetIndex( sal::static_int_cast<BYTE>(pAcc->GetBestPaletteIndex(BitmapColor(255,255,255))) );
904 else
906 aBlack = Color(COL_BLACK);
907 aWhite = Color(COL_WHITE);
909 pAcc->SetFillColor(COL_GREEN);
910 pAcc->FillRect(Rectangle(0,0,100,100));
911 pAcc->SetPixel(0,0,aWhite);
912 pAcc->SetPixel(0,1,aBlack);
913 pAcc->SetPixel(0,2,aWhite);
917 rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(aBitmap) );
919 checkCanvasBitmap( xBmp, "single bitmap", nDepth );
921 Bitmap aMask(Size(200,200),1);
922 aMask.Erase(COL_WHITE);
924 ScopedBitmapWriteAccess pAcc(aMask.AcquireWriteAccess(),
925 aMask);
926 if( pAcc.get() )
928 pAcc->SetFillColor(COL_BLACK);
929 pAcc->FillRect(Rectangle(0,0,100,100));
930 pAcc->SetPixel(0,0,BitmapColor(1));
931 pAcc->SetPixel(0,1,BitmapColor(0));
932 pAcc->SetPixel(0,2,BitmapColor(1));
936 xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aMask)) );
938 checkCanvasBitmap( xBmp, "masked bitmap", nDepth );
940 AlphaMask aAlpha(Size(200,200));
941 aAlpha.Erase(255);
943 BitmapWriteAccess* pAcc = aAlpha.AcquireWriteAccess();
944 if( pAcc )
946 pAcc->SetFillColor(COL_BLACK);
947 pAcc->FillRect(Rectangle(0,0,100,100));
948 pAcc->SetPixel(0,0,BitmapColor(255));
949 pAcc->SetPixel(0,1,BitmapColor(0));
950 pAcc->SetPixel(0,2,BitmapColor(255));
951 aAlpha.ReleaseAccess(pAcc);
955 xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aAlpha)) );
957 checkCanvasBitmap( xBmp, "alpha bitmap", nDepth );
960 // Testing XBitmap import
961 // ======================
962 uno::Reference< rendering::XIntegerReadOnlyBitmap > xTestBmp(
963 new TestBitmap( geometry::IntegerSize2D(10,10), true ));
965 BitmapEx aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp);
966 test( aBmp.IsTransparent() == false,
967 "Palette bitmap is not transparent" );
968 test( aBmp.GetSizePixel() == Size(10,10),
969 "Bitmap has size (10,10)" );
970 test( aBmp.GetBitCount() == 8,
971 "Bitmap has bitcount of 8" );
973 BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess();
975 test( pBmpAcc,
976 "Bitmap has valid BitmapReadAccess" );
978 test(pBmpAcc->GetPixel(0,0) == BitmapColor(0),
979 "(0,0) correct content");
980 test(pBmpAcc->GetPixel(2,2) == BitmapColor(2),
981 "(2,2) correct content");
982 test(pBmpAcc->GetPixel(2,9) == BitmapColor(9),
983 "(9,2) correct content");
985 aBmp.GetBitmap().ReleaseAccess(pBmpAcc);
988 xTestBmp.set( new TestBitmap( geometry::IntegerSize2D(10,10), false ));
990 aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp);
991 test( aBmp.IsTransparent() == TRUE,
992 "Palette bitmap is transparent" );
993 test( aBmp.IsAlpha() == TRUE,
994 "Palette bitmap has alpha" );
995 test( aBmp.GetSizePixel() == Size(10,10),
996 "Bitmap has size (10,10)" );
997 test( aBmp.GetBitCount() == 24,
998 "Bitmap has bitcount of 24" );
1000 BitmapReadAccess* pBmpAcc = aBmp.GetBitmap().AcquireReadAccess();
1001 BitmapReadAccess* pAlphaAcc = aBmp.GetAlpha().AcquireReadAccess();
1003 test( pBmpAcc,
1004 "Bitmap has valid BitmapReadAccess" );
1005 test( pAlphaAcc,
1006 "Bitmap has valid alpha BitmapReadAccess" );
1008 test(pBmpAcc->GetPixel(0,0) == BitmapColor(0,1,0),
1009 "(0,0) correct content");
1010 test(pAlphaAcc->GetPixel(0,0) == BitmapColor(255),
1011 "(0,0) correct alpha content");
1012 test(pBmpAcc->GetPixel(2,2) == BitmapColor(0,3,2),
1013 "(2,2) correct content");
1014 test(pAlphaAcc->GetPixel(2,2) == BitmapColor(253),
1015 "(2,2) correct alpha content");
1016 test(pBmpAcc->GetPixel(2,9) == BitmapColor(0,3,9),
1017 "(9,2) correct content");
1018 test(pAlphaAcc->GetPixel(2,9) == BitmapColor(253),
1019 "(9,2) correct alpha content");
1021 aBmp.GetAlpha().ReleaseAccess(pAlphaAcc);
1022 aBmp.GetBitmap().ReleaseAccess(pBmpAcc);
1025 catch( uno::Exception& )
1027 DBG_UNHANDLED_EXCEPTION();
1028 exit(2);
1030 catch( std::exception& )
1032 OSL_TRACE( "Caught std exception!" );
1035 if( g_failure )
1036 exit(2);
1039 } // namespace
1041 void Main()
1043 TestWindow aWindow;
1044 aWindow.Execute();
1045 aWindow.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL - canvasbitmaptest" ) ) );
1047 Application::Execute();