Linux x86 build fix
[LibreOffice.git] / vcl / quartz / cairo_quartz_cairo.cxx
blob0b0835c8fb052656b68f7218c9d73f5c0616e40b
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 #include <config_cairo_canvas.h>
22 #if ENABLE_CAIRO_CANVAS
23 /************************************************************************
24 * Mac OS X/Quartz and iOS surface backend for LibreOffice Cairo Canvas *
25 ************************************************************************/
27 #include <osl/diagnose.h>
28 #include <vcl/sysdata.hxx>
29 #include <vcl/bitmap.hxx>
30 #include <vcl/virdev.hxx>
32 #include "cairo_cairo.hxx"
34 #include <config_cairo_canvas.h>
36 #include "cairo_quartz_cairo.hxx"
38 namespace cairo
40 /**
41 * QuartzSurface::Surface: Create generic Canvas surface using given Cairo Surface
43 * @param pSurface Cairo Surface
45 * This constructor only stores data, it does no processing.
46 * It is used with e.g. cairo_image_surface_create_for_data()
47 * and QuartzSurface::getSimilar()
49 * Set the mpSurface to the new surface or NULL
50 **/
51 QuartzSurface::QuartzSurface( const CairoSurfaceSharedPtr& pSurface ) :
52 mpView(NULL),
53 mpSurface( pSurface )
55 // Necessary, context is lost otherwise
56 CGContextRetain( getCGContext() ); // == NULL for non-native surfaces
59 /**
60 * QuartzSurface::Surface: Create Canvas surface from Window reference.
61 * @param NSView
62 * @param x horizontal location of the new surface
63 * @param y vertical location of the new surface
64 * @param width width of the new surface
65 * @param height height of the new surface
67 * pSysData contains the platform native Window reference.
68 * pSysData is used to create a surface on the Window
70 * Set the mpSurface to the new surface or NULL
71 **/
72 QuartzSurface::QuartzSurface( NSView* pView, int x, int y, int width, int height ) :
73 mpView(pView),
74 mpSurface()
76 OSL_TRACE("Canvas::cairo::Surface(NSView*, x:%d, y:%d, w:%d, h:%d): New Surface for window", x, y, width, height);
78 // on Mac OS X / Quartz we are not drawing directly to the screen, but via regular CGContextRef.
79 // The actual drawing to NSView (i.e. screen) is done in QuartzSurface::flush()
81 // HACK: currently initial size for windowsurface is 0x0, which is not possible for us.
82 if (width == 0 || height == 0) {
83 width = [mpView bounds].size.width;
84 height = [mpView bounds].size.height;
85 OSL_TRACE("Canvas::cairo::Surface(): BUG!! size is ZERO! fixing to %d x %d...", width, height);
88 // create a generic surface, NSView/Window is ARGB32.
89 mpSurface.reset(
90 cairo_quartz_surface_create(CAIRO_FORMAT_ARGB32, width, height),
91 &cairo_surface_destroy);
93 cairo_surface_set_device_offset( mpSurface.get(), x, y );
96 /**
97 * QuartzSurface::Surface: Create Canvas surface from CGContextRef.
98 * @param CGContext Native graphics context
99 * @param x horizontal location of the new surface
100 * @param y vertical location of the new surface
101 * @param width width of the new surface
102 * @param height height of the new surface
104 * Set the mpSurface to the new surface or NULL
106 QuartzSurface::QuartzSurface( CGContextRef rContext, int x, int y, int width, int height ) :
107 mpView(NULL),
108 mpSurface()
110 OSL_TRACE("Canvas::cairo::Surface(CGContext:%p, x:%d, y:%d, w:%d, h:%d): New Surface.", rContext, x, y, width, height);
111 // create surface based on CGContext
113 // ensure kCGBitmapByteOrder32Host flag, otherwise Cairo breaks (we are practically always using CGBitmapContext)
114 OSL_ASSERT ((CGBitmapContextGetBitsPerPixel(rContext) != 32) ||
115 (CGBitmapContextGetBitmapInfo(rContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host);
117 mpSurface.reset(cairo_quartz_surface_create_for_cg_context(rContext, width, height),
118 &cairo_surface_destroy);
120 cairo_surface_set_device_offset( mpSurface.get(), x, y );
122 // Necessary, context is lost otherwise
123 CGContextRetain(rContext);
128 * QuartzSurface::getCairo: Create Cairo (drawing object) for the Canvas surface
130 * @return new Cairo or NULL
132 CairoSharedPtr QuartzSurface::getCairo() const
134 if (mpSurface.get())
136 return CairoSharedPtr( cairo_create(mpSurface.get()),
137 &cairo_destroy );
139 else
141 return CairoSharedPtr();
146 * QuartzSurface::getSimilar: Create new similar Canvas surface
147 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
148 * @param width width of the new surface
149 * @param height height of the new surface
151 * Creates a new Canvas surface. This normally creates platform native surface, even though
152 * generic function is used.
154 * Cairo surface from aContent (cairo_content_t)
156 * @return new surface or NULL
158 SurfaceSharedPtr QuartzSurface::getSimilar( Content aContent, int width, int height ) const
160 return SurfaceSharedPtr(
161 new QuartzSurface(
162 CairoSurfaceSharedPtr(
163 cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
164 &cairo_surface_destroy )));
168 * QuartzSurface::flush: Draw the data to screen
170 void QuartzSurface::flush() const
172 // can only flush surfaces with NSView
173 if( !mpView )
174 return;
176 OSL_TRACE("Canvas::cairo::QuartzSurface::flush(): flush to NSView");
178 CGContextRef mrContext = getCGContext();
180 if (!mrContext)
181 return;
182 #ifndef IOS
183 [mpView lockFocus];
184 #endif
186 #ifndef IOS
188 * This code is using same screen update code as in VCL (esp. AquaSalGraphics::UpdateWindow() )
190 CGContextRef rViewContext = reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
191 #else
192 // Just guessing for now...
193 CGContextRef rViewContext = UIGraphicsGetCurrentContext();
194 #endif
195 CGImageRef xImage = CGBitmapContextCreateImage(mrContext);
196 CGContextDrawImage(rViewContext,
197 CGRectMake( 0, 0,
198 CGImageGetWidth(xImage),
199 CGImageGetHeight(xImage)),
200 xImage);
201 CGImageRelease( xImage );
202 CGContextFlush( rViewContext );
203 #ifndef IOS
204 [mpView unlockFocus];
205 #endif
209 * QuartzSurface::getDepth: Get the color depth of the Canvas surface.
211 * @return color depth
213 int QuartzSurface::getDepth() const
215 if (mpSurface.get())
217 switch (cairo_surface_get_content (mpSurface.get()))
219 case CAIRO_CONTENT_ALPHA: return 8; break;
220 case CAIRO_CONTENT_COLOR: return 24; break;
221 case CAIRO_CONTENT_COLOR_ALPHA: return 32; break;
224 OSL_TRACE("Canvas::cairo::QuartzSurface::getDepth(): ERROR - depth unspecified!");
226 return -1;
230 * QuartzSurface::getCGContext: Get the native CGContextRef of the Canvas's cairo surface
232 * @return graphics context
234 CGContextRef QuartzSurface::getCGContext() const
236 if (mpSurface.get())
237 return cairo_quartz_surface_get_cg_context(mpSurface.get());
238 else
239 return NULL;
243 * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface
245 * @return The new virtual device
247 VclPtr<VirtualDevice> QuartzSurface::createVirtualDevice() const
249 SystemGraphicsData aSystemGraphicsData;
250 aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
251 aSystemGraphicsData.rCGContext = getCGContext();
252 return VclPtr<VirtualDevice>(
253 VclPtr<VirtualDevice>::Create( &aSystemGraphicsData, Size(1, 1), getDepth() ));
256 } // namespace cairo
258 #endif
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */