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