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