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& rPosAry, 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 = rPosAry.mnDestX; 75 thePoints[0].y = TY( rPosAry.mnDestY + rPosAry.mnDestHeight - 1 ); 76 77 // upper-right corner of target 78 thePoints[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth; 79 thePoints[1].y = TY( rPosAry.mnDestY - 1 ); 80 81 // lower-left corner of source 82 thePoints[2].x = rPosAry.mnSrcX; 83 thePoints[2].y = nSrcHeight - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); 84 85 if ( ( rPosAry.mnDestWidth != rPosAry.mnSrcWidth ) || ( rPosAry.mnDestHeight != rPosAry.mnSrcHeight ) ) 86 { 87 // upper-right corner of Source 88 thePoints[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; 89 thePoints[3].y = nSrcHeight - rPosAry.mnSrcY + rPosAry.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& rPosAry, 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 = rPosAry.mnDestX; 309 pts[0].y = nScreenHeight - rPosAry.mnDestY - rPosAry.mnDestHeight; 310 pts[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth - 1; 311 pts[1].y = nScreenHeight - rPosAry.mnDestY - 1; 312 313 pts[2].x = rPosAry.mnSrcX; 314 pts[2].y = nHeight - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); 315 pts[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; 316 pts[3].y = nHeight - rPosAry.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 = rPosAry.mnDestX; 404 pts[0].y = nScreenHeight - rPosAry.mnDestY - rPosAry.mnDestHeight; 405 pts[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth - 1; 406 pts[1].y = nScreenHeight - rPosAry.mnDestY - 1; 407 408 pts[2].x = rPosAry.mnSrcX; 409 pts[2].y = rSalBitmap.GetSize().Height() - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); 410 pts[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; 411 pts[3].y = rSalBitmap.GetSize().Height() - rPosAry.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& rPosAry, const SalBitmap& rSalBitmap ) 429 { 430 ImplDrawBitmap( mhPS, mnHeight, 431 rPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap), 432 mbPrinter, 433 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY ); 434 } 435 436 // ----------------------------------------------------------------------- 437 438 void Os2SalGraphics::drawBitmap( const SalTwoRect& rPosAry, 439 const SalBitmap& rSalBitmap, 440 SalColor nTransparentColor ) 441 { 442 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 443 //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 444 // an FM: kann erst einmal unberuecksichtigt bleiben 445 drawBitmap( rPosAry, rSalBitmap ); 446 } 447 448 // ----------------------------------------------------------------------- 449 450 void Os2SalGraphics::drawBitmap( const SalTwoRect& rPosAry, 451 const SalBitmap& rSSalBitmap, 452 const SalBitmap& rSTransparentBitmap ) 453 { 454 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 455 456 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 457 const Os2SalBitmap& rTransparentBitmap = static_cast<const Os2SalBitmap&>(rSTransparentBitmap); 458 459 if( bFastTransparent ) 460 { 461 ImplDrawBitmap( mhPS, mnHeight, rPosAry, rTransparentBitmap, FALSE, ROP_SRCAND ); 462 ImplDrawBitmap( mhPS, mnHeight, rPosAry, rSalBitmap, FALSE, ROP_SRCPAINT ); 463 } 464 else 465 { 466 SalTwoRect aPosAry = rPosAry; 467 int nDstX = (int) aPosAry.mnDestX; 468 int nDstY = (int) aPosAry.mnDestY; 469 int nDstWidth = (int) aPosAry.mnDestWidth; 470 int nDstHeight = (int) aPosAry.mnDestHeight; 471 HAB hAB = GetSalData()->mhAB; 472 HPS hPS = mhPS; 473 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 474 SIZEL aSizeL = { nDstWidth, nDstHeight }; 475 POINTL aPtL[ 3 ]; 476 477 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 478 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 479 HBITMAP hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 ); 480 HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, hMemBitmap ); 481 HDC hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 482 HPS hMaskPS = Ft2CreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 483 HBITMAP hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 ); 484 HBITMAP hMaskOld = (HBITMAP) Ft2SetBitmap( hMaskPS, hMaskBitmap ); 485 /* 486 HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 ); 487 HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 ); 488 */ 489 aPosAry.mnDestX = aPosAry.mnDestY = 0L; 490 491 aPtL[ 0 ].x = 0; 492 aPtL[ 0 ].y = 0; 493 aPtL[ 1 ].x = nDstWidth; 494 aPtL[ 1 ].y = nDstHeight; 495 aPtL[ 2 ].x = nDstX; 496 aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 ); 497 498 GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); 499 ImplDrawBitmap( hMaskPS, nDstHeight, aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY ); 500 501 aPtL[ 2 ].x = 0; 502 aPtL[ 2 ].y = 0; 503 504 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE ); 505 ImplDrawBitmap( hMaskPS, nDstHeight, aPosAry, rSalBitmap, FALSE, ROP_SRCERASE ); 506 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE ); 507 508 aPtL[ 0 ].x = nDstX; 509 aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 ); 510 aPtL[ 1 ].x = nDstX + nDstWidth; 511 aPtL[ 1 ].y = TY( nDstY - 1 ); 512 513 GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); 514 515 Ft2SetBitmap( hMaskPS, hMaskOld ); 516 Ft2DestroyPS( hMaskPS ); 517 DevCloseDC( hMaskDC ); 518 GpiDeleteBitmap( hMaskBitmap ); 519 520 Ft2SetBitmap( hMemPS, hMemOld ); 521 Ft2DestroyPS( hMemPS ); 522 DevCloseDC( hMemDC ); 523 GpiDeleteBitmap( hMemBitmap ); 524 525 /* 526 ImplReleaseCachedPS( CACHED_HPS_1 ); 527 ImplReleaseCachedPS( CACHED_HPS_2 ); 528 */ 529 } 530 } 531 532 // ----------------------------------------------------------------------- 533 534 bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, 535 const SalBitmap& rSrcBitmap, 536 const SalBitmap& rAlphaBmp ) 537 { 538 // TODO(P3) implement alpha blending 539 return false; 540 } 541 542 // ----------------------------------------------------------------------- 543 544 bool Os2SalGraphics::drawTransformedBitmap( 545 const basegfx::B2DPoint& rNull, 546 const basegfx::B2DPoint& rX, 547 const basegfx::B2DPoint& rY, 548 const SalBitmap& rSourceBitmap, 549 const SalBitmap* pAlphaBitmap) 550 { 551 // here direct support for transformed bitmaps can be impemented 552 (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; 553 return false; 554 } 555 556 // ----------------------------------------------------------------------- 557 558 bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, 559 long nHeight, sal_uInt8 nTransparency ) 560 { 561 // TODO(P3) implement alpha blending 562 return false; 563 } 564 565 // ----------------------------------------------------------------------- 566 567 void Os2SalGraphics::drawMask( const SalTwoRect& rPosAry, 568 const SalBitmap& rSSalBitmap, 569 SalColor nMaskColor ) 570 { 571 DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 572 573 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 574 575 SalTwoRect aPosAry = rPosAry; 576 HPS hPS = mhPS; 577 IMAGEBUNDLE aBundle, aOldBundle; 578 AREABUNDLE aAreaBundle, aOldAreaBundle; 579 const ULONG nColor = MAKE_SALCOLOR( SALCOLOR_RED( nMaskColor ), 580 SALCOLOR_GREEN( nMaskColor ), 581 SALCOLOR_BLUE( nMaskColor ) ); 582 583 GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle ); 584 aBundle.lColor = MAKE_SALCOLOR( 0, 0, 0 ); 585 aBundle.lBackColor = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); 586 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle ); 587 588 GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 589 ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle ); 590 aAreaBundle.lColor = nColor; 591 aAreaBundle.lBackColor = nColor; 592 aAreaBundle.usSymbol = PATSYM_SOLID; 593 aAreaBundle.usMixMode = FM_OVERPAINT; 594 aAreaBundle.usBackMixMode = BM_OVERPAINT; 595 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 596 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle ); 597 598 ImplDrawBitmap( hPS, mnHeight, aPosAry, rSalBitmap, FALSE, 0x00B8L ); 599 600 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle ); 601 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | 602 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle ); 603 } 604 605 // ----------------------------------------------------------------------- 606 607 SalBitmap* Os2SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) 608 { 609 HAB hAB = GetSalData()->mhAB; 610 SIZEL size = { nDX, nDY }; 611 Os2SalBitmap* pSalBitmap = NULL; 612 613 // create device context (at this time allways display compatible) 614 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 615 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 616 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 617 HBITMAP hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 ); 618 HBITMAP hMemOld = Ft2SetBitmap( hMemPS, hMemBmp ); 619 620 // creation successfull? 621 if( hMemDC && hMemPS && hMemBmp ) 622 { 623 POINTL thePoints[ 3 ]; 624 625 // lower-left corner of target 626 thePoints[ 0 ].x = 0; 627 thePoints[ 0 ].y = 0; 628 629 // upper-right corner of target 630 thePoints[ 1 ].x = nDX; 631 thePoints[ 1 ].y = nDY; 632 633 // lower-left corner of source 634 thePoints[ 2 ].x = nX; 635 thePoints[ 2 ].y = TY( nY + nDY - 1 ); 636 637 long lHits = GpiBitBlt( hMemPS, mhPS, 3, thePoints, 638 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); 639 640 if( hMemPS ) 641 { 642 Ft2SetBitmap( hMemPS, hMemOld ); 643 Ft2DestroyPS( hMemPS ); 644 } 645 646 if( hMemDC ) 647 DevCloseDC( hMemDC ); 648 649 if( lHits == GPI_OK ) 650 { 651 pSalBitmap = new Os2SalBitmap; 652 653 if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) ) 654 { 655 delete pSalBitmap; 656 pSalBitmap = NULL; 657 } 658 } 659 } 660 661 if( !pSalBitmap ) 662 GpiDeleteBitmap( hMemBmp ); 663 664 // return pointer to SAL-Bitmap 665 return pSalBitmap; 666 } 667 668 // ----------------------------------------------------------------------- 669 670 SalColor Os2SalGraphics::getPixel( long nX, long nY ) 671 { 672 POINTL aPt = { nX, TY( nY ) }; 673 LONG nColor = Ft2QueryPel( mhPS, &aPt ); 674 675 return MAKE_SALCOLOR( (PM_BYTE) ( nColor >> 16 ), (PM_BYTE) ( nColor >> 8 ), (PM_BYTE) nColor ); 676 } 677 678 // ----------------------------------------------------------------------- 679 680 void Os2SalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) 681 { 682 if( nFlags & SAL_INVERT_TRACKFRAME ) 683 { 684 // save old vylues 685 LINEBUNDLE oldLb; 686 LINEBUNDLE lb; 687 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); 688 689 // set linetype to short dash 690 lb.lColor = MAKE_SALCOLOR( 255, 255, 255 ); 691 lb.usMixMode = FM_XOR; 692 lb.usType = LINETYPE_ALTERNATE; 693 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); 694 695 // draw inverted box 696 POINTL aPt; 697 698 aPt.x = nX; 699 aPt.y = TY( nY ); 700 701 Ft2Move( mhPS, &aPt ); 702 703 aPt.x = nX + nWidth - 1; 704 aPt.y = TY( nY + nHeight - 1 ); 705 706 Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 ); 707 708 // restore old values 709 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); 710 711 } 712 else 713 { 714 // save old values 715 AREABUNDLE oldAb; 716 AREABUNDLE ab; 717 718 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); 719 720 // set fill color to black 721 ab.lColor = MAKE_SALCOLOR( 255, 255, 255 ); 722 ab.usMixMode = FM_XOR; 723 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; 724 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); 725 726 // draw inverted box 727 POINTL aPt; 728 729 aPt.x = nX; 730 aPt.y = TY( nY ); 731 732 Ft2Move( mhPS, &aPt ); 733 734 aPt.x = nX + nWidth - 1; 735 aPt.y = TY( nY + nHeight - 1 ); 736 737 Ft2Box( mhPS, DRO_FILL, &aPt, 0, 0 ); 738 739 // restore old values 740 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); 741 } 742 } 743 744 // ----------------------------------------------------------------------- 745 746 void Os2SalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) 747 { 748 if( nFlags & SAL_INVERT_TRACKFRAME ) 749 { 750 // save old vylues 751 LINEBUNDLE oldLb; 752 LINEBUNDLE lb; 753 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); 754 755 // set linetype to short dash 756 lb.lColor = MAKE_SALCOLOR( 255, 255, 255 ); 757 lb.usMixMode = FM_XOR; 758 lb.usType = LINETYPE_ALTERNATE; 759 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); 760 761 // Draw Polyline 762 drawPolyLine( nPoints, pPtAry ); 763 764 // restore old values 765 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); 766 } 767 else 768 { 769 // save old values 770 AREABUNDLE oldAb; 771 AREABUNDLE ab; 772 773 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); 774 775 // set fill color to black 776 ab.lColor = MAKE_SALCOLOR( 255, 255, 255 ); 777 ab.usMixMode = FM_XOR; 778 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; 779 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); 780 781 // Draw Polyline 782 drawPolygon( nPoints, pPtAry ); 783 784 // restore old values 785 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); 786 } 787 } 788 789