1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <string.h> 28cdf0e10cSrcweir #include <stdlib.h> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include <tools/svwin.h> 31cdf0e10cSrcweir #include <tools/debug.hxx> 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include <win/wincomp.hxx> 34cdf0e10cSrcweir #include <win/salbmp.h> 35cdf0e10cSrcweir #include <win/saldata.hxx> 36cdf0e10cSrcweir #include <win/salids.hrc> 37cdf0e10cSrcweir #include <win/salgdi.h> 38cdf0e10cSrcweir #include <win/salframe.h> 39cdf0e10cSrcweir 40cdf0e10cSrcweir bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const 41cdf0e10cSrcweir { 42cdf0e10cSrcweir static bool bAllowForTest(true); 43cdf0e10cSrcweir bool bRet = false; 44cdf0e10cSrcweir 45cdf0e10cSrcweir switch( eType ) 46cdf0e10cSrcweir { 47cdf0e10cSrcweir case OutDevSupport_TransparentRect: 48cdf0e10cSrcweir bRet = mbVirDev || mbWindow; 49cdf0e10cSrcweir break; 50cdf0e10cSrcweir case OutDevSupport_B2DClip: 51cdf0e10cSrcweir bRet = true; 52cdf0e10cSrcweir break; 53cdf0e10cSrcweir case OutDevSupport_B2DDraw: 54cdf0e10cSrcweir bRet = bAllowForTest; 55cdf0e10cSrcweir default: break; 56cdf0e10cSrcweir } 57cdf0e10cSrcweir return bRet; 58cdf0e10cSrcweir } 59cdf0e10cSrcweir 60cdf0e10cSrcweir // ======================================================================= 61cdf0e10cSrcweir 62cdf0e10cSrcweir void WinSalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir HDC hSrcDC; 65cdf0e10cSrcweir DWORD nRop; 66cdf0e10cSrcweir 67cdf0e10cSrcweir if ( pSrcGraphics ) 68cdf0e10cSrcweir hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->mhDC; 69cdf0e10cSrcweir else 70cdf0e10cSrcweir hSrcDC = mhDC; 71cdf0e10cSrcweir 72cdf0e10cSrcweir if ( mbXORMode ) 73cdf0e10cSrcweir nRop = SRCINVERT; 74cdf0e10cSrcweir else 75cdf0e10cSrcweir nRop = SRCCOPY; 76cdf0e10cSrcweir 77cdf0e10cSrcweir if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && 78cdf0e10cSrcweir (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) 79cdf0e10cSrcweir { 80cdf0e10cSrcweir BitBlt( mhDC, 81cdf0e10cSrcweir (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, 82cdf0e10cSrcweir (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, 83cdf0e10cSrcweir hSrcDC, 84cdf0e10cSrcweir (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, 85cdf0e10cSrcweir nRop ); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir else 88cdf0e10cSrcweir { 89cdf0e10cSrcweir int nOldStretchMode = SetStretchBltMode( mhDC, STRETCH_DELETESCANS ); 90cdf0e10cSrcweir StretchBlt( mhDC, 91cdf0e10cSrcweir (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, 92cdf0e10cSrcweir (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, 93cdf0e10cSrcweir hSrcDC, 94cdf0e10cSrcweir (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, 95cdf0e10cSrcweir (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, 96cdf0e10cSrcweir nRop ); 97cdf0e10cSrcweir SetStretchBltMode( mhDC, nOldStretchMode ); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir // ----------------------------------------------------------------------- 102cdf0e10cSrcweir 103cdf0e10cSrcweir void ImplCalcOutSideRgn( const RECT& rSrcRect, 104cdf0e10cSrcweir int nLeft, int nTop, int nRight, int nBottom, 105cdf0e10cSrcweir HRGN& rhInvalidateRgn ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir HRGN hTempRgn; 108cdf0e10cSrcweir 109cdf0e10cSrcweir // Bereiche ausserhalb des sichtbaren Bereiches berechnen 110cdf0e10cSrcweir if ( rSrcRect.left < nLeft ) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir if ( !rhInvalidateRgn ) 113cdf0e10cSrcweir rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); 114cdf0e10cSrcweir hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 ); 115cdf0e10cSrcweir CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); 116cdf0e10cSrcweir DeleteRegion( hTempRgn ); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir if ( rSrcRect.top < nTop ) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir if ( !rhInvalidateRgn ) 121cdf0e10cSrcweir rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); 122cdf0e10cSrcweir hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop ); 123cdf0e10cSrcweir CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); 124cdf0e10cSrcweir DeleteRegion( hTempRgn ); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir if ( rSrcRect.right > nRight ) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir if ( !rhInvalidateRgn ) 129cdf0e10cSrcweir rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); 130cdf0e10cSrcweir hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 ); 131cdf0e10cSrcweir CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); 132cdf0e10cSrcweir DeleteRegion( hTempRgn ); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir if ( rSrcRect.bottom > nBottom ) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir if ( !rhInvalidateRgn ) 137cdf0e10cSrcweir rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); 138cdf0e10cSrcweir hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 ); 139cdf0e10cSrcweir CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); 140cdf0e10cSrcweir DeleteRegion( hTempRgn ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir // ----------------------------------------------------------------------- 145cdf0e10cSrcweir 146cdf0e10cSrcweir void WinSalGraphics::copyArea( long nDestX, long nDestY, 147cdf0e10cSrcweir long nSrcX, long nSrcY, 148cdf0e10cSrcweir long nSrcWidth, long nSrcHeight, 149cdf0e10cSrcweir sal_uInt16 nFlags ) 150cdf0e10cSrcweir { 151cdf0e10cSrcweir bool bRestoreClipRgn = false; 152cdf0e10cSrcweir HRGN hOldClipRgn = 0; 153cdf0e10cSrcweir int nOldClipRgnType = ERROR; 154cdf0e10cSrcweir HRGN hInvalidateRgn = 0; 155cdf0e10cSrcweir 156cdf0e10cSrcweir // Muessen die ueberlappenden Bereiche auch invalidiert werden? 157cdf0e10cSrcweir if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow ) 158cdf0e10cSrcweir { 159cdf0e10cSrcweir // compute and invalidate those parts that were either off-screen or covered by other windows 160cdf0e10cSrcweir // while performing the above BitBlt 161cdf0e10cSrcweir // those regions then have to be invalidated as they contain useless/wrong data 162cdf0e10cSrcweir RECT aSrcRect; 163cdf0e10cSrcweir RECT aClipRect; 164cdf0e10cSrcweir RECT aTempRect; 165cdf0e10cSrcweir RECT aTempRect2; 166cdf0e10cSrcweir HRGN hTempRgn; 167cdf0e10cSrcweir HWND hWnd; 168cdf0e10cSrcweir int nRgnType; 169cdf0e10cSrcweir 170cdf0e10cSrcweir // restrict srcRect to this window (calc intersection) 171cdf0e10cSrcweir aSrcRect.left = (int)nSrcX; 172cdf0e10cSrcweir aSrcRect.top = (int)nSrcY; 173cdf0e10cSrcweir aSrcRect.right = aSrcRect.left+(int)nSrcWidth; 174cdf0e10cSrcweir aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight; 175cdf0e10cSrcweir GetClientRect( mhWnd, &aClipRect ); 176cdf0e10cSrcweir if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) ) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir // transform srcRect to screen coordinates 179cdf0e10cSrcweir POINT aPt; 180cdf0e10cSrcweir aPt.x = 0; 181cdf0e10cSrcweir aPt.y = 0; 182cdf0e10cSrcweir ClientToScreen( mhWnd, &aPt ); 183cdf0e10cSrcweir aSrcRect.left += aPt.x; 184cdf0e10cSrcweir aSrcRect.top += aPt.y; 185cdf0e10cSrcweir aSrcRect.right += aPt.x; 186cdf0e10cSrcweir aSrcRect.bottom += aPt.y; 187cdf0e10cSrcweir hInvalidateRgn = 0; 188cdf0e10cSrcweir 189cdf0e10cSrcweir // compute the parts that are off screen (ie invisible) 190cdf0e10cSrcweir RECT theScreen; 191cdf0e10cSrcweir ImplSalGetWorkArea( NULL, &theScreen, NULL ); // find the screen area taking multiple monitors into account 192cdf0e10cSrcweir ImplCalcOutSideRgn( aSrcRect, theScreen.left, theScreen.top, theScreen.right, theScreen.bottom, hInvalidateRgn ); 193cdf0e10cSrcweir 194cdf0e10cSrcweir // Bereiche die von anderen Fenstern ueberlagert werden berechnen 195cdf0e10cSrcweir HRGN hTempRgn2 = 0; 196cdf0e10cSrcweir HWND hWndTopWindow = mhWnd; 197cdf0e10cSrcweir // Find the TopLevel Window, because only Windows which are in 198cdf0e10cSrcweir // in the foreground of our TopLevel window must be considered 199cdf0e10cSrcweir if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD ) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir RECT aTempRect3 = aSrcRect; 202cdf0e10cSrcweir do 203cdf0e10cSrcweir { 204cdf0e10cSrcweir hWndTopWindow = ::GetParent( hWndTopWindow ); 205cdf0e10cSrcweir 206cdf0e10cSrcweir // Test, if the Parent clips our window 207cdf0e10cSrcweir GetClientRect( hWndTopWindow, &aTempRect ); 208cdf0e10cSrcweir POINT aPt2; 209cdf0e10cSrcweir aPt2.x = 0; 210cdf0e10cSrcweir aPt2.y = 0; 211cdf0e10cSrcweir ClientToScreen( hWndTopWindow, &aPt2 ); 212cdf0e10cSrcweir aTempRect.left += aPt2.x; 213cdf0e10cSrcweir aTempRect.top += aPt2.y; 214cdf0e10cSrcweir aTempRect.right += aPt2.x; 215cdf0e10cSrcweir aTempRect.bottom += aPt2.y; 216cdf0e10cSrcweir IntersectRect( &aTempRect3, &aTempRect3, &aTempRect ); 217cdf0e10cSrcweir } 218cdf0e10cSrcweir while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD ); 219cdf0e10cSrcweir 220cdf0e10cSrcweir // If one or more Parents clip our window, than we must 221cdf0e10cSrcweir // calculate the outside area 222cdf0e10cSrcweir if ( !EqualRect( &aSrcRect, &aTempRect3 ) ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir ImplCalcOutSideRgn( aSrcRect, 225cdf0e10cSrcweir aTempRect3.left, aTempRect3.top, 226cdf0e10cSrcweir aTempRect3.right, aTempRect3.bottom, 227cdf0e10cSrcweir hInvalidateRgn ); 228cdf0e10cSrcweir } 229cdf0e10cSrcweir } 230cdf0e10cSrcweir // retrieve the top-most (z-order) child window 231cdf0e10cSrcweir hWnd = GetWindow( GetDesktopWindow(), GW_CHILD ); 232cdf0e10cSrcweir while ( hWnd ) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir if ( hWnd == hWndTopWindow ) 235cdf0e10cSrcweir break; 236cdf0e10cSrcweir if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) ) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir GetWindowRect( hWnd, &aTempRect ); 239cdf0e10cSrcweir if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir // hWnd covers part or all of aSrcRect 242cdf0e10cSrcweir if ( !hInvalidateRgn ) 243cdf0e10cSrcweir hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect ); 244cdf0e10cSrcweir 245cdf0e10cSrcweir // get full bounding box of hWnd 246cdf0e10cSrcweir hTempRgn = CreateRectRgnIndirect( &aTempRect ); 247cdf0e10cSrcweir 248cdf0e10cSrcweir // get region of hWnd (the window may be shaped) 249cdf0e10cSrcweir if ( !hTempRgn2 ) 250cdf0e10cSrcweir hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 ); 251cdf0e10cSrcweir nRgnType = GetWindowRgn( hWnd, hTempRgn2 ); 252cdf0e10cSrcweir if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) ) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir // convert window region to screen coordinates 255cdf0e10cSrcweir OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top ); 256cdf0e10cSrcweir // and intersect with the window's bounding box 257cdf0e10cSrcweir CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND ); 258cdf0e10cSrcweir } 259cdf0e10cSrcweir // finally compute that part of aSrcRect which is not covered by any parts of hWnd 260cdf0e10cSrcweir CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF ); 261cdf0e10cSrcweir DeleteRegion( hTempRgn ); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir } 264cdf0e10cSrcweir // retrieve the next window in the z-order, i.e. the window below hwnd 265cdf0e10cSrcweir hWnd = GetWindow( hWnd, GW_HWNDNEXT ); 266cdf0e10cSrcweir } 267cdf0e10cSrcweir if ( hTempRgn2 ) 268cdf0e10cSrcweir DeleteRegion( hTempRgn2 ); 269cdf0e10cSrcweir if ( hInvalidateRgn ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir // hInvalidateRgn contains the fully visible parts of the original srcRect 272cdf0e10cSrcweir hTempRgn = CreateRectRgnIndirect( &aSrcRect ); 273cdf0e10cSrcweir // substract it from the original rect to get the occluded parts 274cdf0e10cSrcweir nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF ); 275cdf0e10cSrcweir DeleteRegion( hTempRgn ); 276cdf0e10cSrcweir 277cdf0e10cSrcweir if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) ) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir // move the occluded parts to the destination pos 280cdf0e10cSrcweir int nOffX = (int)(nDestX-nSrcX); 281cdf0e10cSrcweir int nOffY = (int)(nDestY-nSrcY); 282cdf0e10cSrcweir OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y ); 283cdf0e10cSrcweir 284cdf0e10cSrcweir // by excluding hInvalidateRgn from the system's clip region 285cdf0e10cSrcweir // we will prevent bitblt from copying useless data 286cdf0e10cSrcweir // epsecially now shadows from overlapping windows will appear (#i36344) 287cdf0e10cSrcweir hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 ); 288cdf0e10cSrcweir nOldClipRgnType = GetClipRgn( mhDC, hOldClipRgn ); 289cdf0e10cSrcweir 290cdf0e10cSrcweir bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate 291cdf0e10cSrcweir ExtSelectClipRgn( mhDC, hInvalidateRgn, RGN_DIFF ); 292cdf0e10cSrcweir } 293cdf0e10cSrcweir } 294cdf0e10cSrcweir } 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297cdf0e10cSrcweir BitBlt( mhDC, 298cdf0e10cSrcweir (int)nDestX, (int)nDestY, 299cdf0e10cSrcweir (int)nSrcWidth, (int)nSrcHeight, 300cdf0e10cSrcweir mhDC, 301cdf0e10cSrcweir (int)nSrcX, (int)nSrcY, 302cdf0e10cSrcweir SRCCOPY ); 303cdf0e10cSrcweir 304cdf0e10cSrcweir if( bRestoreClipRgn ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir // restore old clip region 307cdf0e10cSrcweir if( nOldClipRgnType != ERROR ) 308cdf0e10cSrcweir SelectClipRgn( mhDC, hOldClipRgn); 309cdf0e10cSrcweir DeleteRegion( hOldClipRgn ); 310cdf0e10cSrcweir 311cdf0e10cSrcweir // invalidate regions that were not copied 312cdf0e10cSrcweir bool bInvalidate = true; 313cdf0e10cSrcweir 314cdf0e10cSrcweir // Combine Invalidate Region with existing ClipRegion 315cdf0e10cSrcweir HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 ); 316cdf0e10cSrcweir if ( GetClipRgn( mhDC, hTempRgn ) == 1 ) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND ); 319cdf0e10cSrcweir if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) ) 320cdf0e10cSrcweir bInvalidate = false; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir DeleteRegion( hTempRgn ); 323cdf0e10cSrcweir 324cdf0e10cSrcweir if ( bInvalidate ) 325cdf0e10cSrcweir { 326cdf0e10cSrcweir InvalidateRgn( mhWnd, hInvalidateRgn, TRUE ); 327cdf0e10cSrcweir // Hier loesen wir nur ein Update aus, wenn es der 328cdf0e10cSrcweir // MainThread ist, damit es beim Bearbeiten der 329cdf0e10cSrcweir // Paint-Message keinen Deadlock gibt, da der 330cdf0e10cSrcweir // SolarMutex durch diesen Thread schon gelockt ist 331cdf0e10cSrcweir SalData* pSalData = GetSalData(); 332cdf0e10cSrcweir DWORD nCurThreadId = GetCurrentThreadId(); 333cdf0e10cSrcweir if ( pSalData->mnAppThreadId == nCurThreadId ) 334cdf0e10cSrcweir UpdateWindow( mhWnd ); 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir DeleteRegion( hInvalidateRgn ); 338cdf0e10cSrcweir } 339cdf0e10cSrcweir 340cdf0e10cSrcweir } 341cdf0e10cSrcweir 342cdf0e10cSrcweir // ----------------------------------------------------------------------- 343cdf0e10cSrcweir 344cdf0e10cSrcweir void ImplDrawBitmap( HDC hDC, 345cdf0e10cSrcweir const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap, 346cdf0e10cSrcweir sal_Bool bPrinter, int nDrawMode ) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir if( hDC ) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir HGLOBAL hDrawDIB; 351cdf0e10cSrcweir HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); 352cdf0e10cSrcweir WinSalBitmap* pTmpSalBmp = NULL; 353cdf0e10cSrcweir sal_Bool bPrintDDB = ( bPrinter && hDrawDDB ); 354cdf0e10cSrcweir 355cdf0e10cSrcweir if( bPrintDDB ) 356cdf0e10cSrcweir { 357cdf0e10cSrcweir pTmpSalBmp = new WinSalBitmap; 358cdf0e10cSrcweir pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() ); 359cdf0e10cSrcweir hDrawDIB = pTmpSalBmp->ImplGethDIB(); 360cdf0e10cSrcweir } 361cdf0e10cSrcweir else 362cdf0e10cSrcweir hDrawDIB = rSalBitmap.ImplGethDIB(); 363cdf0e10cSrcweir 364cdf0e10cSrcweir if( hDrawDIB ) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB ); 367cdf0e10cSrcweir PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI; 368cdf0e10cSrcweir PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI + 369cdf0e10cSrcweir rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD ); 370cdf0e10cSrcweir const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); 371cdf0e10cSrcweir 372cdf0e10cSrcweir StretchDIBits( hDC, 373cdf0e10cSrcweir (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, 374cdf0e10cSrcweir (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, 375cdf0e10cSrcweir (int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY), 376cdf0e10cSrcweir (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, 377cdf0e10cSrcweir pBits, pBI, DIB_RGB_COLORS, nDrawMode ); 378cdf0e10cSrcweir 379cdf0e10cSrcweir GlobalUnlock( hDrawDIB ); 380cdf0e10cSrcweir SetStretchBltMode( hDC, nOldStretchMode ); 381cdf0e10cSrcweir } 382cdf0e10cSrcweir else if( hDrawDDB && !bPrintDDB ) 383cdf0e10cSrcweir { 384cdf0e10cSrcweir HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB ); 385cdf0e10cSrcweir COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF); 386cdf0e10cSrcweir COLORREF nOldTextColor = RGB(0,0,0); 387cdf0e10cSrcweir sal_Bool bMono = ( rSalBitmap.GetBitCount() == 1 ); 388cdf0e10cSrcweir 389cdf0e10cSrcweir if( bMono ) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir nOldBkColor = SetBkColor( hDC, RGB( 0xFF, 0xFF, 0xFF ) ); 392cdf0e10cSrcweir nOldTextColor = ::SetTextColor( hDC, RGB( 0x00, 0x00, 0x00 ) ); 393cdf0e10cSrcweir } 394cdf0e10cSrcweir 395cdf0e10cSrcweir if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && 396cdf0e10cSrcweir (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) 397cdf0e10cSrcweir { 398cdf0e10cSrcweir BitBlt( hDC, 399cdf0e10cSrcweir (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, 400cdf0e10cSrcweir (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, 401cdf0e10cSrcweir hBmpDC, 402cdf0e10cSrcweir (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, 403cdf0e10cSrcweir nDrawMode ); 404cdf0e10cSrcweir } 405cdf0e10cSrcweir else 406cdf0e10cSrcweir { 407cdf0e10cSrcweir const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); 408cdf0e10cSrcweir 409cdf0e10cSrcweir StretchBlt( hDC, 410cdf0e10cSrcweir (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, 411cdf0e10cSrcweir (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, 412cdf0e10cSrcweir hBmpDC, 413cdf0e10cSrcweir (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, 414cdf0e10cSrcweir (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, 415cdf0e10cSrcweir nDrawMode ); 416cdf0e10cSrcweir 417cdf0e10cSrcweir SetStretchBltMode( hDC, nOldStretchMode ); 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir if( bMono ) 421cdf0e10cSrcweir { 422cdf0e10cSrcweir SetBkColor( hDC, nOldBkColor ); 423cdf0e10cSrcweir ::SetTextColor( hDC, nOldTextColor ); 424cdf0e10cSrcweir } 425cdf0e10cSrcweir 426cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_DRAW ); 427cdf0e10cSrcweir } 428cdf0e10cSrcweir 429cdf0e10cSrcweir if( bPrintDDB ) 430cdf0e10cSrcweir delete pTmpSalBmp; 431cdf0e10cSrcweir } 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir // ----------------------------------------------------------------------- 435cdf0e10cSrcweir 436cdf0e10cSrcweir void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, 437cdf0e10cSrcweir const SalBitmap& rSalBitmap ) 438cdf0e10cSrcweir { 439cdf0e10cSrcweir ImplDrawBitmap( mhDC, pPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), 440cdf0e10cSrcweir mbPrinter, 441cdf0e10cSrcweir mbXORMode ? SRCINVERT : SRCCOPY ); 442cdf0e10cSrcweir } 443cdf0e10cSrcweir 444cdf0e10cSrcweir // ----------------------------------------------------------------------- 445cdf0e10cSrcweir 446cdf0e10cSrcweir void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, 447cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 448cdf0e10cSrcweir SalColor nTransparentColor ) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 451cdf0e10cSrcweir 452cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 453cdf0e10cSrcweir 454cdf0e10cSrcweir WinSalBitmap* pMask = new WinSalBitmap; 455cdf0e10cSrcweir const Point aPoint; 456cdf0e10cSrcweir const Size aSize( rSalBitmap.GetSize() ); 457cdf0e10cSrcweir HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL ); 458cdf0e10cSrcweir HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap ); 459cdf0e10cSrcweir const BYTE cRed = SALCOLOR_RED( nTransparentColor ); 460cdf0e10cSrcweir const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor ); 461cdf0e10cSrcweir const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor ); 462cdf0e10cSrcweir 463cdf0e10cSrcweir if( rSalBitmap.ImplGethDDB() ) 464cdf0e10cSrcweir { 465cdf0e10cSrcweir HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() ); 466cdf0e10cSrcweir COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); 467cdf0e10cSrcweir 468cdf0e10cSrcweir BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); 469cdf0e10cSrcweir 470cdf0e10cSrcweir SetBkColor( hSrcDC, aOldCol ); 471cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 472cdf0e10cSrcweir } 473cdf0e10cSrcweir else 474cdf0e10cSrcweir { 475cdf0e10cSrcweir WinSalBitmap* pTmpSalBmp = new WinSalBitmap; 476cdf0e10cSrcweir 477cdf0e10cSrcweir if( pTmpSalBmp->Create( rSalBitmap, this ) ) 478cdf0e10cSrcweir { 479cdf0e10cSrcweir HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() ); 480cdf0e10cSrcweir COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); 481cdf0e10cSrcweir 482cdf0e10cSrcweir BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); 483cdf0e10cSrcweir 484cdf0e10cSrcweir SetBkColor( hSrcDC, aOldCol ); 485cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 486cdf0e10cSrcweir } 487cdf0e10cSrcweir 488cdf0e10cSrcweir delete pTmpSalBmp; 489cdf0e10cSrcweir } 490cdf0e10cSrcweir 491cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 492cdf0e10cSrcweir 493cdf0e10cSrcweir // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE ) 494cdf0e10cSrcweir if( pMask->Create( hMaskBitmap, FALSE, FALSE ) ) 495cdf0e10cSrcweir drawBitmap( pPosAry, rSalBitmap, *pMask ); 496cdf0e10cSrcweir 497cdf0e10cSrcweir delete pMask; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir 500cdf0e10cSrcweir // ----------------------------------------------------------------------- 501cdf0e10cSrcweir 502cdf0e10cSrcweir void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, 503cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 504cdf0e10cSrcweir const SalBitmap& rSTransparentBitmap ) 505cdf0e10cSrcweir { 506cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 507cdf0e10cSrcweir 508cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 509cdf0e10cSrcweir const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap); 510cdf0e10cSrcweir 511cdf0e10cSrcweir SalTwoRect aPosAry = *pPosAry; 512cdf0e10cSrcweir int nDstX = (int)aPosAry.mnDestX; 513cdf0e10cSrcweir int nDstY = (int)aPosAry.mnDestY; 514cdf0e10cSrcweir int nDstWidth = (int)aPosAry.mnDestWidth; 515cdf0e10cSrcweir int nDstHeight = (int)aPosAry.mnDestHeight; 516cdf0e10cSrcweir HDC hDC = mhDC; 517cdf0e10cSrcweir HBITMAP hMemBitmap = 0; 518cdf0e10cSrcweir HBITMAP hMaskBitmap = 0; 519cdf0e10cSrcweir 520cdf0e10cSrcweir if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) ) 521cdf0e10cSrcweir { 522cdf0e10cSrcweir hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); 523cdf0e10cSrcweir hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); 524cdf0e10cSrcweir } 525cdf0e10cSrcweir 526cdf0e10cSrcweir HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap ); 527cdf0e10cSrcweir HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap ); 528cdf0e10cSrcweir 529cdf0e10cSrcweir aPosAry.mnDestX = aPosAry.mnDestY = 0; 530cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY ); 531cdf0e10cSrcweir 532cdf0e10cSrcweir // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem, 533cdf0e10cSrcweir // die Farben der Maske richtig auf die Palette abzubilden, 534cdf0e10cSrcweir // wenn wir die DIB direkt ausgeben => DDB-Ausgabe 535cdf0e10cSrcweir if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 ) 536cdf0e10cSrcweir { 537cdf0e10cSrcweir WinSalBitmap aTmp; 538cdf0e10cSrcweir 539cdf0e10cSrcweir if( aTmp.Create( rTransparentBitmap, this ) ) 540cdf0e10cSrcweir ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY ); 541cdf0e10cSrcweir } 542cdf0e10cSrcweir else 543cdf0e10cSrcweir ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); 544cdf0e10cSrcweir 545cdf0e10cSrcweir // now MemDC contains background, MaskDC the transparency mask 546cdf0e10cSrcweir 547cdf0e10cSrcweir // #105055# Respect XOR mode 548cdf0e10cSrcweir if( mbXORMode ) 549cdf0e10cSrcweir { 550cdf0e10cSrcweir ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE ); 551cdf0e10cSrcweir // now MaskDC contains the bitmap area with black background 552cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT ); 553cdf0e10cSrcweir // now MemDC contains background XORed bitmap area ontop 554cdf0e10cSrcweir } 555cdf0e10cSrcweir else 556cdf0e10cSrcweir { 557cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND ); 558cdf0e10cSrcweir // now MemDC contains background with masked-out bitmap area 559cdf0e10cSrcweir ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE ); 560cdf0e10cSrcweir // now MaskDC contains the bitmap area with black background 561cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT ); 562cdf0e10cSrcweir // now MemDC contains background and bitmap merged together 563cdf0e10cSrcweir } 564cdf0e10cSrcweir // copy to output DC 565cdf0e10cSrcweir BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY ); 566cdf0e10cSrcweir 567cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 568cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 569cdf0e10cSrcweir 570cdf0e10cSrcweir // hMemBitmap != 0 ==> hMaskBitmap != 0 571cdf0e10cSrcweir if( hMemBitmap ) 572cdf0e10cSrcweir { 573cdf0e10cSrcweir DeleteObject( hMemBitmap ); 574cdf0e10cSrcweir DeleteObject( hMaskBitmap ); 575cdf0e10cSrcweir } 576cdf0e10cSrcweir } 577cdf0e10cSrcweir 578cdf0e10cSrcweir // ----------------------------------------------------------------------- 579cdf0e10cSrcweir 580cdf0e10cSrcweir bool WinSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, 581cdf0e10cSrcweir const SalBitmap& rSrcBitmap, 582cdf0e10cSrcweir const SalBitmap& rAlphaBmp ) 583cdf0e10cSrcweir { 584cdf0e10cSrcweir (void)rTR; (void)rSrcBitmap; (void)rAlphaBmp; 585cdf0e10cSrcweir 586cdf0e10cSrcweir // TODO(P3): implement alpha bmp blits. Catch: Windows only 587cdf0e10cSrcweir // handles 32bpp, premultiplied bitmaps 588cdf0e10cSrcweir return false; 589cdf0e10cSrcweir } 590cdf0e10cSrcweir 591cdf0e10cSrcweir // ----------------------------------------------------------------------- 592cdf0e10cSrcweir 593cdf0e10cSrcweir bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, 594cdf0e10cSrcweir long nHeight, sal_uInt8 nTransparency ) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir if( mbPen || !mbBrush || mbXORMode ) 597cdf0e10cSrcweir return false; // can only perform solid fills without XOR. 598cdf0e10cSrcweir 599cdf0e10cSrcweir HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 ); 600cdf0e10cSrcweir SetPixel( hMemDC, (int)0, (int)0, mnBrushColor ); 601cdf0e10cSrcweir 602cdf0e10cSrcweir BLENDFUNCTION aFunc = { 603cdf0e10cSrcweir AC_SRC_OVER, 604cdf0e10cSrcweir 0, 605cdf0e10cSrcweir 255 - 255L*nTransparency/100, 606cdf0e10cSrcweir 0 607cdf0e10cSrcweir }; 608cdf0e10cSrcweir 609cdf0e10cSrcweir // hMemDC contains a 1x1 bitmap of the right color - stretch-blit 610cdf0e10cSrcweir // that to dest hdc 611cdf0e10cSrcweir bool bRet = AlphaBlend( mhDC, nX, nY, nWidth, nHeight, 612cdf0e10cSrcweir hMemDC, 0,0,1,1, 613cdf0e10cSrcweir aFunc ) == TRUE; 614cdf0e10cSrcweir 615cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 616cdf0e10cSrcweir 617cdf0e10cSrcweir return bRet; 618cdf0e10cSrcweir } 619cdf0e10cSrcweir 620cdf0e10cSrcweir // ----------------------------------------------------------------------- 621cdf0e10cSrcweir 622cdf0e10cSrcweir void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, 623cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 624cdf0e10cSrcweir SalColor nMaskColor ) 625cdf0e10cSrcweir { 626cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 627cdf0e10cSrcweir 628cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 629cdf0e10cSrcweir 630cdf0e10cSrcweir SalTwoRect aPosAry = *pPosAry; 631cdf0e10cSrcweir const BYTE cRed = SALCOLOR_RED( nMaskColor ); 632cdf0e10cSrcweir const BYTE cGreen = SALCOLOR_GREEN( nMaskColor ); 633cdf0e10cSrcweir const BYTE cBlue = SALCOLOR_BLUE( nMaskColor ); 634cdf0e10cSrcweir HDC hDC = mhDC; 635cdf0e10cSrcweir HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) ); 636cdf0e10cSrcweir HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush ); 637cdf0e10cSrcweir 638cdf0e10cSrcweir // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem, 639cdf0e10cSrcweir // die Farben der Maske richtig auf die Palette abzubilden, 640cdf0e10cSrcweir // wenn wir die DIB direkt ausgeben => DDB-Ausgabe 641cdf0e10cSrcweir if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 ) 642cdf0e10cSrcweir { 643cdf0e10cSrcweir WinSalBitmap aTmp; 644cdf0e10cSrcweir 645cdf0e10cSrcweir if( aTmp.Create( rSalBitmap, this ) ) 646cdf0e10cSrcweir ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL ); 647cdf0e10cSrcweir } 648cdf0e10cSrcweir else 649cdf0e10cSrcweir ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); 650cdf0e10cSrcweir 651cdf0e10cSrcweir SelectBrush( hDC, hOldBrush ); 652cdf0e10cSrcweir DeleteBrush( hMaskBrush ); 653cdf0e10cSrcweir } 654cdf0e10cSrcweir 655cdf0e10cSrcweir // ----------------------------------------------------------------------- 656cdf0e10cSrcweir 657cdf0e10cSrcweir SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) 658cdf0e10cSrcweir { 659cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No ::GetBitmap() from printer possible!" ); 660cdf0e10cSrcweir 661cdf0e10cSrcweir WinSalBitmap* pSalBitmap = NULL; 662cdf0e10cSrcweir 663cdf0e10cSrcweir nDX = labs( nDX ); 664cdf0e10cSrcweir nDY = labs( nDY ); 665cdf0e10cSrcweir 666cdf0e10cSrcweir HDC hDC = mhDC; 667cdf0e10cSrcweir HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); 668cdf0e10cSrcweir HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); 669cdf0e10cSrcweir sal_Bool bRet; 670cdf0e10cSrcweir DWORD err = 0; 671cdf0e10cSrcweir 672cdf0e10cSrcweir bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE; 673cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 674cdf0e10cSrcweir 675cdf0e10cSrcweir if( bRet ) 676cdf0e10cSrcweir { 677cdf0e10cSrcweir pSalBitmap = new WinSalBitmap; 678cdf0e10cSrcweir 679cdf0e10cSrcweir if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) ) 680cdf0e10cSrcweir { 681cdf0e10cSrcweir delete pSalBitmap; 682cdf0e10cSrcweir pSalBitmap = NULL; 683cdf0e10cSrcweir } 684cdf0e10cSrcweir } 685cdf0e10cSrcweir else 686cdf0e10cSrcweir { 687cdf0e10cSrcweir err = GetLastError(); 688cdf0e10cSrcweir // #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers) 689cdf0e10cSrcweir DeleteBitmap( hBmpBitmap ); 690cdf0e10cSrcweir } 691cdf0e10cSrcweir 692cdf0e10cSrcweir return pSalBitmap; 693cdf0e10cSrcweir } 694cdf0e10cSrcweir 695cdf0e10cSrcweir // ----------------------------------------------------------------------- 696cdf0e10cSrcweir 697cdf0e10cSrcweir SalColor WinSalGraphics::getPixel( long nX, long nY ) 698cdf0e10cSrcweir { 699cdf0e10cSrcweir COLORREF aWinCol = ::GetPixel( mhDC, (int) nX, (int) nY ); 700cdf0e10cSrcweir 701cdf0e10cSrcweir if ( CLR_INVALID == aWinCol ) 702cdf0e10cSrcweir return MAKE_SALCOLOR( 0, 0, 0 ); 703cdf0e10cSrcweir else 704cdf0e10cSrcweir return MAKE_SALCOLOR( GetRValue( aWinCol ), 705cdf0e10cSrcweir GetGValue( aWinCol ), 706cdf0e10cSrcweir GetBValue( aWinCol ) ); 707cdf0e10cSrcweir } 708cdf0e10cSrcweir 709cdf0e10cSrcweir // ----------------------------------------------------------------------- 710cdf0e10cSrcweir 711cdf0e10cSrcweir void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) 712cdf0e10cSrcweir { 713cdf0e10cSrcweir if ( nFlags & SAL_INVERT_TRACKFRAME ) 714cdf0e10cSrcweir { 715cdf0e10cSrcweir HPEN hDotPen = CreatePen( PS_DOT, 0, 0 ); 716cdf0e10cSrcweir HPEN hOldPen = SelectPen( mhDC, hDotPen ); 717cdf0e10cSrcweir HBRUSH hOldBrush = SelectBrush( mhDC, GetStockBrush( NULL_BRUSH ) ); 718cdf0e10cSrcweir int nOldROP = SetROP2( mhDC, R2_NOT ); 719cdf0e10cSrcweir 720cdf0e10cSrcweir WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); 721cdf0e10cSrcweir 722cdf0e10cSrcweir SetROP2( mhDC, nOldROP ); 723cdf0e10cSrcweir SelectPen( mhDC, hOldPen ); 724cdf0e10cSrcweir SelectBrush( mhDC, hOldBrush ); 725cdf0e10cSrcweir DeletePen( hDotPen ); 726cdf0e10cSrcweir } 727cdf0e10cSrcweir else if ( nFlags & SAL_INVERT_50 ) 728cdf0e10cSrcweir { 729cdf0e10cSrcweir SalData* pSalData = GetSalData(); 730cdf0e10cSrcweir if ( !pSalData->mh50Brush ) 731cdf0e10cSrcweir { 732cdf0e10cSrcweir if ( !pSalData->mh50Bmp ) 733cdf0e10cSrcweir pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); 734cdf0e10cSrcweir pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); 735cdf0e10cSrcweir } 736cdf0e10cSrcweir 737cdf0e10cSrcweir COLORREF nOldTextColor = ::SetTextColor( mhDC, 0 ); 738cdf0e10cSrcweir HBRUSH hOldBrush = SelectBrush( mhDC, pSalData->mh50Brush ); 739cdf0e10cSrcweir PatBlt( mhDC, nX, nY, nWidth, nHeight, PATINVERT ); 740cdf0e10cSrcweir ::SetTextColor( mhDC, nOldTextColor ); 741cdf0e10cSrcweir SelectBrush( mhDC, hOldBrush ); 742cdf0e10cSrcweir } 743cdf0e10cSrcweir else 744cdf0e10cSrcweir { 745cdf0e10cSrcweir RECT aRect; 746cdf0e10cSrcweir aRect.left = (int)nX; 747cdf0e10cSrcweir aRect.top = (int)nY; 748cdf0e10cSrcweir aRect.right = (int)nX+nWidth; 749cdf0e10cSrcweir aRect.bottom = (int)nY+nHeight; 750cdf0e10cSrcweir ::InvertRect( mhDC, &aRect ); 751cdf0e10cSrcweir } 752cdf0e10cSrcweir } 753cdf0e10cSrcweir 754cdf0e10cSrcweir // ----------------------------------------------------------------------- 755cdf0e10cSrcweir 756cdf0e10cSrcweir void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nSalFlags ) 757cdf0e10cSrcweir { 758cdf0e10cSrcweir HPEN hPen; 759cdf0e10cSrcweir HPEN hOldPen; 760cdf0e10cSrcweir HBRUSH hBrush; 761cdf0e10cSrcweir HBRUSH hOldBrush = 0; 762cdf0e10cSrcweir COLORREF nOldTextColor RGB(0,0,0); 763cdf0e10cSrcweir int nOldROP = SetROP2( mhDC, R2_NOT ); 764cdf0e10cSrcweir 765cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 766cdf0e10cSrcweir hPen = CreatePen( PS_DOT, 0, 0 ); 767cdf0e10cSrcweir else 768cdf0e10cSrcweir { 769cdf0e10cSrcweir 770cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_50 ) 771cdf0e10cSrcweir { 772cdf0e10cSrcweir SalData* pSalData = GetSalData(); 773cdf0e10cSrcweir if ( !pSalData->mh50Brush ) 774cdf0e10cSrcweir { 775cdf0e10cSrcweir if ( !pSalData->mh50Bmp ) 776cdf0e10cSrcweir pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); 777cdf0e10cSrcweir pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); 778cdf0e10cSrcweir } 779cdf0e10cSrcweir 780cdf0e10cSrcweir hBrush = pSalData->mh50Brush; 781cdf0e10cSrcweir } 782cdf0e10cSrcweir else 783cdf0e10cSrcweir hBrush = GetStockBrush( BLACK_BRUSH ); 784cdf0e10cSrcweir 785cdf0e10cSrcweir hPen = GetStockPen( NULL_PEN ); 786cdf0e10cSrcweir nOldTextColor = ::SetTextColor( mhDC, 0 ); 787cdf0e10cSrcweir hOldBrush = SelectBrush( mhDC, hBrush ); 788cdf0e10cSrcweir } 789cdf0e10cSrcweir hOldPen = SelectPen( mhDC, hPen ); 790cdf0e10cSrcweir 791cdf0e10cSrcweir POINT* pWinPtAry; 792cdf0e10cSrcweir // Unter NT koennen wir das Array direkt weiterreichen 793cdf0e10cSrcweir DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ), 794cdf0e10cSrcweir "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" ); 795cdf0e10cSrcweir 796cdf0e10cSrcweir pWinPtAry = (POINT*)pPtAry; 797cdf0e10cSrcweir // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl 798cdf0e10cSrcweir // von Punkten 799cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) 802cdf0e10cSrcweir Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS ); 803cdf0e10cSrcweir } 804cdf0e10cSrcweir else 805cdf0e10cSrcweir { 806cdf0e10cSrcweir if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) 807cdf0e10cSrcweir WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS ); 808cdf0e10cSrcweir } 809cdf0e10cSrcweir 810cdf0e10cSrcweir SetROP2( mhDC, nOldROP ); 811cdf0e10cSrcweir SelectPen( mhDC, hOldPen ); 812cdf0e10cSrcweir 813cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 814cdf0e10cSrcweir DeletePen( hPen ); 815cdf0e10cSrcweir else 816cdf0e10cSrcweir { 817cdf0e10cSrcweir ::SetTextColor( mhDC, nOldTextColor ); 818cdf0e10cSrcweir SelectBrush( mhDC, hOldBrush ); 819cdf0e10cSrcweir } 820cdf0e10cSrcweir } 821