fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / canvas / source / cairo / cairo_quartz_cairo.cxx
blob9c3d5a065a07e9a3907d4592a03e778fc3c07cdc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #if defined MACOSX || defined IOS
21 /************************************************************************
22 * Mac OS X/Quartz and iOS surface backend for OpenOffice.org Cairo Canvas *
23 ************************************************************************/
25 #include <osl/diagnose.h>
26 #include <vcl/sysdata.hxx>
27 #include <vcl/bitmap.hxx>
28 #include <vcl/virdev.hxx>
30 #include "cairo_cairo.hxx"
32 #if defined CAIRO_HAS_QUARTZ_SURFACE
34 #include "cairo_quartz_cairo.hxx"
36 namespace cairo
38 bool IsCairoWorking( OutputDevice* )
40 // trivially true for Mac
41 return true;
44 /**
45 * QuartzSurface::Surface: Create generic Canvas surface using given Cairo Surface
47 * @param pSurface Cairo Surface
49 * This constructor only stores data, it does no processing.
50 * It is used with e.g. cairo_image_surface_create_for_data()
51 * and QuartzSurface::getSimilar()
53 * Set the mpSurface to the new surface or NULL
54 **/
55 QuartzSurface::QuartzSurface( const CairoSurfaceSharedPtr& pSurface ) :
56 mpView(NULL),
57 mpSurface( pSurface )
59 // Necessary, context is lost otherwise
60 CGContextRetain( getCGContext() ); // == NULL for non-native surfaces
63 /**
64 * QuartzSurface::Surface: Create Canvas surface from Window reference.
65 * @param NSView
66 * @param x horizontal location of the new surface
67 * @param y vertical location of the new surface
68 * @param width width of the new surface
69 * @param height height of the new surface
71 * pSysData contains the platform native Window reference.
72 * pSysData is used to create a surface on the Window
74 * Set the mpSurface to the new surface or NULL
75 **/
76 QuartzSurface::QuartzSurface( NSView* pView, int x, int y, int width, int height ) :
77 mpView(pView),
78 mpSurface()
80 OSL_TRACE("Canvas::cairo::Surface(NSView*, x:%d, y:%d, w:%d, h:%d): New Surface for window", x, y, width, height);
82 // on Mac OS X / Quartz we are not drawing directly to the screen, but via regular CGContextRef.
83 // The actual drawing to NSView (i.e. screen) is done in QuartzSurface::flush()
85 // HACK: currently initial size for windowsurface is 0x0, which is not possible for us.
86 if (width == 0 || height == 0) {
87 width = [mpView bounds].size.width;
88 height = [mpView bounds].size.height;
89 OSL_TRACE("Canvas::cairo::Surface(): BUG!! size is ZERO! fixing to %d x %d...", width, height);
92 // create a generic surface, NSView/Window is ARGB32.
93 mpSurface.reset(
94 cairo_quartz_surface_create(CAIRO_FORMAT_ARGB32, width, height),
95 &cairo_surface_destroy);
97 cairo_surface_set_device_offset( mpSurface.get(), x, y );
101 * QuartzSurface::Surface: Create Canvas surface from CGContextRef.
102 * @param CGContext Native graphics context
103 * @param x horizontal location of the new surface
104 * @param y vertical location of the new surface
105 * @param width width of the new surface
106 * @param height height of the new surface
108 * Set the mpSurface to the new surface or NULL
110 QuartzSurface::QuartzSurface( CGContextRef rContext, int x, int y, int width, int height ) :
111 mpView(NULL),
112 mpSurface()
114 OSL_TRACE("Canvas::cairo::Surface(CGContext:%p, x:%d, y:%d, w:%d, h:%d): New Surface.", rContext, x, y, width, height);
115 // create surface based on CGContext
117 // ensure kCGBitmapByteOrder32Host flag, otherwise Cairo breaks (we are practically always using CGBitmapContext)
118 OSL_ASSERT ((CGBitmapContextGetBitsPerPixel(rContext) != 32) ||
119 (CGBitmapContextGetBitmapInfo(rContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host);
121 mpSurface.reset(cairo_quartz_surface_create_for_cg_context(rContext, width, height),
122 &cairo_surface_destroy);
124 cairo_surface_set_device_offset( mpSurface.get(), x, y );
126 // Necessary, context is lost otherwise
127 CGContextRetain(rContext);
132 * QuartzSurface::getCairo: Create Cairo (drawing object) for the Canvas surface
134 * @return new Cairo or NULL
136 CairoSharedPtr QuartzSurface::getCairo() const
138 if (mpSurface.get())
140 return CairoSharedPtr( cairo_create(mpSurface.get()),
141 &cairo_destroy );
143 else
145 return CairoSharedPtr();
150 * QuartzSurface::getSimilar: Create new similar Canvas surface
151 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
152 * @param width width of the new surface
153 * @param height height of the new surface
155 * Creates a new Canvas surface. This normally creates platform native surface, even though
156 * generic function is used.
158 * Cairo surface from aContent (cairo_content_t)
160 * @return new surface or NULL
162 SurfaceSharedPtr QuartzSurface::getSimilar( Content aContent, int width, int height ) const
164 return SurfaceSharedPtr(
165 new QuartzSurface(
166 CairoSurfaceSharedPtr(
167 cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
168 &cairo_surface_destroy )));
172 * QuartzSurface::Resize: Resizes the Canvas surface.
173 * @param width new width of the surface
174 * @param height new height of the surface
176 * Only used on X11.
178 * @return The new surface or NULL
180 void QuartzSurface::Resize( int /* width */, int /* height */ )
182 OSL_FAIL("not supposed to be called!");
187 * QuartzSurface::flush: Draw the data to screen
189 void QuartzSurface::flush() const
191 // can only flush surfaces with NSView
192 if( !mpView )
193 return;
195 OSL_TRACE("Canvas::cairo::QuartzSurface::flush(): flush to NSView");
197 CGContextRef mrContext = getCGContext();
199 if (!mrContext)
200 return;
201 #ifndef IOS
202 [mpView lockFocus];
203 #endif
205 #ifndef IOS
207 * This code is using same screen update code as in VCL (esp. AquaSalGraphics::UpdateWindow() )
209 CGContextRef rViewContext = reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
210 #else
211 // Just guessing for now...
212 CGContextRef rViewContext = UIGraphicsGetCurrentContext();
213 #endif
214 CGImageRef xImage = CGBitmapContextCreateImage(mrContext);
215 CGContextDrawImage(rViewContext,
216 CGRectMake( 0, 0,
217 CGImageGetWidth(xImage),
218 CGImageGetHeight(xImage)),
219 xImage);
220 CGImageRelease( xImage );
221 CGContextFlush( rViewContext );
222 #ifndef IOS
223 [mpView unlockFocus];
224 #endif
228 * QuartzSurface::getDepth: Get the color depth of the Canvas surface.
230 * @return color depth
232 int QuartzSurface::getDepth() const
234 if (mpSurface.get())
236 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
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */