125ea7f45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 325ea7f45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 425ea7f45SAndrew Rist * or more contributor license agreements. See the NOTICE file 525ea7f45SAndrew Rist * distributed with this work for additional information 625ea7f45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 725ea7f45SAndrew Rist * to you under the Apache License, Version 2.0 (the 825ea7f45SAndrew Rist * "License"); you may not use this file except in compliance 925ea7f45SAndrew Rist * with the License. You may obtain a copy of the License at 1025ea7f45SAndrew Rist * 1125ea7f45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1225ea7f45SAndrew Rist * 1325ea7f45SAndrew Rist * Unless required by applicable law or agreed to in writing, 1425ea7f45SAndrew Rist * software distributed under the License is distributed on an 1525ea7f45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1625ea7f45SAndrew Rist * KIND, either express or implied. See the License for the 1725ea7f45SAndrew Rist * specific language governing permissions and limitations 1825ea7f45SAndrew Rist * under the License. 1925ea7f45SAndrew Rist * 2025ea7f45SAndrew Rist *************************************************************/ 2125ea7f45SAndrew Rist 2225ea7f45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_canvas.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #ifdef WNT 28cdf0e10cSrcweir /************************************************************************ 29cdf0e10cSrcweir * Win32 surface backend for OpenOffice.org Cairo Canvas * 30cdf0e10cSrcweir ************************************************************************/ 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <tools/prewin.h> 33cdf0e10cSrcweir #include <windows.h> 34cdf0e10cSrcweir #include <tools/postwin.h> 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include <osl/diagnose.h> 37cdf0e10cSrcweir #include <vcl/bitmap.hxx> 38cdf0e10cSrcweir #include <vcl/virdev.hxx> 39cdf0e10cSrcweir #include <vcl/sysdata.hxx> 40cdf0e10cSrcweir 41cdf0e10cSrcweir #include "cairo_win32_cairo.hxx" 42cdf0e10cSrcweir 43cdf0e10cSrcweir #ifdef CAIRO_HAS_WIN32_SURFACE 44cdf0e10cSrcweir 45cdf0e10cSrcweir namespace cairo 46cdf0e10cSrcweir { 47cdf0e10cSrcweir 48cdf0e10cSrcweir #include <cairo-win32.h> 49cdf0e10cSrcweir IsCairoWorking(OutputDevice *)50cdf0e10cSrcweir bool IsCairoWorking( OutputDevice* ) 51cdf0e10cSrcweir { 52cdf0e10cSrcweir // trivially true for Windows 53cdf0e10cSrcweir return true; 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir /** 57cdf0e10cSrcweir * Surface::Surface: Create generic Canvas surface using given Cairo Surface 58cdf0e10cSrcweir * 59cdf0e10cSrcweir * @param pSurface Cairo Surface 60cdf0e10cSrcweir * 61cdf0e10cSrcweir * This constructor only stores data, it does no processing. 62cdf0e10cSrcweir * It is used with e.g. cairo_image_surface_create_for_data() 63cdf0e10cSrcweir * and Surface::getSimilar() 64cdf0e10cSrcweir * 65cdf0e10cSrcweir * Set the mpSurface to the new surface or NULL 66cdf0e10cSrcweir **/ Win32Surface(const CairoSurfaceSharedPtr & pSurface)67cdf0e10cSrcweir Win32Surface::Win32Surface( const CairoSurfaceSharedPtr& pSurface ) : 68cdf0e10cSrcweir mpSurface( pSurface ) 69cdf0e10cSrcweir {} 70cdf0e10cSrcweir 71cdf0e10cSrcweir /** 72cdf0e10cSrcweir * Surface::Surface: Create Canvas surface from Window reference. 73cdf0e10cSrcweir * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 74cdf0e10cSrcweir * @param x horizontal location of the new surface 75cdf0e10cSrcweir * @param y vertical location of the new surface 76cdf0e10cSrcweir * 77cdf0e10cSrcweir * pSysData contains the platform native Window reference. 78cdf0e10cSrcweir * pSysData is used to create a surface on the Window 79cdf0e10cSrcweir * 80cdf0e10cSrcweir * Set the mpSurface to the new surface or NULL 81cdf0e10cSrcweir **/ Win32Surface(HDC hDC,int x,int y)82cdf0e10cSrcweir Win32Surface::Win32Surface( HDC hDC, int x, int y) : 83cdf0e10cSrcweir mpSurface( 84cdf0e10cSrcweir cairo_win32_surface_create(hDC), 85cdf0e10cSrcweir &cairo_surface_destroy) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir cairo_surface_set_device_offset( mpSurface.get(), x, y ); 88cdf0e10cSrcweir } 89cdf0e10cSrcweir 90cdf0e10cSrcweir /** 91*07a3d7f1SPedro Giffuni * Surface::Surface: Create platform native Canvas surface from BitmapSystemData 92cdf0e10cSrcweir * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 93cdf0e10cSrcweir * 94cdf0e10cSrcweir * Create a surface based on image data on pBmpData 95cdf0e10cSrcweir * 96cdf0e10cSrcweir * Set the mpSurface to the new surface or NULL 97cdf0e10cSrcweir **/ Win32Surface(const BitmapSystemData & rBmpData)98cdf0e10cSrcweir Win32Surface::Win32Surface( const BitmapSystemData& rBmpData ) : 99cdf0e10cSrcweir mpSurface() 100cdf0e10cSrcweir { 101cdf0e10cSrcweir OSL_ASSERT(rBmpData.pDIB == NULL); 102cdf0e10cSrcweir 103cdf0e10cSrcweir if(rBmpData.pDIB != NULL) { 104cdf0e10cSrcweir // So just leave mpSurface to NULL, little else we can do at 105cdf0e10cSrcweir // this stage. Hopefully the Win32 patch to 106cdf0e10cSrcweir // cairocanvas::DeviceHelper::getSurface(BitmapSystemData&, 107cdf0e10cSrcweir // const Size&) will catch the cases where this 108cdf0e10cSrcweir // constructor would be called with a DIB bitmap, and we 109cdf0e10cSrcweir // will never get here. At least it worked for Ballmer.ppt. 110cdf0e10cSrcweir } 111cdf0e10cSrcweir else 112cdf0e10cSrcweir { 113cdf0e10cSrcweir HDC hDC = CreateCompatibleDC(NULL); 114cdf0e10cSrcweir void* hOrigBitmap; 115cdf0e10cSrcweir OSL_TRACE ("Surface::Surface(): Selecting bitmap %p into DC %p", rBmpData.pDDB, hDC); 116cdf0e10cSrcweir hOrigBitmap = SelectObject( hDC, (HANDLE)rBmpData.pDDB ); 117cdf0e10cSrcweir if(hOrigBitmap == NULL) 118cdf0e10cSrcweir OSL_TRACE ("SelectObject failed: %d", GetLastError ()); 119cdf0e10cSrcweir mpSurface.reset( 120cdf0e10cSrcweir cairo_win32_surface_create(hDC), 121cdf0e10cSrcweir &cairo_surface_destroy); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir /** 126cdf0e10cSrcweir * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface 127cdf0e10cSrcweir * 128cdf0e10cSrcweir * @return new Cairo or NULL 129cdf0e10cSrcweir **/ getCairo() const130cdf0e10cSrcweir CairoSharedPtr Win32Surface::getCairo() const 131cdf0e10cSrcweir { 132cdf0e10cSrcweir return CairoSharedPtr( cairo_create(mpSurface.get()), 133cdf0e10cSrcweir &cairo_destroy ); 134cdf0e10cSrcweir } 135cdf0e10cSrcweir 136cdf0e10cSrcweir /** 137cdf0e10cSrcweir * Surface::getSimilar: Create new similar Canvas surface 138cdf0e10cSrcweir * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h) 139cdf0e10cSrcweir * @param width width of the new surface 140cdf0e10cSrcweir * @param height height of the new surface 141cdf0e10cSrcweir * 142cdf0e10cSrcweir * Creates a new Canvas surface. This normally creates platform native surface, even though 143cdf0e10cSrcweir * generic function is used. 144cdf0e10cSrcweir * 145cdf0e10cSrcweir * Cairo surface from aContent (cairo_content_t) 146cdf0e10cSrcweir * 147cdf0e10cSrcweir * @return new surface or NULL 148cdf0e10cSrcweir **/ getSimilar(Content aContent,int width,int height) const149cdf0e10cSrcweir SurfaceSharedPtr Win32Surface::getSimilar( Content aContent, int width, int height ) const 150cdf0e10cSrcweir { 151cdf0e10cSrcweir return SurfaceSharedPtr( 152cdf0e10cSrcweir new Win32Surface( 153cdf0e10cSrcweir CairoSurfaceSharedPtr( 154cdf0e10cSrcweir cairo_surface_create_similar( mpSurface.get(), aContent, width, height ), 155cdf0e10cSrcweir &cairo_surface_destroy ))); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir 158cdf0e10cSrcweir /** 159cdf0e10cSrcweir * Surface::Resize: Resizes the Canvas surface. 160cdf0e10cSrcweir * @param width new width of the surface 161cdf0e10cSrcweir * @param height new height of the surface 162cdf0e10cSrcweir * 163cdf0e10cSrcweir * Only used on X11. 164cdf0e10cSrcweir * 165cdf0e10cSrcweir * @return The new surface or NULL 166cdf0e10cSrcweir **/ Resize(int,int)167cdf0e10cSrcweir void Win32Surface::Resize( int /*width*/, int /*height*/ ) 168cdf0e10cSrcweir { 169cdf0e10cSrcweir OSL_ENSURE(false,"not supposed to be called!"); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir flush() const172cdf0e10cSrcweir void Win32Surface::flush() const 173cdf0e10cSrcweir { 174cdf0e10cSrcweir GdiFlush(); 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir /** 178cdf0e10cSrcweir * Surface::getDepth: Get the color depth of the Canvas surface. 179cdf0e10cSrcweir * 180cdf0e10cSrcweir * @return color depth 181cdf0e10cSrcweir **/ getDepth() const182cdf0e10cSrcweir int Win32Surface::getDepth() const 183cdf0e10cSrcweir { 184cdf0e10cSrcweir if (mpSurface) { 185cdf0e10cSrcweir switch (cairo_surface_get_content (mpSurface.get())) { 186cdf0e10cSrcweir case CAIRO_CONTENT_ALPHA: return 8; break; 187cdf0e10cSrcweir case CAIRO_CONTENT_COLOR: return 24; break; 188cdf0e10cSrcweir case CAIRO_CONTENT_COLOR_ALPHA: return 32; break; 189cdf0e10cSrcweir } 190cdf0e10cSrcweir } 191cdf0e10cSrcweir OSL_TRACE("Canvas::cairo::Surface::getDepth(): ERROR - depth unspecified!"); 192cdf0e10cSrcweir return -1; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir 196cdf0e10cSrcweir /** 197cdf0e10cSrcweir * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface 198cdf0e10cSrcweir * 199cdf0e10cSrcweir * @return The new virtual device 200cdf0e10cSrcweir **/ createVirtualDevice() const201cdf0e10cSrcweir boost::shared_ptr<VirtualDevice> Win32Surface::createVirtualDevice() const 202cdf0e10cSrcweir { 203cdf0e10cSrcweir SystemGraphicsData aSystemGraphicsData; 204cdf0e10cSrcweir aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); 205cdf0e10cSrcweir aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() ); 206cdf0e10cSrcweir 207cdf0e10cSrcweir return boost::shared_ptr<VirtualDevice>( 208cdf0e10cSrcweir new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) )); 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir 212cdf0e10cSrcweir /** 213cdf0e10cSrcweir * cairo::createSurface: Create generic Canvas surface using given Cairo Surface 214cdf0e10cSrcweir * 215cdf0e10cSrcweir * @param rSurface Cairo Surface 216cdf0e10cSrcweir * 217cdf0e10cSrcweir * @return new Surface 218cdf0e10cSrcweir */ createSurface(const CairoSurfaceSharedPtr & rSurface)219cdf0e10cSrcweir SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir return SurfaceSharedPtr(new Win32Surface(rSurface)); 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir 225cdf0e10cSrcweir /** 226cdf0e10cSrcweir * cairo::createSurface: Create Canvas surface using given VCL Window or Virtualdevice 227cdf0e10cSrcweir * 228cdf0e10cSrcweir * @param rSurface Cairo Surface 229cdf0e10cSrcweir * 230cdf0e10cSrcweir * For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 231cdf0e10cSrcweir * For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx) 232cdf0e10cSrcweir * 233cdf0e10cSrcweir * @return new Surface 234cdf0e10cSrcweir */ createSurface(const OutputDevice & rRefDevice,int x,int y,int,int)235cdf0e10cSrcweir SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice, 236cdf0e10cSrcweir int x, int y, int /* width */, int /* height */) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir SurfaceSharedPtr surf; 239cdf0e10cSrcweir 240cdf0e10cSrcweir if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir const Window &rWindow = (const Window &) rRefDevice; 243cdf0e10cSrcweir const SystemEnvData* pSysData = GetSysData(&rWindow); 244cdf0e10cSrcweir if (pSysData && pSysData->hWnd) 245cdf0e10cSrcweir surf = SurfaceSharedPtr(new Win32Surface(GetDC((HWND) pSysData->hWnd), x, y)); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData(); 250cdf0e10cSrcweir if (aSysData.hDC) 251cdf0e10cSrcweir surf = SurfaceSharedPtr(new Win32Surface((HDC) aSysData.hDC, x, y)); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir return surf; 254cdf0e10cSrcweir } 255cdf0e10cSrcweir 256cdf0e10cSrcweir 257cdf0e10cSrcweir /** 258*07a3d7f1SPedro Giffuni * cairo::createBitmapSurface: Create platform native Canvas surface from BitmapSystemData 259cdf0e10cSrcweir * @param OutputDevice (not used) 260cdf0e10cSrcweir * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 261cdf0e10cSrcweir * @param rSize width and height of the new surface 262cdf0e10cSrcweir * 263cdf0e10cSrcweir * Create a surface based on image data on rData 264cdf0e10cSrcweir * 265cdf0e10cSrcweir * @return new surface or empty surface 266cdf0e10cSrcweir **/ createBitmapSurface(const OutputDevice &,const BitmapSystemData & rData,const Size & rSize)267cdf0e10cSrcweir SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */, 268cdf0e10cSrcweir const BitmapSystemData& rData, 269cdf0e10cSrcweir const Size& rSize ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir OSL_TRACE( "requested size: %d x %d available size: %d x %d", 272cdf0e10cSrcweir rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight ); 273cdf0e10cSrcweir 274cdf0e10cSrcweir if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() ) 275cdf0e10cSrcweir return SurfaceSharedPtr(new Win32Surface( rData )); 276cdf0e10cSrcweir else 277cdf0e10cSrcweir return SurfaceSharedPtr(); 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir 281cdf0e10cSrcweir /** 282cdf0e10cSrcweir * cairo::ucs4toindex: Convert ucs4 char to glyph index 283cdf0e10cSrcweir * @param ucs4 an ucs4 char 284cdf0e10cSrcweir * @param hfont current font 285cdf0e10cSrcweir * 286cdf0e10cSrcweir * @return true if successful 287cdf0e10cSrcweir **/ ucs4toindex(unsigned int ucs4,HFONT hfont)288cdf0e10cSrcweir unsigned long ucs4toindex(unsigned int ucs4, HFONT hfont) 289cdf0e10cSrcweir { 290cdf0e10cSrcweir wchar_t unicode[2]; 291cdf0e10cSrcweir WORD glyph_index; 292cdf0e10cSrcweir HDC hdc = NULL; 293cdf0e10cSrcweir int i = 0; 294cdf0e10cSrcweir 295cdf0e10cSrcweir hdc = CreateCompatibleDC (NULL); 296cdf0e10cSrcweir 297cdf0e10cSrcweir if (!hdc) return 0; 298cdf0e10cSrcweir if (!SetGraphicsMode (hdc, GM_ADVANCED)) { 299cdf0e10cSrcweir DeleteDC (hdc); 300cdf0e10cSrcweir return 0; 301cdf0e10cSrcweir } 302cdf0e10cSrcweir 303cdf0e10cSrcweir SelectObject (hdc, hfont); 304cdf0e10cSrcweir SetMapMode (hdc, MM_TEXT); 305cdf0e10cSrcweir 306cdf0e10cSrcweir unicode[0] = ucs4; 307cdf0e10cSrcweir unicode[1] = 0; 308cdf0e10cSrcweir if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR) { 309cdf0e10cSrcweir glyph_index = 0; 310cdf0e10cSrcweir } 311cdf0e10cSrcweir 312cdf0e10cSrcweir DeleteDC (hdc); 313cdf0e10cSrcweir return glyph_index; 314cdf0e10cSrcweir } 315cdf0e10cSrcweir 316cdf0e10cSrcweir 317cdf0e10cSrcweir } // namespace cairo 318cdf0e10cSrcweir 319cdf0e10cSrcweir #endif // CAIRO_HAS_WIN32_SURFACE 320cdf0e10cSrcweir 321cdf0e10cSrcweir #endif // WNT 322