1906a4e93SYuri Dario /************************************************************** 2906a4e93SYuri Dario * 3906a4e93SYuri Dario * Licensed to the Apache Software Foundation (ASF) under one 4906a4e93SYuri Dario * or more contributor license agreements. See the NOTICE file 5906a4e93SYuri Dario * distributed with this work for additional information 6906a4e93SYuri Dario * regarding copyright ownership. The ASF licenses this file 7906a4e93SYuri Dario * to you under the Apache License, Version 2.0 (the 8906a4e93SYuri Dario * "License"); you may not use this file except in compliance 9906a4e93SYuri Dario * with the License. You may obtain a copy of the License at 10906a4e93SYuri Dario * 11906a4e93SYuri Dario * http://www.apache.org/licenses/LICENSE-2.0 12906a4e93SYuri Dario * 13906a4e93SYuri Dario * Unless required by applicable law or agreed to in writing, 14906a4e93SYuri Dario * software distributed under the License is distributed on an 15906a4e93SYuri Dario * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16906a4e93SYuri Dario * KIND, either express or implied. See the License for the 17906a4e93SYuri Dario * specific language governing permissions and limitations 18906a4e93SYuri Dario * under the License. 19906a4e93SYuri Dario * 20906a4e93SYuri Dario *************************************************************/ 21906a4e93SYuri Dario 22906a4e93SYuri Dario 23906a4e93SYuri Dario 24906a4e93SYuri Dario // MARKER(update_precomp.py): autogen include statement, do not remove 25906a4e93SYuri Dario #include "precompiled_canvas.hxx" 26906a4e93SYuri Dario 27906a4e93SYuri Dario #ifdef OS2 28906a4e93SYuri Dario /************************************************************************ 29906a4e93SYuri Dario * OS/2 surface backend for Apache OpenOffice Cairo Canvas * 30906a4e93SYuri Dario ************************************************************************/ 31906a4e93SYuri Dario 32906a4e93SYuri Dario #define INCL_WIN 33906a4e93SYuri Dario #include <os2.h> 34906a4e93SYuri Dario 35906a4e93SYuri Dario #include <osl/diagnose.h> 36906a4e93SYuri Dario #include <vcl/bitmap.hxx> 37906a4e93SYuri Dario #include <vcl/virdev.hxx> 38906a4e93SYuri Dario #include <vcl/sysdata.hxx> 39906a4e93SYuri Dario 40906a4e93SYuri Dario #include "cairo_os2_cairo.hxx" 41906a4e93SYuri Dario 42906a4e93SYuri Dario namespace cairo 43906a4e93SYuri Dario { 44906a4e93SYuri Dario 45906a4e93SYuri Dario #include <cairo/cairo-os2.h> 46906a4e93SYuri Dario 47906a4e93SYuri Dario // workaround for svpm.h definitions 48906a4e93SYuri Dario #define sal_Bool BOOL 49906a4e93SYuri Dario #define PM_FIXED FIXED 50906a4e93SYuri Dario #define LPGLYPHMETRICS void* 51906a4e93SYuri Dario #define MAT2 void 52906a4e93SYuri Dario #include <ft2lib.h> 53906a4e93SYuri Dario IsCairoWorking(OutputDevice *)54906a4e93SYuri Dario bool IsCairoWorking( OutputDevice* ) 55906a4e93SYuri Dario { 56906a4e93SYuri Dario // trivially true for OS/2 57906a4e93SYuri Dario return true; 58906a4e93SYuri Dario } 59906a4e93SYuri Dario 60906a4e93SYuri Dario /** 61906a4e93SYuri Dario * Surface::Surface: Create generic Canvas surface using given Cairo Surface 62906a4e93SYuri Dario * 63906a4e93SYuri Dario * @param pSurface Cairo Surface 64906a4e93SYuri Dario * 65906a4e93SYuri Dario * This constructor only stores data, it does no processing. 66906a4e93SYuri Dario * It is used with e.g. cairo_image_surface_create_for_data() 67906a4e93SYuri Dario * and Surface::getSimilar() 68906a4e93SYuri Dario * 69906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 70906a4e93SYuri Dario **/ Os2Surface(const CairoSurfaceSharedPtr & pSurface)71906a4e93SYuri Dario Os2Surface::Os2Surface( const CairoSurfaceSharedPtr& pSurface ) : 72906a4e93SYuri Dario mpSurface( pSurface ) 73906a4e93SYuri Dario {} 74906a4e93SYuri Dario 75906a4e93SYuri Dario /** 76906a4e93SYuri Dario * Surface::Surface: Create Canvas surface from Window reference. 77906a4e93SYuri Dario * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 78906a4e93SYuri Dario * @param x horizontal location of the new surface 79906a4e93SYuri Dario * @param y vertical location of the new surface 80906a4e93SYuri Dario * 81906a4e93SYuri Dario * pSysData contains the platform native Window reference. 82906a4e93SYuri Dario * pSysData is used to create a surface on the Window 83906a4e93SYuri Dario * 84906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 85906a4e93SYuri Dario **/ Os2Surface(HWND hwnd,int x,int y,int w,int h)86906a4e93SYuri Dario Os2Surface::Os2Surface( HWND hwnd, int x, int y, int w, int h) : 87906a4e93SYuri Dario mpSurface( 88906a4e93SYuri Dario cairo_os2_surface_create_for_window( hwnd, w + x, h + y), 89906a4e93SYuri Dario &cairo_surface_destroy) 90906a4e93SYuri Dario { 91906a4e93SYuri Dario OSL_TRACE( "Os2Surface::Os2Surface hwnd:%x offset: %d,%d size %d x %d", 92906a4e93SYuri Dario hwnd, x, y, w, h); 93906a4e93SYuri Dario cairo_surface_set_device_offset( mpSurface.get(), 0, 0); 94906a4e93SYuri Dario } 95906a4e93SYuri Dario 96906a4e93SYuri Dario /** 97906a4e93SYuri Dario * Surface::Surface: Create platform native Canvas surface from BitmapSystemData 98906a4e93SYuri Dario * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 99906a4e93SYuri Dario * 100906a4e93SYuri Dario * Create a surface based on image data on pBmpData 101906a4e93SYuri Dario * 102906a4e93SYuri Dario * Set the mpSurface to the new surface or NULL 103906a4e93SYuri Dario **/ Os2Surface(const BitmapSystemData & rBmpData)104906a4e93SYuri Dario Os2Surface::Os2Surface( const BitmapSystemData& rBmpData ) : 105906a4e93SYuri Dario mpSurface() 106906a4e93SYuri Dario { 107906a4e93SYuri Dario OSL_TRACE( "Os2Surface::Os2Surface bitmap"); 108906a4e93SYuri Dario #if 0 109906a4e93SYuri Dario OSL_ASSERT(rBmpData.pDIB == NULL); 110906a4e93SYuri Dario 111906a4e93SYuri Dario if(rBmpData.pDIB != NULL) { 112906a4e93SYuri Dario // So just leave mpSurface to NULL, little else we can do at 113906a4e93SYuri Dario // this stage. Hopefully the Win32 patch to 114906a4e93SYuri Dario // cairocanvas::DeviceHelper::getSurface(BitmapSystemData&, 115906a4e93SYuri Dario // const Size&) will catch the cases where this 116906a4e93SYuri Dario // constructor would be called with a DIB bitmap, and we 117906a4e93SYuri Dario // will never get here. At least it worked for Ballmer.ppt. 118906a4e93SYuri Dario } 119906a4e93SYuri Dario else 120906a4e93SYuri Dario { 121906a4e93SYuri Dario HDC hDC = CreateCompatibleDC(NULL); 122906a4e93SYuri Dario void* hOrigBitmap; 123906a4e93SYuri Dario OSL_TRACE ("Surface::Surface(): Selecting bitmap %p into DC %p", rBmpData.pDDB, hDC); 124906a4e93SYuri Dario hOrigBitmap = SelectObject( hDC, (HANDLE)rBmpData.pDDB ); 125906a4e93SYuri Dario if(hOrigBitmap == NULL) 126906a4e93SYuri Dario OSL_TRACE ("SelectObject failed: %d", GetLastError ()); 127906a4e93SYuri Dario mpSurface.reset( 128906a4e93SYuri Dario cairo_win32_surface_create(hDC), 129906a4e93SYuri Dario &cairo_surface_destroy); 130906a4e93SYuri Dario } 131906a4e93SYuri Dario #endif 132906a4e93SYuri Dario } 133906a4e93SYuri Dario 134906a4e93SYuri Dario /** 135906a4e93SYuri Dario * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface 136906a4e93SYuri Dario * 137906a4e93SYuri Dario * @return new Cairo or NULL 138906a4e93SYuri Dario **/ getCairo() const139906a4e93SYuri Dario CairoSharedPtr Os2Surface::getCairo() const 140906a4e93SYuri Dario { 141906a4e93SYuri Dario return CairoSharedPtr( cairo_create(mpSurface.get()), 142906a4e93SYuri Dario &cairo_destroy ); 143906a4e93SYuri Dario } 144906a4e93SYuri Dario 145906a4e93SYuri Dario /** 146906a4e93SYuri Dario * Surface::getSimilar: Create new similar Canvas surface 147906a4e93SYuri Dario * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h) 148906a4e93SYuri Dario * @param width width of the new surface 149906a4e93SYuri Dario * @param height height of the new surface 150906a4e93SYuri Dario * 151906a4e93SYuri Dario * Creates a new Canvas surface. This normally creates platform native surface, even though 152906a4e93SYuri Dario * generic function is used. 153906a4e93SYuri Dario * 154906a4e93SYuri Dario * Cairo surface from aContent (cairo_content_t) 155906a4e93SYuri Dario * 156906a4e93SYuri Dario * @return new surface or NULL 157906a4e93SYuri Dario **/ getSimilar(Content aContent,int width,int height) const158906a4e93SYuri Dario SurfaceSharedPtr Os2Surface::getSimilar( Content aContent, int width, int height ) const 159906a4e93SYuri Dario { 160906a4e93SYuri Dario OSL_TRACE( "Os2Surface::getSimilar size: %d x %d", width, height); 161906a4e93SYuri Dario // cairo hits assertion in cairo-surface.c#535 if size is 0x0 162906a4e93SYuri Dario int w = (width == 0 ? 1 : width); 163906a4e93SYuri Dario int h = (height == 0 ? 1 : height); 164906a4e93SYuri Dario return SurfaceSharedPtr( 165906a4e93SYuri Dario new Os2Surface( 166906a4e93SYuri Dario CairoSurfaceSharedPtr( 167906a4e93SYuri Dario cairo_surface_create_similar( mpSurface.get(), aContent, w, h), 168906a4e93SYuri Dario &cairo_surface_destroy ))); 169906a4e93SYuri Dario } 170906a4e93SYuri Dario 171906a4e93SYuri Dario /** 172906a4e93SYuri Dario * Surface::Resize: Resizes the Canvas surface. 173906a4e93SYuri Dario * @param width new width of the surface 174906a4e93SYuri Dario * @param height new height of the surface 175906a4e93SYuri Dario * 176906a4e93SYuri Dario * Only used on X11. 177906a4e93SYuri Dario * 178906a4e93SYuri Dario * @return The new surface or NULL 179906a4e93SYuri Dario **/ Resize(int width,int height)180906a4e93SYuri Dario void Os2Surface::Resize( int width, int height) 181906a4e93SYuri Dario { 182906a4e93SYuri Dario cairo_os2_surface_set_size( mpSurface.get(), width, height, false); 183906a4e93SYuri Dario } 184906a4e93SYuri Dario flush() const185906a4e93SYuri Dario void Os2Surface::flush() const 186906a4e93SYuri Dario { 187906a4e93SYuri Dario OSL_TRACE( "Os2Surface::flush"); 188906a4e93SYuri Dario cairo_os2_surface_paint_window( mpSurface.get(), NULL, NULL, 0); 189906a4e93SYuri Dario } 190906a4e93SYuri Dario 191906a4e93SYuri Dario /** 192906a4e93SYuri Dario * Surface::getDepth: Get the color depth of the Canvas surface. 193906a4e93SYuri Dario * 194906a4e93SYuri Dario * @return color depth 195906a4e93SYuri Dario **/ getDepth() const196906a4e93SYuri Dario int Os2Surface::getDepth() const 197906a4e93SYuri Dario { 198906a4e93SYuri Dario OSL_TRACE( "Os2Surface::getDepth"); 199906a4e93SYuri Dario if (mpSurface) { 200906a4e93SYuri Dario switch (cairo_surface_get_content (mpSurface.get())) { 201906a4e93SYuri Dario case CAIRO_CONTENT_ALPHA: return 8; break; 202906a4e93SYuri Dario case CAIRO_CONTENT_COLOR: return 24; break; 203906a4e93SYuri Dario case CAIRO_CONTENT_COLOR_ALPHA: return 32; break; 204906a4e93SYuri Dario } 205906a4e93SYuri Dario } 206906a4e93SYuri Dario OSL_TRACE("Canvas::cairo::Surface::getDepth(): ERROR - depth unspecified!"); 207906a4e93SYuri Dario return -1; 208906a4e93SYuri Dario } 209906a4e93SYuri Dario 210906a4e93SYuri Dario 211906a4e93SYuri Dario /** 212906a4e93SYuri Dario * cairo::createVirtualDevice: Create a VCL virtual device for the CGContext in the cairo Surface 213906a4e93SYuri Dario * 214906a4e93SYuri Dario * @return The new virtual device 215906a4e93SYuri Dario **/ createVirtualDevice() const216906a4e93SYuri Dario boost::shared_ptr<VirtualDevice> Os2Surface::createVirtualDevice() const 217906a4e93SYuri Dario { 218906a4e93SYuri Dario SystemGraphicsData aSystemGraphicsData; 219906a4e93SYuri Dario aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); 220906a4e93SYuri Dario //aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() ); 221906a4e93SYuri Dario OSL_TRACE( "Os2Surface::createVirtualDevice"); 222906a4e93SYuri Dario 223906a4e93SYuri Dario return boost::shared_ptr<VirtualDevice>( 224906a4e93SYuri Dario new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) )); 225906a4e93SYuri Dario } 226906a4e93SYuri Dario 227906a4e93SYuri Dario 228906a4e93SYuri Dario /** 229906a4e93SYuri Dario * cairo::createSurface: Create generic Canvas surface using given Cairo Surface 230906a4e93SYuri Dario * 231906a4e93SYuri Dario * @param rSurface Cairo Surface 232906a4e93SYuri Dario * 233906a4e93SYuri Dario * @return new Surface 234906a4e93SYuri Dario */ createSurface(const CairoSurfaceSharedPtr & rSurface)235906a4e93SYuri Dario SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) 236906a4e93SYuri Dario { 237906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface from surface"); 238906a4e93SYuri Dario return SurfaceSharedPtr(new Os2Surface(rSurface)); 239906a4e93SYuri Dario } 240906a4e93SYuri Dario 241906a4e93SYuri Dario 242906a4e93SYuri Dario /** 243906a4e93SYuri Dario * cairo::createSurface: Create Canvas surface using given VCL Window or Virtualdevice 244906a4e93SYuri Dario * 245906a4e93SYuri Dario * @param rSurface Cairo Surface 246906a4e93SYuri Dario * 247906a4e93SYuri Dario * For VCL Window, use platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 248906a4e93SYuri Dario * For VCL Virtualdevice, use platform native system graphics data (struct SystemGraphicsData in vcl/inc/sysdata.hxx) 249906a4e93SYuri Dario * 250906a4e93SYuri Dario * @return new Surface 251906a4e93SYuri Dario */ createSurface(const OutputDevice & rRefDevice,int x,int y,int width,int height)252906a4e93SYuri Dario SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice, 253906a4e93SYuri Dario int x, int y, int width, int height) 254906a4e93SYuri Dario { 255906a4e93SYuri Dario SurfaceSharedPtr surf; 256906a4e93SYuri Dario // cairo hits assertion in cairo-surface.c#535 if size is 0x0 257906a4e93SYuri Dario int w = (width == 0 ? 1 : width); 258906a4e93SYuri Dario int h = (height == 0 ? 1 : height); 259906a4e93SYuri Dario OSL_TRACE( "createSurface refDev:%x, offset: %d x %d", &rRefDevice, x, y); 260906a4e93SYuri Dario 261906a4e93SYuri Dario if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) 262906a4e93SYuri Dario { 263906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface for WINDOW"); 264906a4e93SYuri Dario const Window &rWindow = (const Window &) rRefDevice; 265906a4e93SYuri Dario const SystemEnvData* pSysData = GetSysData(&rWindow); 266906a4e93SYuri Dario if (pSysData && pSysData->hWnd) 267906a4e93SYuri Dario surf = SurfaceSharedPtr(new Os2Surface( 268906a4e93SYuri Dario pSysData->hWnd, x, y, w, h)); 269906a4e93SYuri Dario } 270906a4e93SYuri Dario else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) 271906a4e93SYuri Dario { 272906a4e93SYuri Dario OSL_TRACE( "Os2Surface createSurface for VIRDEV"); 273906a4e93SYuri Dario //SystemGraphicsData aSysData = ((const VirtualDevice&) rRefDevice).GetSystemGfxData(); 274906a4e93SYuri Dario //if (aSysData.hDC) 275906a4e93SYuri Dario // surf = SurfaceSharedPtr(new Os2Surface((HDC) aSysData.hDC, x, y)); 276906a4e93SYuri Dario } 277906a4e93SYuri Dario return surf; 278906a4e93SYuri Dario } 279906a4e93SYuri Dario 280906a4e93SYuri Dario 281906a4e93SYuri Dario /** 282906a4e93SYuri Dario * cairo::createBitmapSurface: Create platform native Canvas surface from BitmapSystemData 283906a4e93SYuri Dario * @param OutputDevice (not used) 284906a4e93SYuri Dario * @param rData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 285906a4e93SYuri Dario * @param rSize width and height of the new surface 286906a4e93SYuri Dario * 287906a4e93SYuri Dario * Create a surface based on image data on rData 288906a4e93SYuri Dario * 289906a4e93SYuri Dario * @return new surface or empty surface 290906a4e93SYuri Dario **/ createBitmapSurface(const OutputDevice &,const BitmapSystemData & rData,const Size & rSize)291906a4e93SYuri Dario SurfaceSharedPtr createBitmapSurface( const OutputDevice& /* rRefDevice */, 292906a4e93SYuri Dario const BitmapSystemData& rData, 293906a4e93SYuri Dario const Size& rSize ) 294906a4e93SYuri Dario { 295906a4e93SYuri Dario OSL_TRACE( "createBitmapSurface requested size: %d x %d available size: %d x %d", 296906a4e93SYuri Dario rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight ); 297906a4e93SYuri Dario 298906a4e93SYuri Dario if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() ) 299906a4e93SYuri Dario return SurfaceSharedPtr(new Os2Surface( rData )); 300906a4e93SYuri Dario else 301906a4e93SYuri Dario return SurfaceSharedPtr(); 302906a4e93SYuri Dario } 303906a4e93SYuri Dario 304906a4e93SYuri Dario typedef USHORT WCHAR; 305906a4e93SYuri Dario extern "C" ULONG APIENTRY Ft2GetGlyphIndices( HPS, WCHAR *, int, USHORT *, ULONG ); 306906a4e93SYuri Dario 307906a4e93SYuri Dario /** 308906a4e93SYuri Dario * cairo::ucs4toindex: Convert ucs4 char to glyph index 309906a4e93SYuri Dario * @param ucs4 an ucs4 char 310906a4e93SYuri Dario * @param hfont current font 311906a4e93SYuri Dario * 312906a4e93SYuri Dario * @return true if successful 313906a4e93SYuri Dario **/ ucs4toindex(unsigned int ucs4,const char * font)314906a4e93SYuri Dario unsigned long ucs4toindex(unsigned int ucs4, const char* font) 315906a4e93SYuri Dario { 316906a4e93SYuri Dario WCHAR unicode[2]; 317906a4e93SYuri Dario USHORT glyph_index; 318906a4e93SYuri Dario HPS hps = NULL; 319906a4e93SYuri Dario FATTRS fontAttrs; 320906a4e93SYuri Dario APIRET rc; 321906a4e93SYuri Dario 322906a4e93SYuri Dario hps = WinGetPS( HWND_DESKTOP); 323906a4e93SYuri Dario if (!hps) return 0; 324906a4e93SYuri Dario 325906a4e93SYuri Dario memset( &fontAttrs, 0, sizeof( fontAttrs)); 326906a4e93SYuri Dario fontAttrs.usRecordLength = sizeof( FATTRS); 327906a4e93SYuri Dario fontAttrs.usCodePage = 850; 328906a4e93SYuri Dario fontAttrs.fsType = FATTR_TYPE_MBCS; 329906a4e93SYuri Dario fontAttrs.fsFontUse = FATTR_FONTUSE_NOMIX; 330*1919b60fSYuri Dario // map StarSymbol to OpenSymbol 331*1919b60fSYuri Dario if (strcmp( font, "StarSymbol") == 0) 332*1919b60fSYuri Dario strcpy( fontAttrs.szFacename, "OpenSymbol"); 333*1919b60fSYuri Dario else 334906a4e93SYuri Dario strcpy( fontAttrs.szFacename, font); 335906a4e93SYuri Dario rc = Ft2CreateLogFont( hps, NULL, 1L, &fontAttrs); 336906a4e93SYuri Dario rc = Ft2SetCharSet( hps, 1L); 337906a4e93SYuri Dario 338906a4e93SYuri Dario unicode[0] = ucs4; 339906a4e93SYuri Dario unicode[1] = 0; 340906a4e93SYuri Dario if (Ft2GetGlyphIndices( hps, unicode, 1, &glyph_index, 0) == -1) { 341906a4e93SYuri Dario glyph_index = 0; 342906a4e93SYuri Dario } 343906a4e93SYuri Dario 344906a4e93SYuri Dario WinReleasePS( hps); 345906a4e93SYuri Dario 346906a4e93SYuri Dario return glyph_index; 347906a4e93SYuri Dario } 348906a4e93SYuri Dario 349906a4e93SYuri Dario 350906a4e93SYuri Dario } // namespace cairo 351906a4e93SYuri Dario 352906a4e93SYuri Dario #endif // OS2 353