1*906a4e93SYuri Dario /************************************************************** 2*906a4e93SYuri Dario * 3*906a4e93SYuri Dario * Licensed to the Apache Software Foundation (ASF) under one 4*906a4e93SYuri Dario * or more contributor license agreements. See the NOTICE file 5*906a4e93SYuri Dario * distributed with this work for additional information 6*906a4e93SYuri Dario * regarding copyright ownership. The ASF licenses this file 7*906a4e93SYuri Dario * to you under the Apache License, Version 2.0 (the 8*906a4e93SYuri Dario * "License"); you may not use this file except in compliance 9*906a4e93SYuri Dario * with the License. You may obtain a copy of the License at 10*906a4e93SYuri Dario * 11*906a4e93SYuri Dario * http://www.apache.org/licenses/LICENSE-2.0 12*906a4e93SYuri Dario * 13*906a4e93SYuri Dario * Unless required by applicable law or agreed to in writing, 14*906a4e93SYuri Dario * software distributed under the License is distributed on an 15*906a4e93SYuri Dario * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*906a4e93SYuri Dario * KIND, either express or implied. See the License for the 17*906a4e93SYuri Dario * specific language governing permissions and limitations 18*906a4e93SYuri Dario * under the License. 19*906a4e93SYuri Dario * 20*906a4e93SYuri Dario *************************************************************/ 21*906a4e93SYuri Dario 22*906a4e93SYuri Dario 23*906a4e93SYuri Dario 24*906a4e93SYuri Dario // MARKER(update_precomp.py): autogen include statement, do not remove 25*906a4e93SYuri Dario #include "precompiled_canvas.hxx" 26*906a4e93SYuri Dario 27*906a4e93SYuri Dario #ifdef OS2 28*906a4e93SYuri Dario /************************************************************************ 29*906a4e93SYuri Dario * OS/2 surface backend for Apache OpenOffice Cairo Canvas * 30*906a4e93SYuri Dario ************************************************************************/ 31*906a4e93SYuri Dario 32*906a4e93SYuri Dario #define INCL_WIN 33*906a4e93SYuri Dario #include <os2.h> 34*906a4e93SYuri Dario 35*906a4e93SYuri Dario #include <osl/diagnose.h> 36*906a4e93SYuri Dario #include <vcl/bitmap.hxx> 37*906a4e93SYuri Dario #include <vcl/virdev.hxx> 38*906a4e93SYuri Dario #include <vcl/sysdata.hxx> 39*906a4e93SYuri Dario 40*906a4e93SYuri Dario #include "cairo_os2_cairo.hxx" 41*906a4e93SYuri Dario 42*906a4e93SYuri Dario namespace cairo 43*906a4e93SYuri Dario { 44*906a4e93SYuri Dario 45*906a4e93SYuri Dario #include <cairo/cairo-os2.h> 46*906a4e93SYuri Dario 47*906a4e93SYuri Dario // workaround for svpm.h definitions 48*906a4e93SYuri Dario #define sal_Bool BOOL 49*906a4e93SYuri Dario #define PM_FIXED FIXED 50*906a4e93SYuri Dario #define LPGLYPHMETRICS void* 51*906a4e93SYuri Dario #define MAT2 void 52*906a4e93SYuri Dario #include <ft2lib.h> 53*906a4e93SYuri Dario 54*906a4e93SYuri Dario bool IsCairoWorking( OutputDevice* ) 55*906a4e93SYuri Dario { 56*906a4e93SYuri Dario // trivially true for OS/2 57*906a4e93SYuri Dario return true; 58*906a4e93SYuri Dario } 59*906a4e93SYuri Dario 60*906a4e93SYuri Dario /** 61*906a4e93SYuri Dario * Surface::Surface: Create generic Canvas surface using given Cairo Surface 62*906a4e93SYuri Dario * 63*906a4e93SYuri Dario * @param pSurface Cairo Surface 64*906a4e93SYuri Dario * 65*906a4e93SYuri Dario * This constructor only stores data, it does no processing. 66*906a4e93SYuri Dario * It is used with e.g. cairo_image_surface_create_for_data() 67*906a4e93SYuri Dario * and Surface::getSimilar() 68*906a4e93SYuri Dario * 69*906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 70*906a4e93SYuri Dario **/ 71*906a4e93SYuri Dario Os2Surface::Os2Surface( const CairoSurfaceSharedPtr& pSurface ) : 72*906a4e93SYuri Dario mpSurface( pSurface ) 73*906a4e93SYuri Dario {} 74*906a4e93SYuri Dario 75*906a4e93SYuri Dario /** 76*906a4e93SYuri Dario * Surface::Surface: Create Canvas surface from Window reference. 77*906a4e93SYuri Dario * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 78*906a4e93SYuri Dario * @param x horizontal location of the new surface 79*906a4e93SYuri Dario * @param y vertical location of the new surface 80*906a4e93SYuri Dario * 81*906a4e93SYuri Dario * pSysData contains the platform native Window reference. 82*906a4e93SYuri Dario * pSysData is used to create a surface on the Window 83*906a4e93SYuri Dario * 84*906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 85*906a4e93SYuri Dario **/ 86*906a4e93SYuri Dario Os2Surface::Os2Surface( HWND hwnd, int x, int y, int w, int h) : 87*906a4e93SYuri Dario mpSurface( 88*906a4e93SYuri Dario cairo_os2_surface_create_for_window( hwnd, w + x, h + y), 89*906a4e93SYuri Dario &cairo_surface_destroy) 90*906a4e93SYuri Dario { 91*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::Os2Surface hwnd:%x offset: %d,%d size %d x %d", 92*906a4e93SYuri Dario hwnd, x, y, w, h); 93*906a4e93SYuri Dario cairo_surface_set_device_offset( mpSurface.get(), 0, 0); 94*906a4e93SYuri Dario } 95*906a4e93SYuri Dario 96*906a4e93SYuri Dario /** 97*906a4e93SYuri Dario * Surface::Surface: Create platform native Canvas surface from BitmapSystemData 98*906a4e93SYuri Dario * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 99*906a4e93SYuri Dario * 100*906a4e93SYuri Dario * Create a surface based on image data on pBmpData 101*906a4e93SYuri Dario * 102*906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 103*906a4e93SYuri Dario **/ 104*906a4e93SYuri Dario Os2Surface::Os2Surface( const BitmapSystemData& rBmpData ) : 105*906a4e93SYuri Dario mpSurface() 106*906a4e93SYuri Dario { 107*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::Os2Surface bitmap"); 108*906a4e93SYuri Dario #if 0 109*906a4e93SYuri Dario OSL_ASSERT(rBmpData.pDIB == NULL); 110*906a4e93SYuri Dario 111*906a4e93SYuri Dario if(rBmpData.pDIB != NULL) { 112*906a4e93SYuri Dario // So just leave mpSurface to NULL, little else we can do at 113*906a4e93SYuri Dario // this stage. Hopefully the Win32 patch to 114*906a4e93SYuri Dario // cairocanvas::DeviceHelper::getSurface(BitmapSystemData&, 115*906a4e93SYuri Dario // const Size&) will catch the cases where this 116*906a4e93SYuri Dario // constructor would be called with a DIB bitmap, and we 117*906a4e93SYuri Dario // will never get here. At least it worked for Ballmer.ppt. 118*906a4e93SYuri Dario } 119*906a4e93SYuri Dario else 120*906a4e93SYuri Dario { 121*906a4e93SYuri Dario HDC hDC = CreateCompatibleDC(NULL); 122*906a4e93SYuri Dario void* hOrigBitmap; 123*906a4e93SYuri Dario OSL_TRACE ("Surface::Surface(): Selecting bitmap %p into DC %p", rBmpData.pDDB, hDC); 124*906a4e93SYuri Dario hOrigBitmap = SelectObject( hDC, (HANDLE)rBmpData.pDDB ); 125*906a4e93SYuri Dario if(hOrigBitmap == NULL) 126*906a4e93SYuri Dario OSL_TRACE ("SelectObject failed: %d", GetLastError ()); 127*906a4e93SYuri Dario mpSurface.reset( 128*906a4e93SYuri Dario cairo_win32_surface_create(hDC), 129*906a4e93SYuri Dario &cairo_surface_destroy); 130*906a4e93SYuri Dario } 131*906a4e93SYuri Dario #endif 132*906a4e93SYuri Dario } 133*906a4e93SYuri Dario 134*906a4e93SYuri Dario /** 135*906a4e93SYuri Dario * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface 136*906a4e93SYuri Dario * 137*906a4e93SYuri Dario * @return new Cairo or NULL 138*906a4e93SYuri Dario **/ 139*906a4e93SYuri Dario CairoSharedPtr Os2Surface::getCairo() const 140*906a4e93SYuri Dario { 141*906a4e93SYuri Dario return CairoSharedPtr( cairo_create(mpSurface.get()), 142*906a4e93SYuri Dario &cairo_destroy ); 143*906a4e93SYuri Dario } 144*906a4e93SYuri Dario 145*906a4e93SYuri Dario /** 146*906a4e93SYuri Dario * Surface::getSimilar: Create new similar Canvas surface 147*906a4e93SYuri Dario * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h) 148*906a4e93SYuri Dario * @param width width of the new surface 149*906a4e93SYuri Dario * @param height height of the new surface 150*906a4e93SYuri Dario * 151*906a4e93SYuri Dario * Creates a new Canvas surface. This normally creates platform native surface, even though 152*906a4e93SYuri Dario * generic function is used. 153*906a4e93SYuri Dario * 154*906a4e93SYuri Dario * Cairo surface from aContent (cairo_content_t) 155*906a4e93SYuri Dario * 156*906a4e93SYuri Dario * @return new surface or NULL 157*906a4e93SYuri Dario **/ 158*906a4e93SYuri Dario SurfaceSharedPtr Os2Surface::getSimilar( Content aContent, int width, int height ) const 159*906a4e93SYuri Dario { 160*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::getSimilar size: %d x %d", width, height); 161*906a4e93SYuri Dario // cairo hits assertion in cairo-surface.c#535 if size is 0x0 162*906a4e93SYuri Dario int w = (width == 0 ? 1 : width); 163*906a4e93SYuri Dario int h = (height == 0 ? 1 : height); 164*906a4e93SYuri Dario return SurfaceSharedPtr( 165*906a4e93SYuri Dario new Os2Surface( 166*906a4e93SYuri Dario CairoSurfaceSharedPtr( 167*906a4e93SYuri Dario cairo_surface_create_similar( mpSurface.get(), aContent, w, h), 168*906a4e93SYuri Dario &cairo_surface_destroy ))); 169*906a4e93SYuri Dario } 170*906a4e93SYuri Dario 171*906a4e93SYuri Dario /** 172*906a4e93SYuri Dario * Surface::Resize: Resizes the Canvas surface. 173*906a4e93SYuri Dario * @param width new width of the surface 174*906a4e93SYuri Dario * @param height new height of the surface 175*906a4e93SYuri Dario * 176*906a4e93SYuri Dario * Only used on X11. 177*906a4e93SYuri Dario * 178*906a4e93SYuri Dario * @return The new surface or NULL 179*906a4e93SYuri Dario **/ 180*906a4e93SYuri Dario void Os2Surface::Resize( int width, int height) 181*906a4e93SYuri Dario { 182*906a4e93SYuri Dario cairo_os2_surface_set_size( mpSurface.get(), width, height, false); 183*906a4e93SYuri Dario } 184*906a4e93SYuri Dario 185*906a4e93SYuri Dario void Os2Surface::flush() const 186*906a4e93SYuri Dario { 187*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::flush"); 188*906a4e93SYuri Dario cairo_os2_surface_paint_window( mpSurface.get(), NULL, NULL, 0); 189*906a4e93SYuri Dario } 190*906a4e93SYuri Dario 191*906a4e93SYuri Dario /** 192*906a4e93SYuri Dario * Surface::getDepth: Get the color depth of the Canvas surface. 193*906a4e93SYuri Dario * 194*906a4e93SYuri Dario * @return color depth 195*906a4e93SYuri Dario **/ 196*906a4e93SYuri Dario int Os2Surface::getDepth() const 197*906a4e93SYuri Dario { 198*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::getDepth"); 199*906a4e93SYuri Dario if (mpSurface) { 200*906a4e93SYuri Dario switch (cairo_surface_get_content (mpSurface.get())) { 201*906a4e93SYuri Dario case CAIRO_CONTENT_ALPHA: return 8; break; 202*906a4e93SYuri Dario case CAIRO_CONTENT_COLOR: return 24; break; 203*906a4e93SYuri Dario case CAIRO_CONTENT_COLOR_ALPHA: return 32; break; 204*906a4e93SYuri Dario } 205*906a4e93SYuri Dario } 206*906a4e93SYuri Dario OSL_TRACE("Canvas::cairo::Surface::getDepth(): ERROR - depth unspecified!"); 207*906a4e93SYuri Dario return -1; 208*906a4e93SYuri Dario } 209*906a4e93SYuri Dario 210*906a4e93SYuri Dario 211*906a4e93SYuri Dario /** 212*906a4e93SYuri Dario * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface 213*906a4e93SYuri Dario * 214*906a4e93SYuri Dario * @return The new virtual device 215*906a4e93SYuri Dario **/ 216*906a4e93SYuri Dario boost::shared_ptr<VirtualDevice> Os2Surface::createVirtualDevice() const 217*906a4e93SYuri Dario { 218*906a4e93SYuri Dario SystemGraphicsData aSystemGraphicsData; 219*906a4e93SYuri Dario aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); 220*906a4e93SYuri Dario //aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() ); 221*906a4e93SYuri Dario OSL_TRACE( "Os2Surface::createVirtualDevice"); 222*906a4e93SYuri Dario 223*906a4e93SYuri Dario return boost::shared_ptr<VirtualDevice>( 224*906a4e93SYuri Dario new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) )); 225*906a4e93SYuri Dario } 226*906a4e93SYuri Dario 227*906a4e93SYuri Dario 228*906a4e93SYuri Dario /** 229*906a4e93SYuri Dario * cairo::createSurface: Create generic Canvas surface using given Cairo Surface 230*906a4e93SYuri Dario * 231*906a4e93SYuri Dario * @param rSurface Cairo Surface 232*906a4e93SYuri Dario * 233*906a4e93SYuri Dario * @return new Surface 234*906a4e93SYuri Dario */ 235*906a4e93SYuri Dario SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) 236*906a4e93SYuri Dario { 237*906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface from surface"); 238*906a4e93SYuri Dario return SurfaceSharedPtr(new Os2Surface(rSurface)); 239*906a4e93SYuri Dario } 240*906a4e93SYuri Dario 241*906a4e93SYuri Dario 242*906a4e93SYuri Dario /** 243*906a4e93SYuri Dario * cairo::createSurface: Create Canvas surface using given VCL Window or Virtualdevice 244*906a4e93SYuri Dario * 245*906a4e93SYuri Dario * @param rSurface Cairo Surface 246*906a4e93SYuri Dario * 247*906a4e93SYuri Dario * For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 248*906a4e93SYuri Dario * For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx) 249*906a4e93SYuri Dario * 250*906a4e93SYuri Dario * @return new Surface 251*906a4e93SYuri Dario */ 252*906a4e93SYuri Dario SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice, 253*906a4e93SYuri Dario int x, int y, int width, int height) 254*906a4e93SYuri Dario { 255*906a4e93SYuri Dario SurfaceSharedPtr surf; 256*906a4e93SYuri Dario // cairo hits assertion in cairo-surface.c#535 if size is 0x0 257*906a4e93SYuri Dario int w = (width == 0 ? 1 : width); 258*906a4e93SYuri Dario int h = (height == 0 ? 1 : height); 259*906a4e93SYuri Dario OSL_TRACE( "createSurface refDev:%x, offset: %d x %d", &rRefDevice, x, y); 260*906a4e93SYuri Dario 261*906a4e93SYuri Dario if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) 262*906a4e93SYuri Dario { 263*906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface for WINDOW"); 264*906a4e93SYuri Dario const Window &rWindow = (const Window &) rRefDevice; 265*906a4e93SYuri Dario const SystemEnvData* pSysData = GetSysData(&rWindow); 266*906a4e93SYuri Dario if (pSysData && pSysData->hWnd) 267*906a4e93SYuri Dario surf = SurfaceSharedPtr(new Os2Surface( 268*906a4e93SYuri Dario pSysData->hWnd, x, y, w, h)); 269*906a4e93SYuri Dario } 270*906a4e93SYuri Dario else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) 271*906a4e93SYuri Dario { 272*906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface for VIRDEV"); 273*906a4e93SYuri Dario //SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData(); 274*906a4e93SYuri Dario //if (aSysData.hDC) 275*906a4e93SYuri Dario // surf = SurfaceSharedPtr(new Os2Surface((HDC) aSysData.hDC, x, y)); 276*906a4e93SYuri Dario } 277*906a4e93SYuri Dario return surf; 278*906a4e93SYuri Dario } 279*906a4e93SYuri Dario 280*906a4e93SYuri Dario 281*906a4e93SYuri Dario /** 282*906a4e93SYuri Dario * cairo::createBitmapSurface: Create platform native Canvas surface from BitmapSystemData 283*906a4e93SYuri Dario * @param OutputDevice (not used) 284*906a4e93SYuri Dario * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 285*906a4e93SYuri Dario * @param rSize width and height of the new surface 286*906a4e93SYuri Dario * 287*906a4e93SYuri Dario * Create a surface based on image data on rData 288*906a4e93SYuri Dario * 289*906a4e93SYuri Dario * @return new surface or empty surface 290*906a4e93SYuri Dario **/ 291*906a4e93SYuri Dario SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */, 292*906a4e93SYuri Dario const BitmapSystemData& rData, 293*906a4e93SYuri Dario const Size& rSize ) 294*906a4e93SYuri Dario { 295*906a4e93SYuri Dario OSL_TRACE( "createBitmapSurface requested size: %d x %d available size: %d x %d", 296*906a4e93SYuri Dario rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight ); 297*906a4e93SYuri Dario 298*906a4e93SYuri Dario if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() ) 299*906a4e93SYuri Dario return SurfaceSharedPtr(new Os2Surface( rData )); 300*906a4e93SYuri Dario else 301*906a4e93SYuri Dario return SurfaceSharedPtr(); 302*906a4e93SYuri Dario } 303*906a4e93SYuri Dario 304*906a4e93SYuri Dario typedef USHORT WCHAR; 305*906a4e93SYuri Dario extern "C" ULONG APIENTRY Ft2GetGlyphIndices( HPS, WCHAR *, int, USHORT *, ULONG ); 306*906a4e93SYuri Dario 307*906a4e93SYuri Dario /** 308*906a4e93SYuri Dario * cairo::ucs4toindex: Convert ucs4 char to glyph index 309*906a4e93SYuri Dario * @param ucs4 an ucs4 char 310*906a4e93SYuri Dario * @param hfont current font 311*906a4e93SYuri Dario * 312*906a4e93SYuri Dario * @return true if successful 313*906a4e93SYuri Dario **/ 314*906a4e93SYuri Dario unsigned long ucs4toindex(unsigned int ucs4, const char* font) 315*906a4e93SYuri Dario { 316*906a4e93SYuri Dario WCHAR unicode[2]; 317*906a4e93SYuri Dario USHORT glyph_index; 318*906a4e93SYuri Dario HPS hps = NULL; 319*906a4e93SYuri Dario FATTRS fontAttrs; 320*906a4e93SYuri Dario APIRET rc; 321*906a4e93SYuri Dario 322*906a4e93SYuri Dario hps = WinGetPS( HWND_DESKTOP); 323*906a4e93SYuri Dario if (!hps) return 0; 324*906a4e93SYuri Dario 325*906a4e93SYuri Dario memset( &fontAttrs, 0, sizeof( fontAttrs)); 326*906a4e93SYuri Dario fontAttrs.usRecordLength = sizeof( FATTRS); 327*906a4e93SYuri Dario fontAttrs.usCodePage = 850; 328*906a4e93SYuri Dario fontAttrs.fsType = FATTR_TYPE_MBCS; 329*906a4e93SYuri Dario fontAttrs.fsFontUse = FATTR_FONTUSE_NOMIX; 330*906a4e93SYuri Dario strcpy( fontAttrs.szFacename, font); 331*906a4e93SYuri Dario rc = Ft2CreateLogFont( hps, NULL, 1L, &fontAttrs); 332*906a4e93SYuri Dario rc = Ft2SetCharSet( hps, 1L); 333*906a4e93SYuri Dario 334*906a4e93SYuri Dario unicode[0] = ucs4; 335*906a4e93SYuri Dario unicode[1] = 0; 336*906a4e93SYuri Dario if (Ft2GetGlyphIndices( hps, unicode, 1, &glyph_index, 0) == -1) { 337*906a4e93SYuri Dario glyph_index = 0; 338*906a4e93SYuri Dario } 339*906a4e93SYuri Dario 340*906a4e93SYuri Dario WinReleasePS( hps); 341*906a4e93SYuri Dario 342*906a4e93SYuri Dario return glyph_index; 343*906a4e93SYuri Dario } 344*906a4e93SYuri Dario 345*906a4e93SYuri Dario 346*906a4e93SYuri Dario } // namespace cairo 347*906a4e93SYuri Dario 348*906a4e93SYuri Dario #endif // OS2 349