1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <string.h> 29 #include <svpm.h> 30 31 #define _SV_SALGDI2_CXX 32 #include <salbmp.h> 33 #include <saldata.hxx> 34 #ifndef _SV_SALIDS_HRC 35 #include <salids.hrc> 36 #endif 37 #include <salgdi.h> 38 #include <salvd.h> 39 #include <vcl/salbtype.hxx> 40 41 #ifndef __H_FT2LIB 42 #include <wingdi.h> 43 #include <ft2lib.h> 44 #endif 45 46 BOOL bFastTransparent = FALSE; 47 48 // ----------- 49 // - Defines - 50 // ----------- 51 52 #define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16))) 53 #define TY( y ) (mnHeight-(y)-1) 54 55 // --------------- 56 // - SalGraphics - 57 // --------------- 58 59 bool Os2SalGraphics::supportsOperation( OutDevSupportType ) const 60 { 61 return false; 62 } 63 64 65 void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) 66 { 67 HPS hSrcPS; 68 POINTL thePoints[4]; 69 long nSrcHeight; 70 71 if ( pSrcGraphics ) 72 { 73 //hSrcPS = pSrcGraphics->mhPS; 74 //nSrcHeight = pSrcGraphics->mnHeight; 75 hSrcPS = static_cast<Os2SalGraphics*>(pSrcGraphics)->mhPS; 76 nSrcHeight = static_cast<Os2SalGraphics*>(pSrcGraphics)->mnHeight; 77 } 78 else 79 { 80 hSrcPS = mhPS; 81 nSrcHeight = mnHeight; 82 } 83 84 // lower-left corner of target 85 thePoints[0].x = pPosAry->mnDestX; 86 thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 ); 87 88 // upper-right corner of target 89 thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth; 90 thePoints[1].y = TY( pPosAry->mnDestY - 1 ); 91 92 // lower-left corner of source 93 thePoints[2].x = pPosAry->mnSrcX; 94 thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); 95 96 if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) ) 97 { 98 // upper-right corner of Source 99 thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; 100 thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight; 101 102 GpiBitBlt( mhPS, hSrcPS, 4, thePoints, 103 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); 104 } 105 else 106 { 107 GpiBitBlt( mhPS, hSrcPS, 3, thePoints, 108 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); 109 } 110 } 111 112 // ----------------------------------------------------------------------- 113 114 void Os2SalGraphics::copyArea( long nDestX, long nDestY, 115 long nSrcX, long nSrcY, 116 long nSrcWidth, long nSrcHeight, 117 USHORT nFlags ) 118 { 119 POINTL thePoints[3]; 120 121 // lower-left corner of target 122 thePoints[0].x = nDestX; 123 thePoints[0].y = TY( nDestY + nSrcHeight - 1 ); 124 125 // upper-right corner of target 126 thePoints[1].x = nDestX + nSrcWidth; 127 thePoints[1].y = TY( nDestY - 1 ); 128 129 // lower-left corner of source 130 thePoints[2].x = nSrcX; 131 thePoints[2].y = TY( nSrcY + nSrcHeight - 1); 132 133 if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow ) 134 { 135 // Overlap-Bereich berechnen und invalidieren 136 Point aVCLSrcPos( nSrcX, nSrcY ); 137 Size aVCLSrcSize( nSrcWidth, nSrcHeight ); 138 Rectangle aVCLSrcRect( aVCLSrcPos, aVCLSrcSize ); 139 Rectangle aVCLClipRect; 140 SWP aSWP; 141 142 WinQueryWindowPos( mhWnd, &aSWP ); 143 aVCLClipRect.Right() = aSWP.cx-1; 144 aVCLClipRect.Bottom() = aSWP.cy-1; 145 if ( !aVCLSrcRect.Intersection( aVCLClipRect ).IsEmpty() ) 146 { 147 RECTL aSrcRect; 148 RECTL aTempRect; 149 HRGN hInvalidateRgn; 150 HRGN hTempRgn; 151 HWND hWnd; 152 long nRgnType; 153 154 long nVCLScrHeight = aVCLSrcRect.GetHeight(); 155 aSrcRect.xLeft = aVCLSrcRect.Left(); 156 aSrcRect.yBottom = TY( aVCLSrcRect.Top()+nVCLScrHeight-1 ); 157 aSrcRect.xRight = aSrcRect.xLeft+aVCLSrcRect.GetWidth(); 158 aSrcRect.yTop = aSrcRect.yBottom+nVCLScrHeight; 159 160 // Rechteck in Screen-Koordinaaten umrechnen 161 POINTL aPt; 162 long nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); 163 long nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); 164 aPt.x = 0; 165 aPt.y = 0; 166 WinMapWindowPoints( mhWnd, HWND_DESKTOP, &aPt, 1 ); 167 aSrcRect.xLeft += aPt.x; 168 aSrcRect.yTop += aPt.y; 169 aSrcRect.xRight += aPt.x; 170 aSrcRect.yBottom += aPt.y; 171 hInvalidateRgn = 0; 172 // Bereiche ausserhalb des sichtbaren Bereiches berechnen 173 if ( aSrcRect.xLeft < 0 ) 174 { 175 if ( !hInvalidateRgn ) 176 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 177 aTempRect.xLeft = -31999; 178 aTempRect.yBottom = 0; 179 aTempRect.xRight = 0; 180 aTempRect.yTop = 31999; 181 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); 182 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); 183 GpiDestroyRegion( mhPS, hTempRgn ); 184 } 185 if ( aSrcRect.yBottom < 0 ) 186 { 187 if ( !hInvalidateRgn ) 188 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 189 aTempRect.xLeft = 0; 190 aTempRect.yBottom = -31999; 191 aTempRect.xRight = 31999; 192 aTempRect.yTop = 0; 193 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); 194 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); 195 GpiDestroyRegion( mhPS, hTempRgn ); 196 } 197 if ( aSrcRect.xRight > nScreenDX ) 198 { 199 if ( !hInvalidateRgn ) 200 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 201 aTempRect.xLeft = nScreenDX; 202 aTempRect.yBottom = 0; 203 aTempRect.xRight = 31999; 204 aTempRect.yTop = 31999; 205 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); 206 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); 207 GpiDestroyRegion( mhPS, hTempRgn ); 208 } 209 if ( aSrcRect.yTop > nScreenDY ) 210 { 211 if ( !hInvalidateRgn ) 212 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 213 aTempRect.xLeft = 0; 214 aTempRect.yBottom = nScreenDY; 215 aTempRect.xRight = 31999; 216 aTempRect.yTop = 31999; 217 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); 218 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); 219 GpiDestroyRegion( mhPS, hTempRgn ); 220 } 221 222 // Bereiche die von anderen Fenstern ueberlagert werden berechnen 223 // Calculate areas that are overlapped by other windows 224 HWND hWndParent = WinQueryWindow( mhWnd, QW_PARENT ); 225 hWnd = WinQueryWindow( HWND_DESKTOP, QW_TOP ); 226 aVCLSrcRect = Rectangle( aSrcRect.xLeft, aSrcRect.yBottom, aSrcRect.xRight, aSrcRect.yTop ); 227 while ( hWnd ) 228 { 229 if ( hWnd == hWndParent ) 230 break; 231 if ( WinIsWindowVisible( hWnd ) ) 232 { 233 WinQueryWindowPos( hWnd, &aSWP ); 234 if ( !(aSWP.fl & SWP_MINIMIZE) ) 235 { 236 aVCLClipRect = Rectangle( Point( aSWP.x, aSWP.y ), Size( aSWP.cx, aSWP.cy ) ); 237 if ( aVCLSrcRect.IsOver( aVCLClipRect ) ) 238 { 239 if ( !hInvalidateRgn ) 240 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 241 aTempRect.xLeft = aSWP.x; 242 aTempRect.yBottom = aSWP.y; 243 aTempRect.xRight = aTempRect.xLeft+aSWP.cx; 244 aTempRect.yTop = aTempRect.yBottom+aSWP.cy; 245 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); 246 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); 247 GpiDestroyRegion( mhPS, hTempRgn ); 248 } 249 } 250 } 251 hWnd = WinQueryWindow( hWnd, QW_NEXT ); 252 } 253 254 if ( hInvalidateRgn ) 255 { 256 hTempRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); 257 nRgnType = GpiCombineRegion( mhPS, hInvalidateRgn, hTempRgn, hInvalidateRgn, CRGN_DIFF ); 258 GpiDestroyRegion( mhPS, hTempRgn ); 259 if ( (nRgnType != RGN_ERROR) && (nRgnType != RGN_NULL) ) 260 { 261 long nOffX = (nDestX-nSrcX); 262 long nOffY = (nSrcY-nDestY); 263 aPt.x = nOffX-aPt.x; 264 aPt.y = nOffY-aPt.y; 265 GpiOffsetRegion( mhPS, hInvalidateRgn, &aPt ); 266 WinInvalidateRegion( mhWnd, hInvalidateRgn, TRUE ); 267 // Hier loesen wir nur ein Update aus, wenn es der 268 // MainThread ist, damit es beim Bearbeiten der 269 // Paint-Message keinen Deadlock gibt, da der 270 // SolarMutex durch diesen Thread schon gelockt ist 271 SalData* pSalData = GetSalData(); 272 ULONG nCurThreadId = GetCurrentThreadId(); 273 if ( pSalData->mnAppThreadId == nCurThreadId ) 274 WinUpdateWindow( mhWnd ); 275 } 276 GpiDestroyRegion( mhPS, hInvalidateRgn ); 277 } 278 } 279 } 280 281 GpiBitBlt( mhPS, mhPS, 3, thePoints, 282 ROP_SRCCOPY, BBO_IGNORE ); 283 284 } 285 286 // ----------------------------------------------------------------------- 287 288 void ImplDrawBitmap( HPS hPS, long nScreenHeight, 289 const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap, 290 BOOL bPrinter, int nDrawMode ) 291 { 292 if( hPS ) 293 { 294 HANDLE hDrawDIB; 295 HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); 296 Os2SalBitmap* pTmpSalBmp = NULL; 297 BOOL bPrintDDB = ( bPrinter && hDrawDDB ); 298 BOOL bDrawDDB1 = ( ( rSalBitmap.GetBitCount() == 1 ) && hDrawDDB ); 299 300 if( bPrintDDB || bDrawDDB1 ) 301 { 302 pTmpSalBmp = new Os2SalBitmap; 303 pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() ); 304 hDrawDIB = pTmpSalBmp->ImplGethDIB(); 305 } 306 else 307 hDrawDIB = rSalBitmap.ImplGethDIB(); 308 309 if( hDrawDIB ) 310 { 311 HANDLE hSubst = rSalBitmap.ImplGethDIB1Subst(); 312 POINTL pts[ 4 ]; 313 BITMAPINFO2* pBI = (BITMAPINFO2*) hDrawDIB; 314 BITMAPINFOHEADER2* pBIH = (BITMAPINFOHEADER2*) pBI; 315 const long nHeight = pBIH->cy; 316 long nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 ); 317 BYTE* pBits = (BYTE*) pBI + nInfoSize; 318 319 pts[0].x = pPosAry->mnDestX; 320 pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; 321 pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; 322 pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; 323 324 pts[2].x = pPosAry->mnSrcX; 325 pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); 326 pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; 327 pts[3].y = nHeight - pPosAry->mnSrcY; 328 329 // if we've got a 1Bit DIB, we create a 4Bit substitute 330 if( ( pBIH->cBitCount == 1 ) && !hSubst ) 331 { 332 // create 4Bit substitute 333 hSubst = Os2SalBitmap::ImplCreateDIB4FromDIB1( hDrawDIB ); 334 335 // replace substitute only, if it is no temporary SalBitmap 336 if( !( bPrintDDB || bDrawDDB1 ) ) 337 ( (Os2SalBitmap&) rSalBitmap ).ImplReplacehDIB1Subst( hSubst ); 338 } 339 340 if( hSubst ) 341 { 342 pBI = (BITMAPINFO2*) hSubst; 343 pBIH = (BITMAPINFOHEADER2*) pBI; 344 nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hSubst ) * sizeof( RGB2 ); 345 pBits = (BYTE*) pBI + nInfoSize; 346 } 347 348 if( bPrinter ) 349 { 350 BYTE* pDummy; 351 352 // expand 8Bit-DIB's to 24Bit-DIB's, because some printer drivers 353 // have problems to print these DIB's (strange) 354 if( pBIH->cBitCount == 8 && pBIH->ulCompression == BCA_UNCOMP ) 355 { 356 const long nWidth = pBIH->cx; 357 const long nHeight = pBIH->cy; 358 const long nWidthAl8 = AlignedWidth4Bytes( nWidth * 8 ); 359 const long nWidthAl24 = AlignedWidth4Bytes( nWidth * 24 ); 360 const long nNewImageSize = nHeight * nWidthAl24; 361 BITMAPINFOHEADER2* pNewInfo; 362 363 pDummy = new BYTE[ sizeof( BITMAPINFO2 ) + nNewImageSize ]; 364 memset( pDummy, 0, sizeof( BITMAPINFO2 ) ); 365 366 pNewInfo = (BITMAPINFOHEADER2*) pDummy; 367 pNewInfo->cbFix = sizeof( BITMAPINFOHEADER2 ); 368 pNewInfo->cx = nWidth; 369 pNewInfo->cy = nHeight; 370 pNewInfo->cPlanes = 1; 371 pNewInfo->cBitCount = 24; 372 pNewInfo->ulCompression = BCA_UNCOMP; 373 pNewInfo->cbImage = nNewImageSize; 374 375 BYTE* pBitsSrc = (BYTE*) pBIH + nInfoSize; 376 BYTE* pBitsDst = pDummy + sizeof( BITMAPINFO2 ); 377 378 for( long nY = 0UL; nY < nHeight; nY++ ) 379 { 380 BYTE* pSrcLine = pBitsSrc + nY * nWidthAl8; 381 BYTE* pDstLine = pBitsDst + nY * nWidthAl24; 382 383 for( long nX = 0UL; nX < nWidth; nX++ ) 384 { 385 const RGB2& rQuad = pBI->argbColor[ *pSrcLine++ ]; 386 387 *pDstLine++ = rQuad.bBlue; 388 *pDstLine++ = rQuad.bGreen; 389 *pDstLine++ = rQuad.bRed; 390 } 391 } 392 393 nInfoSize = sizeof( BITMAPINFO2 ); 394 } 395 else 396 { 397 const long nImageSize = ( pBIH->cbImage ? pBIH->cbImage : ( pBIH->cy * AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ) ); 398 const long nTotalSize = nInfoSize + nImageSize; 399 400 pDummy = new BYTE[ nTotalSize ]; 401 memcpy( pDummy, pBI, nTotalSize ); 402 } 403 404 GpiDrawBits( hPS, pDummy + nInfoSize, (BITMAPINFO2*) pDummy, 4L, pts, nDrawMode, BBO_IGNORE ); 405 delete[] pDummy; 406 } 407 else 408 GpiDrawBits( hPS, pBits, pBI, 4L, pts, nDrawMode, BBO_IGNORE ); 409 } 410 else if( hDrawDDB && !bPrintDDB ) 411 { 412 POINTL pts[ 4 ]; 413 414 pts[0].x = pPosAry->mnDestX; 415 pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; 416 pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; 417 pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; 418 419 pts[2].x = pPosAry->mnSrcX; 420 pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); 421 pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; 422 pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY; 423 424 GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE ); 425 /* 426 HPS hDrawPS = ImplGetCachedPS( CACHED_HPS_DRAW, hDrawDDB ); 427 Ft2BitBlt( hPS, hDrawPS, 4, pts, nDrawMode, BBO_IGNORE ); 428 ImplReleaseCachedPS( CACHED_HPS_DRAW ); 429 */ 430 } 431 432 if( bPrintDDB || bDrawDDB1 ) 433 delete pTmpSalBmp; 434 } 435 } 436 437 // ----------------------------------------------------------------------- 438 439 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, 440 const SalBitmap& rSalBitmap ) 441 { 442 ImplDrawBitmap( mhPS, mnHeight, 443 pPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap), 444 mbPrinter, 445 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY ); 446 } 447 448 // ----------------------------------------------------------------------- 449 450 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, 451 const SalBitmap& rSalBitmap, 452 SalColor nTransparentColor ) 453 { 454 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 455 //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 456 // an FM: kann erst einmal unberuecksichtigt bleiben 457 drawBitmap( pPosAry, rSalBitmap ); 458 } 459 460 // ----------------------------------------------------------------------- 461 462 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, 463 const SalBitmap& rSSalBitmap, 464 const SalBitmap& rSTransparentBitmap ) 465 { 466 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 467 468 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 469 const Os2SalBitmap& rTransparentBitmap = static_cast<const Os2SalBitmap&>(rSTransparentBitmap); 470 471 if( bFastTransparent ) 472 { 473 ImplDrawBitmap( mhPS, mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND ); 474 ImplDrawBitmap( mhPS, mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT ); 475 } 476 else 477 { 478 SalTwoRect aPosAry = *pPosAry; 479 int nDstX = (int) aPosAry.mnDestX; 480 int nDstY = (int) aPosAry.mnDestY; 481 int nDstWidth = (int) aPosAry.mnDestWidth; 482 int nDstHeight = (int) aPosAry.mnDestHeight; 483 HAB hAB = GetSalData()->mhAB; 484 HPS hPS = mhPS; 485 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 486 SIZEL aSizeL = { nDstWidth, nDstHeight }; 487 POINTL aPtL[ 3 ]; 488 489 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 490 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 491 HBITMAP hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 ); 492 HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, hMemBitmap ); 493 HDC hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 494 HPS hMaskPS = Ft2CreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 495 HBITMAP hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 ); 496 HBITMAP hMaskOld = (HBITMAP) Ft2SetBitmap( hMaskPS, hMaskBitmap ); 497 /* 498 HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 ); 499 HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 ); 500 */ 501 aPosAry.mnDestX = aPosAry.mnDestY = 0L; 502 503 aPtL[ 0 ].x = 0; 504 aPtL[ 0 ].y = 0; 505 aPtL[ 1 ].x = nDstWidth; 506 aPtL[ 1 ].y = nDstHeight; 507 aPtL[ 2 ].x = nDstX; 508 aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 ); 509 510 GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); 511 ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY ); 512 513 aPtL[ 2 ].x = 0; 514 aPtL[ 2 ].y = 0; 515 516 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE ); 517 ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE ); 518 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE ); 519 520 aPtL[ 0 ].x = nDstX; 521 aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 ); 522 aPtL[ 1 ].x = nDstX + nDstWidth; 523 aPtL[ 1 ].y = TY( nDstY - 1 ); 524 525 GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); 526 527 Ft2SetBitmap( hMaskPS, hMaskOld ); 528 Ft2DestroyPS( hMaskPS ); 529 DevCloseDC( hMaskDC ); 530 GpiDeleteBitmap( hMaskBitmap ); 531 532 Ft2SetBitmap( hMemPS, hMemOld ); 533 Ft2DestroyPS( hMemPS ); 534 DevCloseDC( hMemDC ); 535 GpiDeleteBitmap( hMemBitmap ); 536 537 /* 538 ImplReleaseCachedPS( CACHED_HPS_1 ); 539 ImplReleaseCachedPS( CACHED_HPS_2 ); 540 */ 541 } 542 } 543 544 // ----------------------------------------------------------------------- 545 546 bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, 547 const SalBitmap& rSrcBitmap, 548 const SalBitmap& rAlphaBmp ) 549 { 550 // TODO(P3) implement alpha blending 551 return false; 552 } 553 554 // ----------------------------------------------------------------------- 555 556 bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, 557 long nHeight, sal_uInt8 nTransparency ) 558 { 559 // TODO(P3) implement alpha blending 560 return false; 561 } 562 563 // ----------------------------------------------------------------------- 564 565 void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry, 566 const SalBitmap& rSSalBitmap, 567 SalColor nMaskColor ) 568 { 569 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 570 571 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 572 573 SalTwoRect aPosAry = *pPosAry; 574 HPS hPS = mhPS; 575 IMAGEBUNDLE aBundle, aOldBundle; 576 AREABUNDLE aAreaBundle, aOldAreaBundle; 577 const ULONG nColor = RGBCOLOR( SALCOLOR_RED( nMaskColor ), 578 SALCOLOR_GREEN( nMaskColor ), 579 SALCOLOR_BLUE( nMaskColor ) ); 580 581 GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle ); 582 aBundle.lColor = RGBCOLOR( 0, 0, 0 ); 583 aBundle.lBackColor = RGBCOLOR( 0xFF, 0xFF, 0xFF ); 584 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle ); 585 586 GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 587 ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle ); 588 aAreaBundle.lColor = nColor; 589 aAreaBundle.lBackColor = nColor; 590 aAreaBundle.usSymbol = PATSYM_SOLID; 591 aAreaBundle.usMixMode = FM_OVERPAINT; 592 aAreaBundle.usBackMixMode = BM_OVERPAINT; 593 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 594 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle ); 595 596 ImplDrawBitmap( hPS, mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L ); 597 598 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle ); 599 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 600 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle ); 601 } 602 603 // ----------------------------------------------------------------------- 604 605 SalBitmap* Os2SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) 606 { 607 HAB hAB = GetSalData()->mhAB; 608 SIZEL size = { nDX, nDY }; 609 Os2SalBitmap* pSalBitmap = NULL; 610 611 // create device context (at this time allways display compatible) 612 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 613 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 614 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 615 HBITMAP hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 ); 616 HBITMAP hMemOld = Ft2SetBitmap( hMemPS, hMemBmp ); 617 618 // creation successfull? 619 if( hMemDC && hMemPS && hMemBmp ) 620 { 621 POINTL thePoints[ 3 ]; 622 623 // lower-left corner of target 624 thePoints[ 0 ].x = 0; 625 thePoints[ 0 ].y = 0; 626 627 // upper-right corner of target 628 thePoints[ 1 ].x = nDX; 629 thePoints[ 1 ].y = nDY; 630 631 // lower-left corner of source 632 thePoints[ 2 ].x = nX; 633 thePoints[ 2 ].y = TY( nY + nDY - 1 ); 634 635 long lHits = GpiBitBlt( hMemPS, mhPS, 3, thePoints, 636 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); 637 638 if( hMemPS ) 639 { 640 Ft2SetBitmap( hMemPS, hMemOld ); 641 Ft2DestroyPS( hMemPS ); 642 } 643 644 if( hMemDC ) 645 DevCloseDC( hMemDC ); 646 647 if( lHits == GPI_OK ) 648 { 649 pSalBitmap = new Os2SalBitmap; 650 651 if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) ) 652 { 653 delete pSalBitmap; 654 pSalBitmap = NULL; 655 } 656 } 657 } 658 659 if( !pSalBitmap ) 660 GpiDeleteBitmap( hMemBmp ); 661 662 // return pointer to SAL-Bitmap 663 return pSalBitmap; 664 } 665 666 // ----------------------------------------------------------------------- 667 668 SalColor Os2SalGraphics::getPixel( long nX, long nY ) 669 { 670 POINTL aPt = { nX, TY( nY ) }; 671 LONG nColor = Ft2QueryPel( mhPS, &aPt ); 672 673 return MAKE_SALCOLOR( (BYTE) ( nColor >> 16 ), (BYTE) ( nColor >> 8 ), (BYTE) nColor ); 674 } 675 676 // ----------------------------------------------------------------------- 677 678 void Os2SalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) 679 { 680 if( nFlags & SAL_INVERT_TRACKFRAME ) 681 { 682 // save old vylues 683 LINEBUNDLE oldLb; 684 LINEBUNDLE lb; 685 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); 686 687 // set linetype to short dash 688 lb.lColor = RGBCOLOR( 255, 255, 255 ); 689 lb.usMixMode = FM_XOR; 690 lb.usType = LINETYPE_ALTERNATE; 691 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); 692 693 // draw inverted box 694 POINTL aPt; 695 696 aPt.x = nX; 697 aPt.y = TY( nY ); 698 699 Ft2Move( mhPS, &aPt ); 700 701 aPt.x = nX + nWidth - 1; 702 aPt.y = TY( nY + nHeight - 1 ); 703 704 Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 ); 705 706 // restore old values 707 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); 708 709 } 710 else 711 { 712 // save old values 713 AREABUNDLE oldAb; 714 AREABUNDLE ab; 715 716 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); 717 718 // set fill color to black 719 ab.lColor = RGBCOLOR( 255, 255, 255 ); 720 ab.usMixMode = FM_XOR; 721 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; 722 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); 723 724 // draw inverted box 725 POINTL aPt; 726 727 aPt.x = nX; 728 aPt.y = TY( nY ); 729 730 Ft2Move( mhPS, &aPt ); 731 732 aPt.x = nX + nWidth - 1; 733 aPt.y = TY( nY + nHeight - 1 ); 734 735 Ft2Box( mhPS, DRO_FILL, &aPt, 0, 0 ); 736 737 // restore old values 738 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); 739 } 740 } 741 742 // ----------------------------------------------------------------------- 743 744 void Os2SalGraphics::invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags ) 745 { 746 if( nFlags & SAL_INVERT_TRACKFRAME ) 747 { 748 // save old vylues 749 LINEBUNDLE oldLb; 750 LINEBUNDLE lb; 751 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); 752 753 // set linetype to short dash 754 lb.lColor = RGBCOLOR( 255, 255, 255 ); 755 lb.usMixMode = FM_XOR; 756 lb.usType = LINETYPE_ALTERNATE; 757 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); 758 759 // Draw Polyline 760 drawPolyLine( nPoints, pPtAry ); 761 762 // restore old values 763 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); 764 } 765 else 766 { 767 // save old values 768 AREABUNDLE oldAb; 769 AREABUNDLE ab; 770 771 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); 772 773 // set fill color to black 774 ab.lColor = RGBCOLOR( 255, 255, 255 ); 775 ab.usMixMode = FM_XOR; 776 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; 777 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); 778 779 // Draw Polyline 780 drawPolygon( nPoints, pPtAry ); 781 782 // restore old values 783 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); 784 } 785 } 786 787