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