update credits
[LibreOffice.git] / canvas / source / cairo / cairo_win32_cairo.cxx
blob3bf9c6db2a904b574417eeb1210398668851da6e
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 #define _WIN32_WINNT 0x0500
22 #ifdef WNT
23 /************************************************************************
24 * Win32 surface backend for OpenOffice.org Cairo Canvas *
25 ************************************************************************/
27 #include <osl/diagnose.h>
28 #include <vcl/bitmap.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/sysdata.hxx>
32 #include "cairo_win32_cairo.hxx"
34 #ifdef CAIRO_HAS_WIN32_SURFACE
36 namespace cairo
39 #include <cairo-win32.h>
41 bool IsCairoWorking( OutputDevice* )
43 // trivially true for Windows
44 return true;
47 /**
48 * Surface::Surface: Create generic Canvas surface using given Cairo Surface
50 * @param pSurface Cairo Surface
52 * This constructor only stores data, it does no processing.
53 * It is used with e.g. cairo_image_surface_create_for_data()
54 * and Surface::getSimilar()
56 * Set the mpSurface to the new surface or NULL
57 **/
58 Win32Surface::Win32Surface( const CairoSurfaceSharedPtr& pSurface ) :
59 mpSurface( pSurface )
62 /**
63 * Surface::Surface: Create Canvas surface from Window reference.
64 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
65 * @param x horizontal location of the new surface
66 * @param y vertical location of the new surface
68 * pSysData contains the platform native Window reference.
69 * pSysData is used to create a surface on the Window
71 * Set the mpSurface to the new surface or NULL
72 **/
73 Win32Surface::Win32Surface( HDC hDC, int x, int y) :
74 mpSurface(
75 cairo_win32_surface_create(hDC),
76 &cairo_surface_destroy)
78 cairo_surface_set_device_offset( mpSurface.get(), x, y );
81 /**
82 * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData
83 * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
85 * Create a surface based on image data on pBmpData
87 * Set the mpSurface to the new surface or NULL
88 **/
89 Win32Surface::Win32Surface( const BitmapSystemData& rBmpData ) :
90 mpSurface()
92 OSL_ASSERT(rBmpData.pDIB == NULL);
94 if(rBmpData.pDIB != NULL)
96 // So just leave mpSurface to NULL, little else we can do at
97 // this stage. Hopefully the Win32 patch to
98 // cairocanvas::DeviceHelper::getSurface(BitmapSystemData&,
99 // const Size&) will catch the cases where this
100 // constructor would be called with a DIB bitmap, and we
101 // will never get here. At least it worked for Ballmer.ppt.
103 else
105 HDC hDC = CreateCompatibleDC(NULL);
106 void* hOrigBitmap;
107 OSL_TRACE ("Surface::Surface(): Selecting bitmap %p into DC %p", rBmpData.pDDB, hDC);
108 hOrigBitmap = SelectObject( hDC, (HANDLE)rBmpData.pDDB );
109 if(hOrigBitmap == NULL)
110 OSL_TRACE ("SelectObject failed: %d", GetLastError ());
111 mpSurface.reset(
112 cairo_win32_surface_create(hDC),
113 &cairo_surface_destroy);
118 * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
120 * @return new Cairo or NULL
122 CairoSharedPtr Win32Surface::getCairo() const
124 return CairoSharedPtr( cairo_create(mpSurface.get()),
125 &cairo_destroy );
129 * Surface::getSimilar: Create new similar Canvas surface
130 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
131 * @param width width of the new surface
132 * @param height height of the new surface
134 * Creates a new Canvas surface. This normally creates platform native surface, even though
135 * generic function is used.
137 * Cairo surface from aContent (cairo_content_t)
139 * @return new surface or NULL
141 SurfaceSharedPtr Win32Surface::getSimilar( Content aContent, int width, int height ) const
143 return SurfaceSharedPtr(
144 new Win32Surface(
145 CairoSurfaceSharedPtr(
146 cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
147 &cairo_surface_destroy )));
151 * Surface::Resize: Resizes the Canvas surface.
152 * @param width new width of the surface
153 * @param height new height of the surface
155 * Only used on X11.
157 * @return The new surface or NULL
159 void Win32Surface::Resize( int /*width*/, int /*height*/ )
161 OSL_FAIL("not supposed to be called!");
164 void Win32Surface::flush() const
166 GdiFlush();
170 * Surface::getDepth: Get the color depth of the Canvas surface.
172 * @return color depth
174 int Win32Surface::getDepth() const
176 if (mpSurface)
178 switch (cairo_surface_get_content (mpSurface.get()))
180 case CAIRO_CONTENT_ALPHA: return 8; break;
181 case CAIRO_CONTENT_COLOR: return 24; break;
182 case CAIRO_CONTENT_COLOR_ALPHA: return 32; break;
185 OSL_TRACE("Canvas::cairo::Surface::getDepth(): ERROR - depth unspecified!");
186 return -1;
191 * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface
193 * @return The new virtual device
195 boost::shared_ptr<VirtualDevice> Win32Surface::createVirtualDevice() const
197 SystemGraphicsData aSystemGraphicsData;
198 aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
199 aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() );
201 return boost::shared_ptr<VirtualDevice>(
202 new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) ));
207 * cairo::createSurface: Create generic Canvas surface using given Cairo Surface
209 * @param rSurface Cairo Surface
211 * @return new Surface
213 SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
215 return SurfaceSharedPtr(new Win32Surface(rSurface));
220 * cairo::createSurface: Create Canvas surface using given VCL Window or Virtualdevice
222 * @param rSurface Cairo Surface
224 * For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
225 * For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx)
227 * @return new Surface
229 SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice,
230 int x, int y, int /* width */, int /* height */)
232 SurfaceSharedPtr surf;
234 if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
236 const Window &rWindow = (const Window &) rRefDevice;
237 const SystemEnvData* pSysData = GetSysData(&rWindow);
238 if (pSysData && pSysData->hWnd)
239 surf = SurfaceSharedPtr(new Win32Surface(GetDC((HWND) pSysData->hWnd), x, y));
241 else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
243 SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData();
244 if (aSysData.hDC)
245 surf = SurfaceSharedPtr(new Win32Surface((HDC) aSysData.hDC, x, y));
247 return surf;
252 * cairo::createBitmapSurface: Create platfrom native Canvas surface from BitmapSystemData
253 * @param OutputDevice (not used)
254 * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
255 * @param rSize width and height of the new surface
257 * Create a surface based on image data on rData
259 * @return new surface or empty surface
261 SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */,
262 const BitmapSystemData& rData,
263 const Size& rSize )
265 OSL_TRACE( "requested size: %d x %d available size: %d x %d",
266 rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
268 if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
269 return SurfaceSharedPtr(new Win32Surface( rData ));
270 else
271 return SurfaceSharedPtr();
276 * cairo::ucs4toindex: Convert ucs4 char to glyph index
277 * @param ucs4 an ucs4 char
278 * @param hfont current font
280 * @return true if successful
282 unsigned long ucs4toindex(unsigned int ucs4, HFONT hfont)
284 wchar_t unicode[2];
285 WORD glyph_index;
286 HDC hdc = NULL;
288 hdc = CreateCompatibleDC (NULL);
290 if (!hdc) return 0;
291 if (!SetGraphicsMode (hdc, GM_ADVANCED))
293 DeleteDC (hdc);
294 return 0;
297 SelectObject (hdc, hfont);
298 SetMapMode (hdc, MM_TEXT);
300 unicode[0] = ucs4;
301 unicode[1] = 0;
302 if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR)
304 glyph_index = 0;
307 DeleteDC (hdc);
308 return glyph_index;
312 } // namespace cairo
314 #endif // CAIRO_HAS_WIN32_SURFACE
316 #endif // WNT
318 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */