INTEGRATION: CWS canvas05 (1.3.68); FILE MERGED

2008/05/21 13:32:03 thb 1.3.68.10: Made vcl and cairo canvas work with emf+ patches; smoothed out internal cairo makefile changes; corrected cairocanvas sprite update
2008/04/21 07:32:10 thb 1.3.68.9: RESYNC: (1.3-1.4); FILE MERGED
2008/04/16 13:47:38 thb 1.3.68.8: Made cairocanvas build on Win32 again
2008/04/10 21:18:37 mox 1.3.68.7: Making cairo quartz buildable. Some pieces still missing.
2008/04/04 22:08:33 thb 1.3.68.6: Fixed output of bezier polygons for cairo; fixed missing surfaces here and there; removed useless refcounted SurfaceProvider arguments (that lead to premature canvas death, as called during ctor)
2008/04/02 22:56:26 thb 1.3.68.5: Reworked Surface class to abstract interface; changed all manual refcount handling to RAII
2008/03/18 22:00:55 thb 1.3.68.4: Implementing non-backbuffered canvas for cairocanvas as well - reworked to share most of the code
2008/03/13 22:48:50 thb 1.3.68.3: merging in remaining ooo-build cairocanvas fixes; completing std color space implementation
2007/12/20 22:18:56 thb 1.3.68.2: #i81092# #i78888# #i78925# #i79258# #i79437# #i84784# Large canvas rework, completing various areas such as color spaces, bitmap data access, true sprite and non-sprite implementations, and upstreaming the canvas parts of rodos emf+ rendering
2007/10/01 13:02:01 thb 1.3.68.1: #i78888# #i78925# #i79258# #i79437# Merge from CWS picom
This commit is contained in:
Kurt Zenker 2008-06-24 09:19:20 +00:00
parent dbfa909d5f
commit e2ca3a417c

View file

