1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cairo_canvasbitmap.cxx,v $
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_canvas.hxx"
34 #include <canvas/debug.hxx>
35 #include <canvas/canvastools.hxx>
36 #include <tools/diagnose_ex.h>
38 #include "cairo_canvasbitmap.hxx"
40 #ifdef CAIRO_HAS_XLIB_SURFACE
41 # include "cairo_xlib_cairo.hxx"
42 #elif defined CAIRO_HAS_QUARTZ_SURFACE
43 # include "cairo_quartz_cairo.hxx"
44 #elif defined CAIRO_HAS_WIN32_SURFACE
45 # include "cairo_win32_cairo.hxx"
46 # include <cairo-win32.h>
48 # error Native API needed.
51 using namespace ::cairo
;
52 using namespace ::com::sun::star
;
54 #ifdef CAIRO_HAS_WIN32_SURFACE
57 HBITMAP
surface2HBitmap( const SurfaceSharedPtr
& rSurface
, const basegfx::B2ISize
& rSize
)
59 // cant seem to retrieve HBITMAP from cairo. copy content then
60 HDC hScreenDC
=GetDC(NULL
);
61 HBITMAP hBmpBitmap
= CreateCompatibleBitmap( hScreenDC
,
65 HDC hBmpDC
= CreateCompatibleDC( 0 );
66 HBITMAP hBmpOld
= (HBITMAP
) SelectObject( hBmpDC
, hBmpBitmap
);
68 BitBlt( hBmpDC
, 0, 0, rSize
.getX(), rSize
.getX(),
69 cairo_win32_surface_get_dc(rSurface
->getCairoSurface().get()),
72 SelectObject( hBmpDC
, hBmpOld
);
82 CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize
& rSize
,
83 const SurfaceProviderRef
& rSurfaceProvider
,
84 rendering::XGraphicDevice
* pDevice
,
86 mpSurfaceProvider( rSurfaceProvider
),
92 ENSURE_OR_THROW( mpSurfaceProvider
.is(),
93 "CanvasBitmap::CanvasBitmap(): Invalid surface or device" );
95 OSL_TRACE( "bitmap size: %dx%d", rSize
.getX(), rSize
.getY() );
97 mpBufferSurface
= mpSurfaceProvider
->createSurface( rSize
, bHasAlpha
? CAIRO_CONTENT_COLOR_ALPHA
: CAIRO_CONTENT_COLOR
);
98 mpBufferCairo
= mpBufferSurface
->getCairo();
100 maCanvasHelper
.init( rSize
, *mpSurfaceProvider
, pDevice
);
101 maCanvasHelper
.setSurface( mpBufferSurface
, bHasAlpha
);
103 // clear bitmap to 100% transparent
104 maCanvasHelper
.clear();
107 void SAL_CALL
CanvasBitmap::disposing()
109 mpSurfaceProvider
.clear();
111 mpBufferCairo
.reset();
112 mpBufferSurface
.reset();
115 CanvasBitmap_Base::disposing();
118 SurfaceSharedPtr
CanvasBitmap::getSurface()
120 return mpBufferSurface
;
123 SurfaceSharedPtr
CanvasBitmap::createSurface( const ::basegfx::B2ISize
& rSize
, Content aContent
)
125 return mpSurfaceProvider
->createSurface(rSize
,aContent
);
128 SurfaceSharedPtr
CanvasBitmap::createSurface( ::Bitmap
& rBitmap
)
130 return mpSurfaceProvider
->createSurface(rBitmap
);
133 SurfaceSharedPtr
CanvasBitmap::changeSurface( bool, bool )
135 // non-modifiable surface here
136 return SurfaceSharedPtr();
139 OutputDevice
* CanvasBitmap::getOutputDevice()
141 return mpSurfaceProvider
->getOutputDevice();
144 bool CanvasBitmap::repaint( const SurfaceSharedPtr
& pSurface
,
145 const rendering::ViewState
& viewState
,
146 const rendering::RenderState
& renderState
)
148 return maCanvasHelper
.repaint( pSurface
, viewState
, renderState
);
151 uno::Any SAL_CALL
CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle
) throw (uno::RuntimeException
)
153 uno::Any
aRV( sal_Int32(0) );
154 // 0 ... get BitmapEx
155 // 1 ... get Pixbuf with bitmap RGB content
156 // 2 ... get Pixbuf with bitmap alpha mask
161 aRV
= uno::Any( reinterpret_cast<sal_Int64
>( (BitmapEx
*) NULL
) );
166 #ifdef CAIRO_HAS_XLIB_SURFACE
167 X11Surface
* pXlibSurface
=dynamic_cast<X11Surface
*>(mpBufferSurface
.get());
168 OSL_ASSERT(pXlibSurface
);
169 uno::Sequence
< uno::Any
> args( 3 );
170 args
[0] = uno::Any( false ); // do not call XFreePixmap on it
171 args
[1] = uno::Any( pXlibSurface
->getPixmap()->mhDrawable
);
172 args
[2] = uno::Any( sal_Int32( pXlibSurface
->getDepth() ) );
174 aRV
= uno::Any( args
);
175 #elif defined CAIRO_HAS_QUARTZ_SURFACE
176 QuartzSurface
* pQuartzSurface
= dynamic_cast<QuartzSurface
*>(mpBufferSurface
.get());
177 OSL_ASSERT(pQuartzSurface
);
178 uno::Sequence
< uno::Any
> args( 1 );
179 args
[0] = uno::Any( sal_IntPtr (pQuartzSurface
->getCGContext()) );
180 aRV
= uno::Any( args
);
181 #elif defined CAIRO_HAS_WIN32_SURFACE
182 // TODO(F2): check whether under all circumstances,
183 // the alpha channel is ignored here.
184 uno::Sequence
< uno::Any
> args( 1 );
185 args
[1] = uno::Any( sal_Int64(surface2HBitmap(mpBufferSurface
,maSize
)) );
187 aRV
= uno::Any( args
);
188 // caller frees the bitmap
190 # error Please define fast prop retrieval for your platform!
196 #ifdef CAIRO_HAS_XLIB_SURFACE
197 uno::Sequence
< uno::Any
> args( 3 );
198 SurfaceSharedPtr pAlphaSurface
= mpSurfaceProvider
->createSurface( maSize
, CAIRO_CONTENT_COLOR
);
199 CairoSharedPtr pAlphaCairo
= pAlphaSurface
->getCairo();
200 X11Surface
* pXlibSurface
=dynamic_cast<X11Surface
*>(pAlphaSurface
.get());
201 OSL_ASSERT(pXlibSurface
);
203 // create RGB image (levels of gray) of alpha channel of original picture
204 cairo_set_source_rgba( pAlphaCairo
.get(), 1, 1, 1, 1 );
205 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_SOURCE
);
206 cairo_paint( pAlphaCairo
.get() );
207 cairo_set_source_surface( pAlphaCairo
.get(), mpBufferSurface
->getCairoSurface().get(), 0, 0 );
208 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_XOR
);
209 cairo_paint( pAlphaCairo
.get() );
212 X11PixmapSharedPtr pPixmap
= pXlibSurface
->getPixmap();
213 args
[0] = uno::Any( true );
214 args
[1] = ::com::sun::star::uno::Any( pPixmap
->mhDrawable
);
215 args
[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface
->getDepth () ) );
216 pPixmap
->clear(); // caller takes ownership of pixmap
218 // return pixmap and alphachannel pixmap - it will be used in BitmapEx
219 aRV
= uno::Any( args
);
220 #elif defined CAIRO_HAS_QUARTZ_SURFACE
221 SurfaceSharedPtr pAlphaSurface
= mpSurfaceProvider
->createSurface( maSize
, CAIRO_CONTENT_COLOR
);
222 CairoSharedPtr pAlphaCairo
= pAlphaSurface
->getCairo();
223 QuartzSurface
* pQuartzSurface
=dynamic_cast<QuartzSurface
*>(pAlphaSurface
.get());
224 OSL_ASSERT(pQuartzSurface
);
226 // create RGB image (levels of gray) of alpha channel of original picture
227 cairo_set_source_rgba( pAlphaCairo
.get(), 1, 1, 1, 1 );
228 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_SOURCE
);
229 cairo_paint( pAlphaCairo
.get() );
230 cairo_set_source_surface( pAlphaCairo
.get(), mpBufferSurface
->getCairoSurface().get(), 0, 0 );
231 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_XOR
);
232 cairo_paint( pAlphaCairo
.get() );
235 uno::Sequence
< uno::Any
> args( 1 );
236 args
[0] = uno::Any( sal_IntPtr (pQuartzSurface
->getCGContext()) );
237 // return ??? and alphachannel ??? - it will be used in BitmapEx
238 aRV
= uno::Any( args
);
239 #elif defined CAIRO_HAS_WIN32_SURFACE
240 SurfaceSharedPtr pAlphaSurface
= mpSurfaceProvider
->createSurface( maSize
, CAIRO_CONTENT_COLOR
);
241 CairoSharedPtr pAlphaCairo
= pAlphaSurface
->getCairo();
243 // create RGB image (levels of gray) of alpha channel of original picture
244 cairo_set_source_rgba( pAlphaCairo
.get(), 1, 1, 1, 1 );
245 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_SOURCE
);
246 cairo_paint( pAlphaCairo
.get() );
247 cairo_set_source_surface( pAlphaCairo
.get(), mpBufferSurface
->getCairoSurface().get(), 0, 0 );
248 cairo_set_operator( pAlphaCairo
.get(), CAIRO_OPERATOR_XOR
);
249 cairo_paint( pAlphaCairo
.get() );
252 // cant seem to retrieve HBITMAP from cairo. copy content then
253 uno::Sequence
< uno::Any
> args( 1 );
254 args
[1] = uno::Any( sal_Int64(surface2HBitmap(pAlphaSurface
,maSize
)) );
256 aRV
= uno::Any( args
);
257 // caller frees the bitmap
259 # error Please define fast prop retrieval for your platform!
268 #define IMPLEMENTATION_NAME "CairoCanvas.CanvasBitmap"
269 #define SERVICE_NAME "com.sun.star.rendering.CanvasBitmap"
271 ::rtl::OUString SAL_CALL
CanvasBitmap::getImplementationName( ) throw (uno::RuntimeException
)
273 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME
) );
276 sal_Bool SAL_CALL
CanvasBitmap::supportsService( const ::rtl::OUString
& ServiceName
) throw (uno::RuntimeException
)
278 return ServiceName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME
) );
281 uno::Sequence
< ::rtl::OUString
> SAL_CALL
CanvasBitmap::getSupportedServiceNames( ) throw (uno::RuntimeException
)
283 uno::Sequence
< ::rtl::OUString
> aRet(1);
284 aRet
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME
) );