Update ooo320-m1
[ooovba.git] / canvas / source / cairo / cairo_quartz_cairo.cxx
blob3d2ac7fa908624764feb393e61a28057d0b031ba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cairo_quartz_cairo.cxx,v $
10 * $Revision: 1.4 $
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 #ifdef QUARTZ
35 /************************************************************************
36 * Mac OS X/Quartz surface backend for OpenOffice.org Cairo Canvas *
37 ************************************************************************/
39 #include <osl/diagnose.h>
40 #include <vcl/sysdata.hxx>
41 #include <vcl/bitmap.hxx>
42 #include <vcl/virdev.hxx>
44 #include "cairo_cairo.hxx"
46 #if defined CAIRO_HAS_QUARTZ_SURFACE
48 #include "cairo_quartz_cairo.hxx"
50 namespace cairo
52 bool IsCairoWorking( OutputDevice* )
54 // trivially true for Mac
55 return true;
58 /**
59 * QuartzSurface::Surface: Create generic Canvas surface using given Cairo Surface
61 * @param pSurface Cairo Surface
63 * This constructor only stores data, it does no processing.
64 * It is used with e.g. cairo_image_surface_create_for_data()
65 * and QuartzSurface::getSimilar()
67 * Set the mpSurface to the new surface or NULL
68 **/
69 QuartzSurface::QuartzSurface( const CairoSurfaceSharedPtr& pSurface ) :
70 mpView(NULL),
71 mpSurface( pSurface )
73 // Necessary, context is lost otherwise
74 CGContextRetain( getCGContext() ); // == NULL for non-native surfaces
77 /**
78 * QuartzSurface::Surface: Create Canvas surface from Window reference.
79 * @param NSView
80 * @param x horizontal location of the new surface
81 * @param y vertical location of the new surface
82 * @param width width of the new surface
83 * @param height height of the new surface
85 * pSysData contains the platform native Window reference.
86 * pSysData is used to create a surface on the Window
88 * Set the mpSurface to the new surface or NULL
89 **/
90 QuartzSurface::QuartzSurface( NSView* pView, int x, int y, int width, int height ) :
91 mpView(pView),
92 mpSurface()
94 OSL_TRACE("Canvas::cairo::Surface(NSView*, x:%d, y:%d, w:%d, h:%d): New Surface for window", x, y, width, height);
96 // on Mac OS X / Quartz we are not drawing directly to the screen, but via regular CGContextRef.
97 // The actual drawing to NSView (i.e. screen) is done in QuartzSurface::flush()
99 // HACK: currently initial size for windowsurface is 0x0, which is not possible for us.
100 if (width == 0 || height == 0) {
101 width = [mpView bounds].size.width;
102 height = [mpView bounds].size.height;
103 OSL_TRACE("Canvas::cairo::Surface(): BUG!! size is ZERO! fixing to %d x %d...", width, height);
106 // create a generic surface, NSView/Window is ARGB32.
107 mpSurface.reset(
108 cairo_quartz_surface_create(CAIRO_FORMAT_ARGB32, width, height),
109 &cairo_surface_destroy);
111 cairo_surface_set_device_offset( mpSurface.get(), x, y );
115 * QuartzSurface::Surface: Create Canvas surface from CGContextRef.
116 * @param CGContext Native graphics context
117 * @param x horizontal location of the new surface
118 * @param y vertical location of the new surface
119 * @param width width of the new surface
120 * @param height height of the new surface
122 * Set the mpSurface to the new surface or NULL
124 QuartzSurface::QuartzSurface( CGContextRef rContext, int x, int y, int width, int height ) :
125 mpView(NULL),
126 mpSurface()
128 OSL_TRACE("Canvas::cairo::Surface(CGContext:%p, x:%d, y:%d, w:%d, h:%d): New Surface.", rContext, x, y, width, height);
129 // create surface based on CGContext
131 // ensure kCGBitmapByteOrder32Host flag, otherwise Cairo breaks (we are practically always using CGBitmapContext)
132 OSL_ASSERT ((CGBitmapContextGetBitsPerPixel(rContext) != 32) ||
133 (CGBitmapContextGetBitmapInfo(rContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host);
135 mpSurface.reset(cairo_quartz_surface_create_for_cg_context(rContext, width, height),
136 &cairo_surface_destroy);
138 cairo_surface_set_device_offset( mpSurface.get(), x, y );
140 // Necessary, context is lost otherwise
141 CGContextRetain(rContext);
146 * QuartzSurface::getCairo: Create Cairo (drawing object) for the Canvas surface
148 * @return new Cairo or NULL
150 CairoSharedPtr QuartzSurface::getCairo() const
152 if (mpSurface.get()){
153 return CairoSharedPtr( cairo_create(mpSurface.get()),
154 &cairo_destroy );
155 } else {
156 return CairoSharedPtr();
161 * QuartzSurface::getSimilar: Create new similar Canvas surface
162 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
163 * @param width width of the new surface
164 * @param height height of the new surface
166 * Creates a new Canvas surface. This normally creates platform native surface, even though
167 * generic function is used.
169 * Cairo surface from aContent (cairo_content_t)
171 * @return new surface or NULL
172 **/
173 SurfaceSharedPtr QuartzSurface::getSimilar( Content aContent, int width, int height ) const
175 return SurfaceSharedPtr(
176 new QuartzSurface(
177 CairoSurfaceSharedPtr(
178 cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
179 &cairo_surface_destroy )));
183 * QuartzSurface::Resize: Resizes the Canvas surface.
184 * @param width new width of the surface
185 * @param height new height of the surface
187 * Only used on X11.
189 * @return The new surface or NULL
191 void QuartzSurface::Resize( int width, int height )
193 OSL_ENSURE(false,"not supposed to be called!");
198 * QuartzSurface::flush: Draw the data to screen
200 void QuartzSurface::flush() const
202 // can only flush surfaces with NSView
203 if( !mpView ) return;
205 OSL_TRACE("Canvas::cairo::QuartzSurface::flush(): flush to NSView");
207 CGContextRef mrContext = getCGContext();
209 if (!mrContext) return;
211 [mpView lockFocus];
214 * This code is using same screen update code as in VCL (esp. AquaSalGraphics::UpdateWindow() )
216 CGContextRef rViewContext = reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
217 CGImageRef xImage = CGBitmapContextCreateImage(mrContext);
218 CGContextDrawImage(rViewContext,
219 CGRectMake( 0, 0,
220 CGImageGetWidth(xImage),
221 CGImageGetHeight(xImage)),
222 xImage);
223 CGImageRelease( xImage );
224 CGContextFlush( rViewContext );
226 [mpView unlockFocus];
230 * QuartzSurface::getDepth: Get the color depth of the Canvas surface.
232 * @return color depth
234 int QuartzSurface::getDepth() const
236 if (mpSurface.get()) {
237 switch (cairo_surface_get_content (mpSurface.get())) {
238 case CAIRO_CONTENT_ALPHA: return 8; break;
239 case CAIRO_CONTENT_COLOR: return 24; break;
240 case CAIRO_CONTENT_COLOR_ALPHA: return 32; break;
243 OSL_TRACE("Canvas::cairo::QuartzSurface::getDepth(): ERROR - depth unspecified!");
245 return -1;
249 * QuartzSurface::getCGContext: Get the native CGContextRef of the Canvas's cairo surface
251 * @return graphics context
253 CGContextRef QuartzSurface::getCGContext() const
255 if (mpSurface.get())
256 return cairo_quartz_surface_get_cg_context(mpSurface.get());
257 else
258 return NULL;
262 * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface
264 * @return The new virtual device
266 boost::shared_ptr<VirtualDevice> QuartzSurface::createVirtualDevice() const
268 SystemGraphicsData aSystemGraphicsData;
269 aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
270 aSystemGraphicsData.rCGContext = getCGContext();
271 return boost::shared_ptr<VirtualDevice>(
272 new VirtualDevice( &aSystemGraphicsData, getDepth() ));
276 * cairo::createSurface: Create generic Canvas surface using given Cairo Surface
278 * @param rSurface Cairo Surface
280 * @return new Surface
282 SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
284 return SurfaceSharedPtr(new QuartzSurface(rSurface));
288 * cairo::createSurface: Create Canvas surface using given VCL Window or Virtualdevice
290 * @param rSurface Cairo Surface
292 * For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
293 * For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx)
295 * @return new Surface
297 SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice,
298 int x, int y, int width, int height )
300 SurfaceSharedPtr surf;
302 if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
304 const Window &rWindow = (const Window &) rRefDevice;
305 const SystemEnvData* pSysData = GetSysData(&rWindow);
306 if (pSysData)
307 surf = SurfaceSharedPtr(new QuartzSurface(pSysData->pView, x, y, width, height));
309 else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
311 SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData();
313 if (aSysData.rCGContext)
314 surf = SurfaceSharedPtr(new QuartzSurface(aSysData.rCGContext, x, y, width, height));
316 return surf;
320 * cairo::createBitmapSurface: Create platfrom native Canvas surface from BitmapSystemData
321 * @param OutputDevice (not used)
322 * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
323 * @param rSize width and height of the new surface
325 * Create a surface based on image data on rData
327 * @return new surface or empty surface
329 SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */,
330 const BitmapSystemData& rData,
331 const Size& rSize )
333 OSL_TRACE( "requested size: %d x %d available size: %d x %d",
334 rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
336 if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
338 CGContextRef rContext = (CGContextRef)rData.rImageContext;
339 OSL_TRACE("Canvas::cairo::createBitmapSurface(): New native image surface, context = %p.", rData.rImageContext);
341 return SurfaceSharedPtr(new QuartzSurface(rContext, 0, 0, rData.mnWidth, rData.mnHeight));
343 return SurfaceSharedPtr();
346 } // namespace cairo
348 #endif // CAIRO_HAS_QUARTZ_SURFACE
350 #endif // QUARTZ