@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: cairo_canvasbitmap.cxx,v $
* $Revision: 1.4 $
* $Revision: 1.5 $
*
* This file is part of OpenOffice.org.
*
@ -33,64 +33,238 @@
#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>
#include <tools/diagnose_ex.h>
#include "cairo_canvasbitmap.hxx"
#ifdef CAIRO_HAS_XLIB_SURFACE
# include "cairo_xlib_cairo.hxx"
#elif defined CAIRO_HAS_QUARTZ_SURFACE
# include "cairo_quartz_cairo.hxx"
#elif defined CAIRO_HAS_WIN32_SURFACE
# include "cairo_win32_cairo.hxx"
# include <cairo-win32.h>
#else
# error Native API needed.
#endif
using namespace ::cairo;
using namespace ::com::sun::star;
#ifdef CAIRO_HAS_WIN32_SURFACE
namespace
{
HBITMAP surface2HBitmap( const SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize )
{
// cant seem to retrieve HBITMAP from cairo. copy content then
HDC hScreenDC=GetDC(NULL);
HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC,
rSize.getX(),
rSize.getY() );
HDC hBmpDC = CreateCompatibleDC( 0 );
HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hBmpBitmap );
BitBlt( hBmpDC, 0, 0, rSize.getX(), rSize.getX(),
cairo_win32_surface_get_dc(rSurface->getCairoSurface().get()),
0, 0, SRCCOPY );
SelectObject( hBmpDC, hBmpOld );
DeleteDC( hBmpDC );
return hBmpBitmap;
}
}
#endif
namespace cairocanvas
{
CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize& rSize,
const DeviceRef& rDevice,
bool bHasAlpha ) :
mpDevice( rDevice )
CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize& rSize,
const SurfaceProviderRef& rSurfaceProvider,
rendering::XGraphicDevice* pDevice,
bool bHasAlpha ) :
mpSurfaceProvider( rSurfaceProvider ),
mpBufferSurface(),
mpBufferCairo(),
maSize(rSize),
mbHasAlpha(bHasAlpha)
{
ENSURE_AND_THROW( mpDevice.is(),
ENSURE_OR_THROW( mpSurfaceProvider.is(),
"CanvasBitmap::CanvasBitmap(): Invalid surface or device" );
OSL_TRACE( "bitmap size: %dx%d", rSize.getX(), rSize.getY() );
mpBufferSurface = mpDevice->getSurface( rSize, bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR );
mpBufferSurface = mpSurfaceProvider->createSurface( rSize, bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR );
mpBufferCairo = mpBufferSurface->getCairo();
maCanvasHelper.init( rSize, *mpDevice.get() );
maCanvasHelper.init( rSize, *mpSurfaceProvider, pDevice );
maCanvasHelper.setSurface( mpBufferSurface, bHasAlpha );
mbHasAlpha = bHasAlpha;
// clear bitmap to 100% transparent
maCanvasHelper.clear();
}
void SAL_CALL CanvasBitmap::disposing()
{
mpDevice.clear();
mpSurfaceProvider.clear();
if( mpBufferCairo ) {
cairo_destroy( mpBufferCairo );
mpBufferCairo = NULL;
}
if( mpBufferSurface ) {
mpBufferSurface->Unref();
mpBufferSurface = NULL;
}
mpBufferCairo.reset();
mpBufferSurface.reset();
// forward to parent
CanvasBitmap_Base::disposing();
}
Surface* CanvasBitmap::getSurface()
SurfaceSharedPtr CanvasBitmap::getSurface()
{
return mpBufferSurface;
}
bool CanvasBitmap::repaint( Surface* pSurface,
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
SurfaceSharedPtr CanvasBitmap::createSurface( const ::basegfx::B2ISize& rSize, Content aContent )
{
return mpSurfaceProvider->createSurface(rSize,aContent);
}
SurfaceSharedPtr CanvasBitmap::createSurface( ::Bitmap& rBitmap )
{
return mpSurfaceProvider->createSurface(rBitmap);
}
SurfaceSharedPtr CanvasBitmap::changeSurface( bool, bool )
{
// non-modifiable surface here
return SurfaceSharedPtr();
}
OutputDevice* CanvasBitmap::getOutputDevice()
{
return mpSurfaceProvider->getOutputDevice();
}
bool CanvasBitmap::repaint( const SurfaceSharedPtr& pSurface,
const rendering::ViewState& viewState,
const rendering::RenderState& renderState )
{
return maCanvasHelper.repaint( pSurface, viewState, renderState );
}
uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle ) throw (uno::RuntimeException)
{
uno::Any aRV( sal_Int32(0) );
// 0 ... get BitmapEx
// 1 ... get Pixbuf with bitmap RGB content
// 2 ... get Pixbuf with bitmap alpha mask
switch( nHandle )
{
case 0:
{
aRV = uno::Any( reinterpret_cast<sal_Int64>( (BitmapEx*) NULL ) );
break;
}
case 1:
{
#ifdef CAIRO_HAS_XLIB_SURFACE
X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(mpBufferSurface.get());
OSL_ASSERT(pXlibSurface);
uno::Sequence< uno::Any > args( 3 );
args[0] = uno::Any( false ); // do not call XFreePixmap on it
args[1] = uno::Any( pXlibSurface->getPixmap()->mhDrawable );
args[2] = uno::Any( sal_Int32( pXlibSurface->getDepth() ) );
aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
QuartzSurface* pQuartzSurface = dynamic_cast<QuartzSurface*>(mpBufferSurface.get());
OSL_ASSERT(pQuartzSurface);
uno::Sequence< uno::Any > args( 1 );
args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
// TODO(F2): check whether under all circumstances,
// the alpha channel is ignored here.
uno::Sequence< uno::Any > args( 1 );
args[1] = uno::Any( sal_Int64(surface2HBitmap(mpBufferSurface,maSize)) );
aRV = uno::Any( args );
// caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
break;
}
case 2:
{
#ifdef CAIRO_HAS_XLIB_SURFACE
uno::Sequence< uno::Any > args( 3 );
SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
CairoSharedPtr pAlphaCairo = pAlphaSurface->getCairo();
X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(pAlphaSurface.get());
OSL_ASSERT(pXlibSurface);
// create RGB image (levels of gray) of alpha channel of original picture
cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_paint( pAlphaCairo.get() );
cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
cairo_paint( pAlphaCairo.get() );
pAlphaCairo.reset();
X11PixmapSharedPtr pPixmap = pXlibSurface->getPixmap();
args[0] = uno::Any( true );
args[1] = ::com::sun::star::uno::Any( pPixmap->mhDrawable );
args[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface->getDepth () ) );
pPixmap->clear(); // caller takes ownership of pixmap
// return pixmap and alphachannel pixmap - it will be used in BitmapEx
aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
CairoSharedPtr pAlphaCairo = pAlphaSurface->getCairo();
QuartzSurface* pQuartzSurface=dynamic_cast<QuartzSurface*>(pAlphaSurface.get());
OSL_ASSERT(pQuartzSurface);
// create RGB image (levels of gray) of alpha channel of original picture
cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_paint( pAlphaCairo.get() );
cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
cairo_paint( pAlphaCairo.get() );
pAlphaCairo.reset();
uno::Sequence< uno::Any > args( 1 );
args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
// return ??? and alphachannel ??? - it will be used in BitmapEx
aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
CairoSharedPtr pAlphaCairo = pAlphaSurface->getCairo();
// create RGB image (levels of gray) of alpha channel of original picture
cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_paint( pAlphaCairo.get() );
cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
cairo_paint( pAlphaCairo.get() );
pAlphaCairo.reset();
// cant seem to retrieve HBITMAP from cairo. copy content then
uno::Sequence< uno::Any > args( 1 );
args[1] = uno::Any( sal_Int64(surface2HBitmap(pAlphaSurface,maSize)) );
aRV = uno::Any( args );
// caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
break;
}
}
return aRV;
}
#define IMPLEMENTATION_NAME "CairoCanvas.CanvasBitmap"
#define SERVICE_NAME "com.sun.star.rendering.CanvasBitmap"