Files
libreoffice/canvas/source/vcl/canvasbitmaphelper.cxx

560 lines
23 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <com/sun/star/util/Endianness.hpp>
#include <rtl/logfile.hxx>
#include <rtl/math.hxx>
#include <tools/poly.hxx>
#include <vcl/window.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/canvastools.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <canvas/canvastools.hxx>
#include "canvasbitmap.hxx"
#include "canvasbitmaphelper.hxx"
using namespace ::com::sun::star;
namespace vclcanvas
{
CanvasBitmapHelper::CanvasBitmapHelper() :
mpBackBuffer(),
mpOutDevReference()
{
}
void CanvasBitmapHelper::setBitmap( const BitmapEx& rBitmap )
{
ENSURE_OR_THROW( mpOutDev,
"Invalid reference device" );
mpBackBuffer.reset( new BitmapBackBuffer( rBitmap,
mpOutDev->getOutDev() ) );
// tell canvas helper about the new target OutDev (don't
// protect state, it's our own VirDev, anyways)
setOutDev( mpBackBuffer, false );
}
void CanvasBitmapHelper::init( const BitmapEx& rBitmap,
rendering::XGraphicDevice& rDevice,
const OutDevProviderSharedPtr& rOutDevReference )
{
mpOutDevReference = rOutDevReference;
mpBackBuffer.reset( new BitmapBackBuffer( rBitmap, rOutDevReference->getOutDev() ));
// forward new settings to base class (ref device, output
// surface, no protection (own backbuffer), alpha depends on
// whether BmpEx is transparent or not)
CanvasHelper::init( rDevice,
mpBackBuffer,
false,
rBitmap.IsTransparent() );
}
void CanvasBitmapHelper::disposing()
{
mpBackBuffer.reset();
mpOutDevReference.reset();
// forward to base class
CanvasHelper::disposing();
}
geometry::IntegerSize2D CanvasBitmapHelper::getSize()
{
if( !mpBackBuffer )
return geometry::IntegerSize2D();
CWS-TOOLING: integrate CWS vcl101 2009-04-30 16:05:34 +0200 pl r271420 : #i95591# need a poll timer so XtTimers work properly 2009-04-30 11:25:52 +0200 hdu r271406 : #i100929# avoid unneeded colormap reallocation 2009-04-30 11:21:16 +0200 hdu r271405 : #i100929# use improved SetDrawable() also for salframe updates 2009-04-30 11:12:41 +0200 hdu r271404 : i100929# invalidate cached renderpic also for changed vdev 2009-04-29 14:31:40 +0200 hdu r271375 : i100929# use cached renderpic also for alpha-rect/bitmap drawing 2009-04-29 14:16:51 +0200 hdu r271370 : i100929# notify only GtkSalFrame's valid X11SalFrames 2009-04-29 13:58:10 +0200 hdu r271369 : i100929# notify GtkSalFrame's X11SalGraphics that their drawables will become obsolete 2009-04-29 13:53:48 +0200 hdu r271367 : #i100929# release cached renderpic whenever the corresponding drawable changes 2009-04-28 11:56:07 +0200 pl r271317 : fix a snafu 2009-04-27 16:52:29 +0200 hdu r271293 : #i100000# WAE fix for debug=true compilation 2009-04-27 12:38:11 +0200 hdu r271260 : #i101367# disable vdev mapmode when measuring pixel size 2009-04-27 12:28:37 +0200 hdu r271259 : #i101367# speedup svclcanvas::CanvasBitmapHelper::getSize() 2009-04-23 15:11:25 +0200 hdu r271175 : #i91685# ignore trailing space in last cell 2009-04-23 12:55:14 +0200 pl r271156 : #i101032# check for empty bitmap 2009-04-23 11:04:50 +0200 pl r271144 : #101184# add a paranoia check 2009-04-21 19:12:25 +0200 pl r271055 : #i101184# add: recognize added/removed monitors in xinerama configuration for gtk plugin (thanks cmc) 2009-04-21 17:04:44 +0200 pl r271046 : #i101089# remove unused method (thanks cmc) 2009-04-21 16:41:38 +0200 hdu r271042 : #i99842# set text decoration color 2009-04-20 22:57:37 +0200 pl r271015 : #i101063# fix warnings 2009-04-20 22:55:39 +0200 pl r271014 : #i101063# fix warnings 2009-04-20 11:35:24 +0200 hdu r270968 : #i1001102# remove dependency to psprint module 2009-04-20 11:31:08 +0200 hdu r270967 : #i100929# keep cached render Picture in X11SalGraphics removes 2009-04-20 11:24:57 +0200 hdu r270966 : #i100929# cache render Picture in X11SalGraphics 2009-04-18 14:53:22 +0200 hdu r270959 : CWS-TOOLING: rebase CWS vcl101 to trunk@270723 (milestone: DEV300:m46) 2009-04-17 12:00:50 +0200 hdu r270934 : #i100951# b2d-polygon clipping handles bezier-segments nowadays => performance opt possible 2009-04-17 11:50:49 +0200 hdu r270933 : #i100922# count b2d-polypoly-points to avoid priority-queue reallocations 2009-04-17 11:07:03 +0200 hdu r270930 : #i101145# match dpi-sanity check with gnome-UI (thanks Caolan!) 2009-04-17 10:44:41 +0200 hdu r270929 : #i100603# dingbats-encoded PDF-builtin fonts are symbol fonts too 2009-04-17 10:36:10 +0200 hdu r270928 : #i101145# check sanity of resolution reported by Xft-dpi (thanks CMC!) 2009-04-08 13:53:35 +0200 hdu r270644 : #i100951# avoid expensive calls to basegfx::tools::clipPolygonOnRange() if possible 2009-04-08 13:19:26 +0200 hdu r270637 : #i100922# prevent needless stl::priority_queue reallacations by reserving 2009-04-08 11:14:30 +0200 hdu r270627 : #i100929# use X11SalGraphics::GetXRenderPicture() also for text drawing 2009-04-08 10:00:42 +0200 hdu r270620 : #i100929# add and use X11SalGraphics::GetXRenderPicture() for polygon drawing 2009-04-06 15:52:47 +0200 hdu r270563 : #i100885# add and use AquaSalGraphics::copyResolution() to speed up virdev creation 2009-04-02 14:39:06 +0200 pl r270408 : #i95873# do not set LD_LIBRARY_PATH for external apps 2009-03-31 18:43:19 +0200 pl r270292 : #i99783# transparency of closer image changed to mask in the meantime 2009-03-27 15:42:37 +0100 hdu r270158 : #i100591# fix binary search in dingbats encoding converter 2009-03-27 13:06:34 +0100 hdu r270151 : #i100603# only PDF builtin text fonts use WinAnsiEncoding 2009-03-27 12:05:35 +0100 hdu r270147 : #i100603# use correct encoding for all PDF builtin fonts 2009-03-27 09:04:07 +0100 hdu r270133 : #i100603# use proper encoding for PDF builtin symbol fonts 2009-03-26 17:19:38 +0100 hdu r270090 : #i100591# support RTL_TEXTENCODING_ADOBE_DINGBATS encoding 2009-03-25 09:02:18 +0100 hdu r269995 : #i100521# prefer osl_getAsciiFunctionSymbol() when dynloading SAGE and extra USER32 symbols 2009-03-25 08:55:49 +0100 hdu r269994 : #i100521# prefer osl_getAsciiFunctionSymbol() when dynloading LUNA symbols 2009-03-24 16:15:54 +0100 hdu r269965 : #i100521# prefer osl_getAsciiFunctionSymbol() when dynloading vclplugin symbols 2009-03-24 16:10:29 +0100 hdu r269963 : #i100521# prefer osl_getAsciiFunctionSymbol() when dynloading USP symbols 2009-03-24 15:54:30 +0100 hdu r269962 : #i100521# prefer osl_getAsciiFunctionSymbol() when dynloading xrender symbols 2009-03-24 10:46:55 +0100 hdu r269920 : #i100506# fix WAE build breakers on unxsols4 for debug=true 2009-03-23 16:36:43 +0100 hdu r269884 : #159477# fix crash for PDFs with big zlib-chunks 2009-03-20 17:36:56 +0100 pl r269821 : #i96568# add recent files to mac quickstarter 2009-03-20 14:39:41 +0100 pl r269809 : #i35482# no HC mode detection, automatically done in independent part 2009-03-19 20:01:37 +0100 pl r269768 : #i95591# do not reuse UnxPloginComm because of connection loss problems 2009-03-19 18:08:23 +0100 pl r269765 : #i95588# change default visibility that was ignored everywhere but unix anyway
2009-06-03 15:45:09 +00:00
return ::vcl::unotools::integerSize2DFromSize( mpBackBuffer->getBitmapSizePixel() );
}
void CanvasBitmapHelper::clear()
{
// are we disposed?
if( mpBackBuffer )
mpBackBuffer->clear(); // alpha vdev needs special treatment
}
uno::Reference< rendering::XBitmap > CanvasBitmapHelper::getScaledBitmap( const geometry::RealSize2D& newSize,
sal_Bool beFast )
{
ENSURE_OR_THROW( mpDevice,
"disposed CanvasHelper" );
RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getScaledBitmap()" );
if( !mpBackBuffer || mpDevice )
return uno::Reference< rendering::XBitmap >(); // we're disposed
BitmapEx aRes( mpBackBuffer->getBitmapReference() );
aRes.Scale( ::vcl::unotools::sizeFromRealSize2D(newSize),
beFast ? BMP_SCALE_DEFAULT : BMP_SCALE_BESTQUALITY );
return uno::Reference< rendering::XBitmap >(
new CanvasBitmap( aRes, *mpDevice, mpOutDevReference ) );
}
uno::Sequence< sal_Int8 > CanvasBitmapHelper::getData( rendering::IntegerBitmapLayout& rLayout,
const geometry::IntegerRectangle2D& rect )
{
RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getData()" );
if( !mpBackBuffer )
return uno::Sequence< sal_Int8 >(); // we're disposed
rLayout = getMemoryLayout();
Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
Bitmap::ScopedReadAccess pReadAccess( aBitmap );
Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
(BitmapReadAccess*)NULL : aAlpha.AcquireReadAccess(),
aAlpha );
ENSURE_OR_THROW( pReadAccess.get() != NULL,
"Could not acquire read access to bitmap" );
// TODO(F1): Support more formats.
const Size aBmpSize( aBitmap.GetSizePixel() );
rLayout.ScanLines = aBmpSize.Height();
rLayout.ScanLineBytes = aBmpSize.Width()*4;
rLayout.ScanLineStride = rLayout.ScanLineBytes;
// for the time being, always return as BGRA
uno::Sequence< sal_Int8 > aRes( 4*aBmpSize.Width()*aBmpSize.Height() );
sal_Int8* pRes = aRes.getArray();
int nCurrPos(0);
for( int y=rect.Y1;
y<aBmpSize.Height() && y<rect.Y2;
++y )
{
if( pAlphaReadAccess.get() != NULL )
{
for( int x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
pRes[ nCurrPos++ ] = pAlphaReadAccess->GetPixel( y, x ).GetIndex();
}
}
else
{
for( int x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
pRes[ nCurrPos++ ] = sal_uInt8(255);
}
}
}
return aRes;
}
void CanvasBitmapHelper::setData( const uno::Sequence< sal_Int8 >& data,
const rendering::IntegerBitmapLayout& rLayout,
const geometry::IntegerRectangle2D& rect )
{
RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::setData()" );
if( !mpBackBuffer )
return; // we're disposed
const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() );
ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != rLayout.PlaneStride ||
aRefLayout.ColorSpace != rLayout.ColorSpace ||
aRefLayout.Palette != rLayout.Palette ||
aRefLayout.IsMsbFirst != rLayout.IsMsbFirst,
"Mismatching memory layout" );
// retrieve local copies from the BitmapEx, which are later
// stored back. Unfortunately, the BitmapEx does not permit
// in-place modifications, as they are necessary here.
Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
bool bCopyBack( false ); // only copy something back, if we
// actually changed a pixel
{
Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ?
(BitmapWriteAccess*)NULL : aAlpha.AcquireWriteAccess(),
aAlpha );
if( pAlphaWriteAccess.get() )
{
DBG_ASSERT( pAlphaWriteAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
pAlphaWriteAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
"non-8bit alpha not supported!" );
}
ENSURE_OR_THROW( pWriteAccess.get() != NULL,
"Could not acquire write access to bitmap" );
// TODO(F1): Support more formats.
const Size aBmpSize( aBitmap.GetSizePixel() );
// for the time being, always read as BGRA
int x, y, nCurrPos(0);
for( y=rect.Y1;
y<aBmpSize.Height() && y<rect.Y2;
++y )
{
if( pAlphaWriteAccess.get() != NULL )
{
switch( pWriteAccess->GetScanlineFormat() )
{
case BMP_FORMAT_8BIT_PAL:
{
Scanline pScan = pWriteAccess->GetScanline( y );
Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = (sal_uInt8)pWriteAccess->GetBestPaletteIndex(
BitmapColor( data[ nCurrPos ],
data[ nCurrPos+1 ],
data[ nCurrPos+2 ] ) );
nCurrPos += 3;
// cast to unsigned byte, for correct subtraction result
*pAScan++ = static_cast<sal_uInt8>(255 -
static_cast<sal_uInt8>(data[ nCurrPos++ ]));
}
}
break;
case BMP_FORMAT_24BIT_TC_BGR:
{
Scanline pScan = pWriteAccess->GetScanline( y );
Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = data[ nCurrPos+2 ];
*pScan++ = data[ nCurrPos+1 ];
*pScan++ = data[ nCurrPos ];
nCurrPos += 3;
// cast to unsigned byte, for correct subtraction result
*pAScan++ = static_cast<sal_uInt8>(255 -
static_cast<sal_uInt8>(data[ nCurrPos++ ]));
}
}
break;
case BMP_FORMAT_24BIT_TC_RGB:
{
Scanline pScan = pWriteAccess->GetScanline( y );
Scanline pAScan = pAlphaWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = data[ nCurrPos ];
*pScan++ = data[ nCurrPos+1 ];
*pScan++ = data[ nCurrPos+2 ];
nCurrPos += 3;
// cast to unsigned byte, for correct subtraction result
*pAScan++ = static_cast<sal_uInt8>(255 -
static_cast<sal_uInt8>(data[ nCurrPos++ ]));
}
}
break;
default:
{
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos ],
data[ nCurrPos+1 ],
data[ nCurrPos+2 ] ) );
nCurrPos += 3;
// cast to unsigned byte, for correct subtraction result
pAlphaWriteAccess->SetPixel( y, x,
BitmapColor(
static_cast<sal_uInt8>(255 -
static_cast<sal_uInt8>(data[ nCurrPos++ ])) ) );
}
}
break;
}
}
else
{
// TODO(Q3): This is copy'n'pasted from
// canvashelper.cxx, unify!
switch( pWriteAccess->GetScanlineFormat() )
{
case BMP_FORMAT_8BIT_PAL:
{
Scanline pScan = pWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = (sal_uInt8)pWriteAccess->GetBestPaletteIndex(
BitmapColor( data[ nCurrPos ],
data[ nCurrPos+1 ],
data[ nCurrPos+2 ] ) );
nCurrPos += 4; // skip three colors, _plus_ alpha
}
}
break;
case BMP_FORMAT_24BIT_TC_BGR:
{
Scanline pScan = pWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = data[ nCurrPos+2 ];
*pScan++ = data[ nCurrPos+1 ];
*pScan++ = data[ nCurrPos ];
nCurrPos += 4; // skip three colors, _plus_ alpha
}
}
break;
case BMP_FORMAT_24BIT_TC_RGB:
{
Scanline pScan = pWriteAccess->GetScanline( y );
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
*pScan++ = data[ nCurrPos ];
*pScan++ = data[ nCurrPos+1 ];
*pScan++ = data[ nCurrPos+2 ];
nCurrPos += 4; // skip three colors, _plus_ alpha
}
}
break;
default:
{
for( x=rect.X1;
x<aBmpSize.Width() && x<rect.X2;
++x )
{
pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos ],
data[ nCurrPos+1 ],
data[ nCurrPos+2 ] ) );
nCurrPos += 4; // skip three colors, _plus_ alpha
}
}
break;
}
}
bCopyBack = true;
}
}
// copy back only here, since the BitmapAccessors must be
// destroyed beforehand
if( bCopyBack )
{
if( aAlpha.IsEmpty() )
setBitmap( BitmapEx( aBitmap ) );
else
setBitmap( BitmapEx( aBitmap,
AlphaMask( aAlpha ) ) );
}
}
void CanvasBitmapHelper::setPixel( const uno::Sequence< sal_Int8 >& color,
const rendering::IntegerBitmapLayout& rLayout,
const geometry::IntegerPoint2D& pos )
{
RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::setPixel()" );
if( !mpBackBuffer )
return; // we're disposed
const Size aBmpSize( mpBackBuffer->getBitmapReference().GetSizePixel() );
ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(),
"X coordinate out of bounds" );
ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(),
"Y coordinate out of bounds" );
ENSURE_ARG_OR_THROW( color.getLength() > 3,
"not enough color components" );
const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() );
ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != rLayout.PlaneStride ||
aRefLayout.ColorSpace != rLayout.ColorSpace ||
aRefLayout.Palette != rLayout.Palette ||
aRefLayout.IsMsbFirst != rLayout.IsMsbFirst,
"Mismatching memory layout" );
// retrieve local copies from the BitmapEx, which are later
// stored back. Unfortunately, the BitmapEx does not permit
// in-place modifications, as they are necessary here.
Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
bool bCopyBack( false ); // only copy something back, if we
// actually changed a pixel
{
Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
Bitmap::ScopedWriteAccess pAlphaWriteAccess( aAlpha.IsEmpty() ?
(BitmapWriteAccess*)NULL : aAlpha.AcquireWriteAccess(),
aAlpha );
ENSURE_OR_THROW( pWriteAccess.get() != NULL,
"Could not acquire write access to bitmap" );
pWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( color[ 0 ],
color[ 1 ],
color[ 2 ] ) );
if( pAlphaWriteAccess.get() != NULL )
pAlphaWriteAccess->SetPixel( pos.Y, pos.X, BitmapColor( 255 - color[ 3 ] ) );
bCopyBack = true;
}
// copy back only here, since the BitmapAccessors must be
// destroyed beforehand
if( bCopyBack )
{
if( aAlpha.IsEmpty() )
setBitmap( BitmapEx( aBitmap ) );
else
setBitmap( BitmapEx( aBitmap,
AlphaMask( aAlpha ) ) );
}
}
uno::Sequence< sal_Int8 > CanvasBitmapHelper::getPixel( rendering::IntegerBitmapLayout& rLayout,
const geometry::IntegerPoint2D& pos )
{
RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::CanvasBitmapHelper::getPixel()" );
if( !mpBackBuffer )
return uno::Sequence< sal_Int8 >(); // we're disposed
rLayout = getMemoryLayout();
rLayout.ScanLines = 1;
rLayout.ScanLineBytes = 4;
rLayout.ScanLineStride = rLayout.ScanLineBytes;
const Size aBmpSize( mpBackBuffer->getBitmapReference().GetSizePixel() );
ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(),
"X coordinate out of bounds" );
ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(),
"Y coordinate out of bounds" );
Bitmap aBitmap( mpBackBuffer->getBitmapReference().GetBitmap() );
Bitmap aAlpha( mpBackBuffer->getBitmapReference().GetAlpha().GetBitmap() );
Bitmap::ScopedReadAccess pReadAccess( aBitmap );
Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
(BitmapReadAccess*)NULL : aAlpha.AcquireReadAccess(),
aAlpha );
ENSURE_OR_THROW( pReadAccess.get() != NULL,
"Could not acquire read access to bitmap" );
uno::Sequence< sal_Int8 > aRes( 4 );
sal_Int8* pRes = aRes.getArray();
const BitmapColor aColor( pReadAccess->GetColor( pos.Y, pos.X ) );
pRes[ 0 ] = aColor.GetRed();
pRes[ 1 ] = aColor.GetGreen();
pRes[ 2 ] = aColor.GetBlue();
if( pAlphaReadAccess.get() != NULL )
pRes[ 3 ] = pAlphaReadAccess->GetPixel( pos.Y, pos.X ).GetIndex();
else
pRes[ 3 ] = sal_uInt8(255);
return aRes;
}
rendering::IntegerBitmapLayout CanvasBitmapHelper::getMemoryLayout()
{
if( !mpOutDev.get() )
return rendering::IntegerBitmapLayout(); // we're disposed
rendering::IntegerBitmapLayout xBitmapLayout( ::canvas::tools::getStdMemoryLayout(getSize()) );
if ( !hasAlpha() )
xBitmapLayout.ColorSpace = canvas::tools::getStdColorSpaceWithoutAlpha();
return xBitmapLayout;
}
BitmapEx CanvasBitmapHelper::getBitmap() const
{
if( !mpBackBuffer )
return BitmapEx(); // we're disposed
else
return mpBackBuffer->getBitmapReference();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */