Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <canvas/debug.hxx>
31 : : #include <tools/diagnose_ex.h>
32 : :
33 : : #include <com/sun/star/util/Endianness.hpp>
34 : :
35 : : #include <rtl/logfile.hxx>
36 : : #include <rtl/math.hxx>
37 : :
38 : : #include <tools/poly.hxx>
39 : : #include <vcl/window.hxx>
40 : : #include <vcl/bitmapex.hxx>
41 : : #include <vcl/bmpacc.hxx>
42 : : #include <vcl/canvastools.hxx>
43 : :
44 : : #include <basegfx/matrix/b2dhommatrix.hxx>
45 : : #include <basegfx/point/b2dpoint.hxx>
46 : : #include <basegfx/tools/canvastools.hxx>
47 : : #include <basegfx/numeric/ftools.hxx>
48 : :
49 : : #include <canvas/canvastools.hxx>
50 : :
51 : : #include "canvasbitmap.hxx"
52 : : #include "canvasbitmaphelper.hxx"
53 : :
54 : :
55 : : using namespace ::com::sun::star;
56 : :
57 : : namespace vclcanvas
58 : : {
59 : 0 : CanvasBitmapHelper::CanvasBitmapHelper() :
60 : : mpBackBuffer(),
61 : 0 : mpOutDevReference()
62 : : {
63 : 0 : }
64 : :
65 : 0 : void CanvasBitmapHelper::setBitmap( const BitmapEx& rBitmap )
66 : : {
67 : 0 : ENSURE_OR_THROW( mpOutDev,
68 : : "Invalid reference device" );
69 : :
70 : : mpBackBuffer.reset( new BitmapBackBuffer( rBitmap,
71 : 0 : mpOutDev->getOutDev() ) );
72 : :
73 : : // tell canvas helper about the new target OutDev (don't
74 : : // protect state, it's our own VirDev, anyways)
75 : 0 : setOutDev( mpBackBuffer, false );
76 : 0 : }
77 : :
78 : 0 : void CanvasBitmapHelper::init( const BitmapEx& rBitmap,
79 : : rendering::XGraphicDevice& rDevice,
80 : : const OutDevProviderSharedPtr& rOutDevReference )
81 : : {
82 : 0 : mpOutDevReference = rOutDevReference;
83 : 0 : mpBackBuffer.reset( new BitmapBackBuffer( rBitmap, rOutDevReference->getOutDev() ));
84 : :
85 : : // forward new settings to base class (ref device, output
86 : : // surface, no protection (own backbuffer), alpha depends on
87 : : // whether BmpEx is transparent or not)
88 : : CanvasHelper::init( rDevice,
89 : : mpBackBuffer,
90 : : false,
91 : 0 : rBitmap.IsTransparent() );
92 : 0 : }
93 : :
94 : 0 : void CanvasBitmapHelper::disposing()
95 : : {
96 : 0 : mpBackBuffer.reset();
97 : 0 : mpOutDevReference.reset();
98 : :
99 : : // forward to base class
100 : 0 : CanvasHelper::disposing();
101 : 0 : }
102 : :
103 : 0 : geometry::IntegerSize2D CanvasBitmapHelper::getSize()
104 : : {
105 : 0 : if( !mpBackBuffer )
106 : 0 : return geometry::IntegerSize2D();
107 : :
108 : 0 : return ::vcl::unotools::integerSize2DFromSize( mpBackBuffer->getBitmapSizePixel() );
109 : : }
110 : :
111 : 0 : void CanvasBitmapHelper::clear()
112 : : {
113 : : // are we disposed?
114 : 0 : if( mpBackBuffer )
115 : 0 : mpBackBuffer->clear(); // alpha vdev needs special treatment
116 : 0 : }
117 : :
118 : 0 : uno::Reference< rendering::XBitmap > CanvasBitmapHelper::getScaledBitmap( const geometry::RealSize2D& newSize,
119 : : sal_Bool beFast )
120 : : {
121 : 0 : ENSURE_OR_THROW( mpDevice,
122 : : "disposed CanvasHelper" );
123 : :
124 : : RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getScaledBitmap()" );
125 : :
126 : 0 : if( !mpBackBuffer || mpDevice )
127 : 0 : return uno::Reference< rendering::XBitmap >(); // we're disposed
128 : :
129 : 0 : BitmapEx aRes( mpBackBuffer->getBitmapReference() );
130 : :
131 : : aRes.Scale( ::vcl::unotools::sizeFromRealSize2D(newSize),
132 : 0 : beFast ? BMP_SCALE_FAST : BMP_SCALE_DEFAULT );
133 : :
134 : : return uno::Reference< rendering::XBitmap >(
135 : 0 : new CanvasBitmap( aRes, *mpDevice, mpOutDevReference ) );
136 : : }
137 : :
138 : 0 : uno::Sequence< sal_Int8 > CanvasBitmapHelper::getData( rendering::IntegerBitmapLayout& rLayout,
139 : : const geometry::IntegerRectangle2D& rect )
140 : : {
141 : : RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getData()" );
142 : :
143 : 0 : if( !mpBackBuffer )
144 : 0 : return uno::Sequence< sal_Int8 >(); // we're disposed
145 : :
146 : 0 : rLayout = getMemoryLayout();
147 : 0 : Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
148 : 0 : Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
149 : :
150 : 0 : Bitmap::ScopedReadAccess pReadAccess( aBitmap );
151 : 0 : Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
152 : : (BitmapReadAccess*)NULL : aAlpha.AcquireReadAccess(),
153 : 0 : aAlpha );
154 : :
155 : 0 : ENSURE_OR_THROW( pReadAccess.get() != NULL,
156 : : "Could not acquire read access to bitmap" );
157 : :
158 : : // TODO(F1): Support more formats.
159 : 0 : const Size aBmpSize( aBitmap.GetSizePixel() );
160 : :
161 : 0 : rLayout.ScanLines = aBmpSize.Height();
162 : 0 : rLayout.ScanLineBytes = aBmpSize.Width()*4;
163 : 0 : rLayout.ScanLineStride = rLayout.ScanLineBytes;
164 : :
165 : : // for the time being, always return as BGRA
166 : 0 : uno::Sequence< sal_Int8 > aRes( 4*aBmpSize.Width()*aBmpSize.Height() );
167 : 0 : sal_Int8* pRes = aRes.getArray();
168 : :
169 : 0 : int nCurrPos(0);
170 : 0 : for( int y=rect.Y1;
171 : 0 : y<aBmpSize.Height() && y<rect.Y2;
172 : : ++y )
173 : : {
174 : 0 : if( pAlphaReadAccess.get() != NULL )
175 : : {
176 : 0 : for( int x=rect.X1;
177 : 0 : x<aBmpSize.Width() && x<rect.X2;
178 : : ++x )
179 : : {
180 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
181 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
182 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
183 : 0 : pRes[ nCurrPos++ ] = pAlphaReadAccess->GetPixel( y, x ).GetIndex();
184 : : }
185 : : }
186 : : else
187 : : {
188 : 0 : for( int x=rect.X1;
189 : 0 : x<aBmpSize.Width() && x<rect.X2;
190 : : ++x )
191 : : {
192 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
193 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
194 : 0 : pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
195 : 0 : pRes[ nCurrPos++ ] = sal_uInt8(255);
196 : : }
197 : : }
198 : : }
199 : :
200 : 0 : return aRes;
201 : : }
202 : :
203 : 0 : void CanvasBitmapHelper::setData( const uno::Sequence< sal_Int8 >& data,
204 : : const rendering::IntegerBitmapLayout& rLayout,
205 : : const geometry::IntegerRectangle2D& rect )
206 : : {
207 : : RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::setData()" );
208 : :
209 : 0 : if( !mpBackBuffer )
210 : 0 : return; // we're disposed
211 : :
212 : 0 : const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() );
213 : 0 : ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != rLayout.PlaneStride ||
214 : : aRefLayout.ColorSpace != rLayout.ColorSpace ||
215 : : aRefLayout.Palette != rLayout.Palette ||
216 : : aRefLayout.IsMsbFirst != rLayout.IsMsbFirst,
217 : : "Mismatching memory layout" );
218 : :
219 : : // retrieve local copies from the BitmapEx, which are later
220 : : // stored back. Unfortunately, the BitmapEx does not permit
221 : : // in-place modifications, as they are necessary here.
222 : 0 : Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
223 : 0 : Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
224 : :
225 : 0 : bool bCopyBack( false ); // only copy something back, if we
226 : : // actually changed a pixel
227 : :
228 : : {
229 : 0 : Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
230 : 0 : Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ?
231 : : (BitmapWriteAccess*)NULL : aAlpha.AcquireWriteAccess(),
232 : 0 : aAlpha );
233 : :
234 : 0 : if( pAlphaWriteAccess.get() )
235 : : {
236 : : DBG_ASSERT( pAlphaWriteAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
237 : : pAlphaWriteAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
238 : : "non-8bit alpha not supported!" );
239 : : }
240 : :
241 : 0 : ENSURE_OR_THROW( pWriteAccess.get() != NULL,
242 : : "Could not acquire write access to bitmap" );
243 : :
244 : : // TODO(F1): Support more formats.
245 : 0 : const Size aBmpSize( aBitmap.GetSizePixel() );
246 : :
247 : : // for the time being, always read as BGRA
248 : 0 : int x, y, nCurrPos(0);
249 : 0 : for( y=rect.Y1;
250 : 0 : y<aBmpSize.Height() && y<rect.Y2;
251 : : ++y )
252 : : {
253 : 0 : if( pAlphaWriteAccess.get() != NULL )
254 : : {
255 : 0 : switch( pWriteAccess->GetScanlineFormat() )
256 : : {
257 : : case BMP_FORMAT_8BIT_PAL:
258 : : {
259 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
260 : 0 : Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
261 : :
262 : 0 : for( x=rect.X1;
263 : 0 : x<aBmpSize.Width() && x<rect.X2;
264 : : ++x )
265 : : {
266 : 0 : *pScan++ = (sal_uInt8)pWriteAccess->GetBestPaletteIndex(
267 : 0 : BitmapColor( data[ nCurrPos ],
268 : 0 : data[ nCurrPos+1 ],
269 : 0 : data[ nCurrPos+2 ] ) );
270 : :
271 : 0 : nCurrPos += 3;
272 : :
273 : : // cast to unsigned byte, for correct subtraction result
274 : : *pAScan++ = static_cast<sal_uInt8>(255 -
275 : 0 : static_cast<sal_uInt8>(data[ nCurrPos++ ]));
276 : : }
277 : : }
278 : 0 : break;
279 : :
280 : : case BMP_FORMAT_24BIT_TC_BGR:
281 : : {
282 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
283 : 0 : Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
284 : :
285 : 0 : for( x=rect.X1;
286 : 0 : x<aBmpSize.Width() && x<rect.X2;
287 : : ++x )
288 : : {
289 : 0 : *pScan++ = data[ nCurrPos+2 ];
290 : 0 : *pScan++ = data[ nCurrPos+1 ];
291 : 0 : *pScan++ = data[ nCurrPos ];
292 : :
293 : 0 : nCurrPos += 3;
294 : :
295 : : // cast to unsigned byte, for correct subtraction result
296 : : *pAScan++ = static_cast<sal_uInt8>(255 -
297 : 0 : static_cast<sal_uInt8>(data[ nCurrPos++ ]));
298 : : }
299 : : }
300 : 0 : break;
301 : :
302 : : case BMP_FORMAT_24BIT_TC_RGB:
303 : : {
304 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
305 : 0 : Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
306 : :
307 : 0 : for( x=rect.X1;
308 : 0 : x<aBmpSize.Width() && x<rect.X2;
309 : : ++x )
310 : : {
311 : 0 : *pScan++ = data[ nCurrPos ];
312 : 0 : *pScan++ = data[ nCurrPos+1 ];
313 : 0 : *pScan++ = data[ nCurrPos+2 ];
314 : :
315 : 0 : nCurrPos += 3;
316 : :
317 : : // cast to unsigned byte, for correct subtraction result
318 : : *pAScan++ = static_cast<sal_uInt8>(255 -
319 : 0 : static_cast<sal_uInt8>(data[ nCurrPos++ ]));
320 : : }
321 : : }
322 : 0 : break;
323 : :
324 : : default:
325 : : {
326 : 0 : for( x=rect.X1;
327 : 0 : x<aBmpSize.Width() && x<rect.X2;
328 : : ++x )
329 : : {
330 : 0 : pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos ],
331 : 0 : data[ nCurrPos+1 ],
332 : 0 : data[ nCurrPos+2 ] ) );
333 : 0 : nCurrPos += 3;
334 : :
335 : : // cast to unsigned byte, for correct subtraction result
336 : : pAlphaWriteAccess->SetPixel( y, x,
337 : : BitmapColor(
338 : : static_cast<sal_uInt8>(255 -
339 : 0 : static_cast<sal_uInt8>(data[ nCurrPos++ ])) ) );
340 : : }
341 : : }
342 : 0 : break;
343 : : }
344 : : }
345 : : else
346 : : {
347 : : // TODO(Q3): This is copy'n'pasted from
348 : : // canvashelper.cxx, unify!
349 : 0 : switch( pWriteAccess->GetScanlineFormat() )
350 : : {
351 : : case BMP_FORMAT_8BIT_PAL:
352 : : {
353 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
354 : :
355 : 0 : for( x=rect.X1;
356 : 0 : x<aBmpSize.Width() && x<rect.X2;
357 : : ++x )
358 : : {
359 : 0 : *pScan++ = (sal_uInt8)pWriteAccess->GetBestPaletteIndex(
360 : 0 : BitmapColor( data[ nCurrPos ],
361 : 0 : data[ nCurrPos+1 ],
362 : 0 : data[ nCurrPos+2 ] ) );
363 : :
364 : 0 : nCurrPos += 4; // skip three colors, _plus_ alpha
365 : : }
366 : : }
367 : 0 : break;
368 : :
369 : : case BMP_FORMAT_24BIT_TC_BGR:
370 : : {
371 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
372 : :
373 : 0 : for( x=rect.X1;
374 : 0 : x<aBmpSize.Width() && x<rect.X2;
375 : : ++x )
376 : : {
377 : 0 : *pScan++ = data[ nCurrPos+2 ];
378 : 0 : *pScan++ = data[ nCurrPos+1 ];
379 : 0 : *pScan++ = data[ nCurrPos ];
380 : :
381 : 0 : nCurrPos += 4; // skip three colors, _plus_ alpha
382 : : }
383 : : }
384 : 0 : break;
385 : :
386 : : case BMP_FORMAT_24BIT_TC_RGB:
387 : : {
388 : 0 : Scanline pScan = pWriteAccess->GetScanline( y );
389 : :
390 : 0 : for( x=rect.X1;
391 : 0 : x<aBmpSize.Width() && x<rect.X2;
392 : : ++x )
393 : : {
394 : 0 : *pScan++ = data[ nCurrPos ];
395 : 0 : *pScan++ = data[ nCurrPos+1 ];
396 : 0 : *pScan++ = data[ nCurrPos+2 ];
397 : :
398 : 0 : nCurrPos += 4; // skip three colors, _plus_ alpha
399 : : }
400 : : }
401 : 0 : break;
402 : :
403 : : default:
404 : : {
405 : 0 : for( x=rect.X1;
406 : 0 : x<aBmpSize.Width() && x<rect.X2;
407 : : ++x )
408 : : {
409 : 0 : pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos ],
410 : 0 : data[ nCurrPos+1 ],
411 : 0 : data[ nCurrPos+2 ] ) );
412 : 0 : nCurrPos += 4; // skip three colors, _plus_ alpha
413 : : }
414 : : }
415 : 0 : break;
416 : : }
417 : : }
418 : :
419 : 0 : bCopyBack = true;
420 : 0 : }
421 : : }
422 : :
423 : : // copy back only here, since the BitmapAccessors must be
424 : : // destroyed beforehand
425 : 0 : if( bCopyBack )
426 : : {
427 : 0 : if( aAlpha.IsEmpty() )
428 : 0 : setBitmap( BitmapEx( aBitmap ) );
429 : : else
430 : : setBitmap( BitmapEx( aBitmap,
431 : 0 : AlphaMask( aAlpha ) ) );
432 : 0 : }
433 : : }
434 : :
435 : 0 : void CanvasBitmapHelper::setPixel( const uno::Sequence< sal_Int8 >& color,
436 : : const rendering::IntegerBitmapLayout& rLayout,
437 : : const geometry::IntegerPoint2D& pos )
438 : : {
439 : : RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::setPixel()" );
440 : :
441 : 0 : if( !mpBackBuffer )
442 : 0 : return; // we're disposed
443 : :
444 : 0 : const Size aBmpSize( mpBackBuffer->getBitmapReference().GetSizePixel() );
445 : :
446 : 0 : ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(),
447 : : "X coordinate out of bounds" );
448 : 0 : ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(),
449 : : "Y coordinate out of bounds" );
450 : 0 : ENSURE_ARG_OR_THROW( color.getLength() > 3,
451 : : "not enough color components" );
452 : :
453 : 0 : const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() );
454 : 0 : ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != rLayout.PlaneStride ||
455 : : aRefLayout.ColorSpace != rLayout.ColorSpace ||
456 : : aRefLayout.Palette != rLayout.Palette ||
457 : : aRefLayout.IsMsbFirst != rLayout.IsMsbFirst,
458 : : "Mismatching memory layout" );
459 : :
460 : : // retrieve local copies from the BitmapEx, which are later
461 : : // stored back. Unfortunately, the BitmapEx does not permit
462 : : // in-place modifications, as they are necessary here.
463 : 0 : Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
464 : 0 : Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
465 : :
466 : 0 : bool bCopyBack( false ); // only copy something back, if we
467 : : // actually changed a pixel
468 : :
469 : : {
470 : 0 : Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
471 : 0 : Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ?
472 : : (BitmapWriteAccess*)NULL : aAlpha.AcquireWriteAccess(),
473 : 0 : aAlpha );
474 : :
475 : 0 : ENSURE_OR_THROW( pWriteAccess.get() != NULL,
476 : : "Could not acquire write access to bitmap" );
477 : :
478 : 0 : pWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( color[ 0 ],
479 : 0 : color[ 1 ],
480 : 0 : color[ 2 ] ) );
481 : :
482 : 0 : if( pAlphaWriteAccess.get() != NULL )
483 : 0 : pAlphaWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( 255 - color[ 3 ] ) );
484 : :
485 : 0 : bCopyBack = true;
486 : : }
487 : :
488 : : // copy back only here, since the BitmapAccessors must be
489 : : // destroyed beforehand
490 : 0 : if( bCopyBack )
491 : : {
492 : 0 : if( aAlpha.IsEmpty() )
493 : 0 : setBitmap( BitmapEx( aBitmap ) );
494 : : else
495 : : setBitmap( BitmapEx( aBitmap,
496 : 0 : AlphaMask( aAlpha ) ) );
497 : 0 : }
498 : : }
499 : :
500 : 0 : uno::Sequence< sal_Int8 > CanvasBitmapHelper::getPixel( rendering::IntegerBitmapLayout& rLayout,
501 : : const geometry::IntegerPoint2D& pos )
502 : : {
503 : : RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getPixel()" );
504 : :
505 : 0 : if( !mpBackBuffer )
506 : 0 : return uno::Sequence< sal_Int8 >(); // we're disposed
507 : :
508 : 0 : rLayout = getMemoryLayout();
509 : 0 : rLayout.ScanLines = 1;
510 : 0 : rLayout.ScanLineBytes = 4;
511 : 0 : rLayout.ScanLineStride = rLayout.ScanLineBytes;
512 : :
513 : 0 : const Size aBmpSize( mpBackBuffer->getBitmapReference().GetSizePixel() );
514 : :
515 : 0 : ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(),
516 : : "X coordinate out of bounds" );
517 : 0 : ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(),
518 : : "Y coordinate out of bounds" );
519 : :
520 : 0 : Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
521 : 0 : Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
522 : :
523 : 0 : Bitmap::ScopedReadAccess pReadAccess( aBitmap );
524 : 0 : Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
525 : : (BitmapReadAccess*)NULL : aAlpha.AcquireReadAccess(),
526 : 0 : aAlpha );
527 : 0 : ENSURE_OR_THROW( pReadAccess.get() != NULL,
528 : : "Could not acquire read access to bitmap" );
529 : :
530 : 0 : uno::Sequence< sal_Int8 > aRes( 4 );
531 : 0 : sal_Int8* pRes = aRes.getArray();
532 : :
533 : 0 : const BitmapColor aColor( pReadAccess->GetColor( pos.Y, pos.X ) );
534 : 0 : pRes[ 0 ] = aColor.GetRed();
535 : 0 : pRes[ 1 ] = aColor.GetGreen();
536 : 0 : pRes[ 2 ] = aColor.GetBlue();
537 : :
538 : 0 : if( pAlphaReadAccess.get() != NULL )
539 : 0 : pRes[ 3 ] = pAlphaReadAccess->GetPixel( pos.Y, pos.X ).GetIndex();
540 : : else
541 : 0 : pRes[ 3 ] = sal_uInt8(255);
542 : :
543 : 0 : return aRes;
544 : : }
545 : :
546 : 0 : rendering::IntegerBitmapLayout CanvasBitmapHelper::getMemoryLayout()
547 : : {
548 : 0 : if( !mpOutDev.get() )
549 : 0 : return rendering::IntegerBitmapLayout(); // we're disposed
550 : :
551 : 0 : return ::canvas::tools::getStdMemoryLayout(getSize());
552 : : }
553 : :
554 : 0 : BitmapEx CanvasBitmapHelper::getBitmap() const
555 : : {
556 : 0 : if( !mpBackBuffer )
557 : 0 : return BitmapEx(); // we're disposed
558 : : else
559 : 0 : return mpBackBuffer->getBitmapReference();
560 : : }
561 : :
562 : 0 : }
563 : :
564 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|