1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
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
39 #include <cairo-win32.h>
41 bool IsCairoWorking( OutputDevice
* )
43 // trivially true for Windows
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
58 Win32Surface::Win32Surface( const CairoSurfaceSharedPtr
& pSurface
) :
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
73 Win32Surface::Win32Surface( HDC hDC
, int x
, int y
) :
75 cairo_win32_surface_create(hDC
),
76 &cairo_surface_destroy
)
78 cairo_surface_set_device_offset( mpSurface
.get(), x
, y
);
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
89 Win32Surface::Win32Surface( const BitmapSystemData
& rBmpData
) :
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.
105 HDC hDC
= CreateCompatibleDC(NULL
);
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 ());
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()),
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(
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
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
170 * Surface::getDepth: Get the color depth of the Canvas surface.
172 * @return color depth
174 int Win32Surface::getDepth() const
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!");
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();
245 surf
= SurfaceSharedPtr(new Win32Surface((HDC
) aSysData
.hDC
, x
, y
));
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
,
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
));
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
)
288 hdc
= CreateCompatibleDC (NULL
);
291 if (!SetGraphicsMode (hdc
, GM_ADVANCED
))
297 SelectObject (hdc
, hfont
);
298 SetMapMode (hdc
, MM_TEXT
);
302 if (GetGlyphIndicesW (hdc
, unicode
, 1, &glyph_index
, 0) == GDI_ERROR
)
314 #endif // CAIRO_HAS_WIN32_SURFACE
318 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */