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