19f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 59f62ea84SAndrew Rist * distributed with this work for additional information 69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 149f62ea84SAndrew Rist * software distributed under the License is distributed on an 159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 179f62ea84SAndrew Rist * specific language governing permissions and limitations 189f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 209f62ea84SAndrew Rist *************************************************************/ 219f62ea84SAndrew Rist 229f62ea84SAndrew 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 62*5f27b83cSArmin Le Grand void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir HDC hSrcDC; 65cdf0e10cSrcweir DWORD nRop; 66cdf0e10cSrcweir 67cdf0e10cSrcweir if ( pSrcGraphics ) 68*5f27b83cSArmin Le Grand hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC(); 69cdf0e10cSrcweir else 70*5f27b83cSArmin Le Grand hSrcDC = getHDC(); 71cdf0e10cSrcweir 72cdf0e10cSrcweir if ( mbXORMode ) 73cdf0e10cSrcweir nRop = SRCINVERT; 74cdf0e10cSrcweir else 75cdf0e10cSrcweir nRop = SRCCOPY; 76cdf0e10cSrcweir 77*5f27b83cSArmin Le Grand if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && 78*5f27b83cSArmin Le Grand (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) 79cdf0e10cSrcweir { 80*5f27b83cSArmin Le Grand BitBlt( getHDC(), 81*5f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, 82*5f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, 83cdf0e10cSrcweir hSrcDC, 84*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, 85cdf0e10cSrcweir nRop ); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir else 88cdf0e10cSrcweir { 89*5f27b83cSArmin Le Grand int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS ); 90*5f27b83cSArmin Le Grand StretchBlt( getHDC(), 91*5f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, 92*5f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, 93cdf0e10cSrcweir hSrcDC, 94*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, 95*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, 96cdf0e10cSrcweir nRop ); 97*5f27b83cSArmin Le Grand SetStretchBltMode( getHDC(), 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 ); 288*5f27b83cSArmin Le Grand nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn ); 289cdf0e10cSrcweir 290cdf0e10cSrcweir bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate 291*5f27b83cSArmin Le Grand ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF ); 292cdf0e10cSrcweir } 293cdf0e10cSrcweir } 294cdf0e10cSrcweir } 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297*5f27b83cSArmin Le Grand BitBlt( getHDC(), 298cdf0e10cSrcweir (int)nDestX, (int)nDestY, 299cdf0e10cSrcweir (int)nSrcWidth, (int)nSrcHeight, 300*5f27b83cSArmin Le Grand getHDC(), 301cdf0e10cSrcweir (int)nSrcX, (int)nSrcY, 302cdf0e10cSrcweir SRCCOPY ); 303cdf0e10cSrcweir 304cdf0e10cSrcweir if( bRestoreClipRgn ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir // restore old clip region 307cdf0e10cSrcweir if( nOldClipRgnType != ERROR ) 308*5f27b83cSArmin Le Grand SelectClipRgn( getHDC(), 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 ); 316*5f27b83cSArmin Le Grand if ( GetClipRgn( getHDC(), 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, 345*5f27b83cSArmin Le Grand const SalTwoRect& rPosAry, 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, 373*5f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, 374*5f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, 375*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY), 376*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcWidth, (int)rPosAry.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 395*5f27b83cSArmin Le Grand if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && 396*5f27b83cSArmin Le Grand (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) 397cdf0e10cSrcweir { 398cdf0e10cSrcweir BitBlt( hDC, 399*5f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, 400*5f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, 401cdf0e10cSrcweir hBmpDC, 402*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, 403cdf0e10cSrcweir nDrawMode ); 404cdf0e10cSrcweir } 405cdf0e10cSrcweir else 406cdf0e10cSrcweir { 407cdf0e10cSrcweir const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); 408cdf0e10cSrcweir 409cdf0e10cSrcweir StretchBlt( hDC, 410*5f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, 411*5f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, 412cdf0e10cSrcweir hBmpDC, 413*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, 414*5f27b83cSArmin Le Grand (int)rPosAry.mnSrcWidth, (int)rPosAry.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 436*5f27b83cSArmin Le Grand void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) 437cdf0e10cSrcweir { 438*5f27b83cSArmin Le Grand bool bTryDirectPaint(!mbPrinter && !mbXORMode); 439*5f27b83cSArmin Le Grand 440*5f27b83cSArmin Le Grand if(bTryDirectPaint) 441*5f27b83cSArmin Le Grand { 442*5f27b83cSArmin Le Grand // only paint direct when no scaling and no MapMode, else the 443*5f27b83cSArmin Le Grand // more expensive conversions may be done for short-time Bitmap/BitmapEx 444*5f27b83cSArmin Le Grand // used for buffering only 445*5f27b83cSArmin Le Grand if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) 446*5f27b83cSArmin Le Grand { 447*5f27b83cSArmin Le Grand bTryDirectPaint = false; 448*5f27b83cSArmin Le Grand } 449*5f27b83cSArmin Le Grand } 450*5f27b83cSArmin Le Grand 451*5f27b83cSArmin Le Grand // try to draw using GdiPlus directly 452*5f27b83cSArmin Le Grand if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap)) 453*5f27b83cSArmin Le Grand { 454*5f27b83cSArmin Le Grand return; 455*5f27b83cSArmin Le Grand } 456*5f27b83cSArmin Le Grand 457*5f27b83cSArmin Le Grand // fall back old stuff 458*5f27b83cSArmin Le Grand ImplDrawBitmap(getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), 459cdf0e10cSrcweir mbPrinter, 460cdf0e10cSrcweir mbXORMode ? SRCINVERT : SRCCOPY ); 461cdf0e10cSrcweir } 462cdf0e10cSrcweir 463cdf0e10cSrcweir // ----------------------------------------------------------------------- 464cdf0e10cSrcweir 465*5f27b83cSArmin Le Grand void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, 466cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 467cdf0e10cSrcweir SalColor nTransparentColor ) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 470cdf0e10cSrcweir 471cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 472cdf0e10cSrcweir 473cdf0e10cSrcweir WinSalBitmap* pMask = new WinSalBitmap; 474cdf0e10cSrcweir const Point aPoint; 475cdf0e10cSrcweir const Size aSize( rSalBitmap.GetSize() ); 476cdf0e10cSrcweir HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL ); 477cdf0e10cSrcweir HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap ); 478cdf0e10cSrcweir const BYTE cRed = SALCOLOR_RED( nTransparentColor ); 479cdf0e10cSrcweir const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor ); 480cdf0e10cSrcweir const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor ); 481cdf0e10cSrcweir 482cdf0e10cSrcweir if( rSalBitmap.ImplGethDDB() ) 483cdf0e10cSrcweir { 484cdf0e10cSrcweir HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() ); 485cdf0e10cSrcweir COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); 486cdf0e10cSrcweir 487cdf0e10cSrcweir BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); 488cdf0e10cSrcweir 489cdf0e10cSrcweir SetBkColor( hSrcDC, aOldCol ); 490cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 491cdf0e10cSrcweir } 492cdf0e10cSrcweir else 493cdf0e10cSrcweir { 494cdf0e10cSrcweir WinSalBitmap* pTmpSalBmp = new WinSalBitmap; 495cdf0e10cSrcweir 496cdf0e10cSrcweir if( pTmpSalBmp->Create( rSalBitmap, this ) ) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() ); 499cdf0e10cSrcweir COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); 500cdf0e10cSrcweir 501cdf0e10cSrcweir BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); 502cdf0e10cSrcweir 503cdf0e10cSrcweir SetBkColor( hSrcDC, aOldCol ); 504cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 505cdf0e10cSrcweir } 506cdf0e10cSrcweir 507cdf0e10cSrcweir delete pTmpSalBmp; 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 511cdf0e10cSrcweir 512cdf0e10cSrcweir // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE ) 513cdf0e10cSrcweir if( pMask->Create( hMaskBitmap, FALSE, FALSE ) ) 514*5f27b83cSArmin Le Grand drawBitmap( rPosAry, rSalBitmap, *pMask ); 515cdf0e10cSrcweir 516cdf0e10cSrcweir delete pMask; 517cdf0e10cSrcweir } 518cdf0e10cSrcweir 519cdf0e10cSrcweir // ----------------------------------------------------------------------- 520cdf0e10cSrcweir 521*5f27b83cSArmin Le Grand void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, 522cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 523cdf0e10cSrcweir const SalBitmap& rSTransparentBitmap ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 526*5f27b83cSArmin Le Grand bool bTryDirectPaint(!mbPrinter && !mbXORMode); 527*5f27b83cSArmin Le Grand 528*5f27b83cSArmin Le Grand if(bTryDirectPaint) 529*5f27b83cSArmin Le Grand { 530*5f27b83cSArmin Le Grand // only paint direct when no scaling and no MapMode, else the 531*5f27b83cSArmin Le Grand // more expensive conversions may be done for short-time Bitmap/BitmapEx 532*5f27b83cSArmin Le Grand // used for buffering only 533*5f27b83cSArmin Le Grand if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) 534*5f27b83cSArmin Le Grand { 535*5f27b83cSArmin Le Grand bTryDirectPaint = false; 536*5f27b83cSArmin Le Grand } 537*5f27b83cSArmin Le Grand } 538*5f27b83cSArmin Le Grand 539*5f27b83cSArmin Le Grand // try to draw using GdiPlus directly 540*5f27b83cSArmin Le Grand if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap)) 541*5f27b83cSArmin Le Grand { 542*5f27b83cSArmin Le Grand return; 543*5f27b83cSArmin Le Grand } 544cdf0e10cSrcweir 545cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 546cdf0e10cSrcweir const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap); 547cdf0e10cSrcweir 548*5f27b83cSArmin Le Grand SalTwoRect aPosAry = rPosAry; 549cdf0e10cSrcweir int nDstX = (int)aPosAry.mnDestX; 550cdf0e10cSrcweir int nDstY = (int)aPosAry.mnDestY; 551cdf0e10cSrcweir int nDstWidth = (int)aPosAry.mnDestWidth; 552cdf0e10cSrcweir int nDstHeight = (int)aPosAry.mnDestHeight; 553*5f27b83cSArmin Le Grand HDC hDC = getHDC(); 554cdf0e10cSrcweir HBITMAP hMemBitmap = 0; 555cdf0e10cSrcweir HBITMAP hMaskBitmap = 0; 556cdf0e10cSrcweir 557cdf0e10cSrcweir if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) ) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); 560cdf0e10cSrcweir hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); 561cdf0e10cSrcweir } 562cdf0e10cSrcweir 563cdf0e10cSrcweir HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap ); 564cdf0e10cSrcweir HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap ); 565cdf0e10cSrcweir 566cdf0e10cSrcweir aPosAry.mnDestX = aPosAry.mnDestY = 0; 567cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY ); 568cdf0e10cSrcweir 569cdf0e10cSrcweir // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem, 570cdf0e10cSrcweir // die Farben der Maske richtig auf die Palette abzubilden, 571cdf0e10cSrcweir // wenn wir die DIB direkt ausgeben => DDB-Ausgabe 572cdf0e10cSrcweir if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 ) 573cdf0e10cSrcweir { 574cdf0e10cSrcweir WinSalBitmap aTmp; 575cdf0e10cSrcweir 576cdf0e10cSrcweir if( aTmp.Create( rTransparentBitmap, this ) ) 577*5f27b83cSArmin Le Grand ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY ); 578cdf0e10cSrcweir } 579cdf0e10cSrcweir else 580*5f27b83cSArmin Le Grand ImplDrawBitmap( hMaskDC, aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); 581cdf0e10cSrcweir 582cdf0e10cSrcweir // now MemDC contains background, MaskDC the transparency mask 583cdf0e10cSrcweir 584cdf0e10cSrcweir // #105055# Respect XOR mode 585cdf0e10cSrcweir if( mbXORMode ) 586cdf0e10cSrcweir { 587*5f27b83cSArmin Le Grand ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); 588cdf0e10cSrcweir // now MaskDC contains the bitmap area with black background 589cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT ); 590cdf0e10cSrcweir // now MemDC contains background XORed bitmap area ontop 591cdf0e10cSrcweir } 592cdf0e10cSrcweir else 593cdf0e10cSrcweir { 594cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND ); 595cdf0e10cSrcweir // now MemDC contains background with masked-out bitmap area 596*5f27b83cSArmin Le Grand ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); 597cdf0e10cSrcweir // now MaskDC contains the bitmap area with black background 598cdf0e10cSrcweir BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT ); 599cdf0e10cSrcweir // now MemDC contains background and bitmap merged together 600cdf0e10cSrcweir } 601cdf0e10cSrcweir // copy to output DC 602cdf0e10cSrcweir BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY ); 603cdf0e10cSrcweir 604cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 605cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_2 ); 606cdf0e10cSrcweir 607cdf0e10cSrcweir // hMemBitmap != 0 ==> hMaskBitmap != 0 608cdf0e10cSrcweir if( hMemBitmap ) 609cdf0e10cSrcweir { 610cdf0e10cSrcweir DeleteObject( hMemBitmap ); 611cdf0e10cSrcweir DeleteObject( hMaskBitmap ); 612cdf0e10cSrcweir } 613cdf0e10cSrcweir } 614cdf0e10cSrcweir 615cdf0e10cSrcweir // ----------------------------------------------------------------------- 616cdf0e10cSrcweir 617cdf0e10cSrcweir bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, 618cdf0e10cSrcweir long nHeight, sal_uInt8 nTransparency ) 619cdf0e10cSrcweir { 620cdf0e10cSrcweir if( mbPen || !mbBrush || mbXORMode ) 621cdf0e10cSrcweir return false; // can only perform solid fills without XOR. 622cdf0e10cSrcweir 623cdf0e10cSrcweir HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 ); 624cdf0e10cSrcweir SetPixel( hMemDC, (int)0, (int)0, mnBrushColor ); 625cdf0e10cSrcweir 626cdf0e10cSrcweir BLENDFUNCTION aFunc = { 627cdf0e10cSrcweir AC_SRC_OVER, 628cdf0e10cSrcweir 0, 629cdf0e10cSrcweir 255 - 255L*nTransparency/100, 630cdf0e10cSrcweir 0 631cdf0e10cSrcweir }; 632cdf0e10cSrcweir 633cdf0e10cSrcweir // hMemDC contains a 1x1 bitmap of the right color - stretch-blit 634cdf0e10cSrcweir // that to dest hdc 635*5f27b83cSArmin Le Grand bool bRet = AlphaBlend( getHDC(), nX, nY, nWidth, nHeight, 636cdf0e10cSrcweir hMemDC, 0,0,1,1, 637cdf0e10cSrcweir aFunc ) == TRUE; 638cdf0e10cSrcweir 639cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 640cdf0e10cSrcweir 641cdf0e10cSrcweir return bRet; 642cdf0e10cSrcweir } 643cdf0e10cSrcweir 644cdf0e10cSrcweir // ----------------------------------------------------------------------- 645cdf0e10cSrcweir 646*5f27b83cSArmin Le Grand void WinSalGraphics::drawMask( const SalTwoRect& rPosAry, 647cdf0e10cSrcweir const SalBitmap& rSSalBitmap, 648cdf0e10cSrcweir SalColor nMaskColor ) 649cdf0e10cSrcweir { 650cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); 651cdf0e10cSrcweir 652cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); 653cdf0e10cSrcweir 654*5f27b83cSArmin Le Grand SalTwoRect aPosAry = rPosAry; 655cdf0e10cSrcweir const BYTE cRed = SALCOLOR_RED( nMaskColor ); 656cdf0e10cSrcweir const BYTE cGreen = SALCOLOR_GREEN( nMaskColor ); 657cdf0e10cSrcweir const BYTE cBlue = SALCOLOR_BLUE( nMaskColor ); 658*5f27b83cSArmin Le Grand HDC hDC = getHDC(); 659cdf0e10cSrcweir HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) ); 660cdf0e10cSrcweir HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush ); 661cdf0e10cSrcweir 662cdf0e10cSrcweir // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem, 663cdf0e10cSrcweir // die Farben der Maske richtig auf die Palette abzubilden, 664cdf0e10cSrcweir // wenn wir die DIB direkt ausgeben => DDB-Ausgabe 665cdf0e10cSrcweir if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 ) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir WinSalBitmap aTmp; 668cdf0e10cSrcweir 669cdf0e10cSrcweir if( aTmp.Create( rSalBitmap, this ) ) 670*5f27b83cSArmin Le Grand ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL ); 671cdf0e10cSrcweir } 672cdf0e10cSrcweir else 673*5f27b83cSArmin Le Grand ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); 674cdf0e10cSrcweir 675cdf0e10cSrcweir SelectBrush( hDC, hOldBrush ); 676cdf0e10cSrcweir DeleteBrush( hMaskBrush ); 677cdf0e10cSrcweir } 678cdf0e10cSrcweir 679cdf0e10cSrcweir // ----------------------------------------------------------------------- 680cdf0e10cSrcweir 681cdf0e10cSrcweir SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) 682cdf0e10cSrcweir { 683cdf0e10cSrcweir DBG_ASSERT( !mbPrinter, "No ::GetBitmap() from printer possible!" ); 684cdf0e10cSrcweir 685cdf0e10cSrcweir WinSalBitmap* pSalBitmap = NULL; 686cdf0e10cSrcweir 687cdf0e10cSrcweir nDX = labs( nDX ); 688cdf0e10cSrcweir nDY = labs( nDY ); 689cdf0e10cSrcweir 690*5f27b83cSArmin Le Grand HDC hDC = getHDC(); 691cdf0e10cSrcweir HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); 692cdf0e10cSrcweir HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); 693cdf0e10cSrcweir sal_Bool bRet; 694cdf0e10cSrcweir DWORD err = 0; 695cdf0e10cSrcweir 696cdf0e10cSrcweir bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE; 697cdf0e10cSrcweir ImplReleaseCachedDC( CACHED_HDC_1 ); 698cdf0e10cSrcweir 699cdf0e10cSrcweir if( bRet ) 700cdf0e10cSrcweir { 701cdf0e10cSrcweir pSalBitmap = new WinSalBitmap; 702cdf0e10cSrcweir 703cdf0e10cSrcweir if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) ) 704cdf0e10cSrcweir { 705cdf0e10cSrcweir delete pSalBitmap; 706cdf0e10cSrcweir pSalBitmap = NULL; 707cdf0e10cSrcweir } 708cdf0e10cSrcweir } 709cdf0e10cSrcweir else 710cdf0e10cSrcweir { 711cdf0e10cSrcweir err = GetLastError(); 712cdf0e10cSrcweir // #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers) 713cdf0e10cSrcweir DeleteBitmap( hBmpBitmap ); 714cdf0e10cSrcweir } 715cdf0e10cSrcweir 716cdf0e10cSrcweir return pSalBitmap; 717cdf0e10cSrcweir } 718cdf0e10cSrcweir 719cdf0e10cSrcweir // ----------------------------------------------------------------------- 720cdf0e10cSrcweir 721cdf0e10cSrcweir SalColor WinSalGraphics::getPixel( long nX, long nY ) 722cdf0e10cSrcweir { 723*5f27b83cSArmin Le Grand COLORREF aWinCol = ::GetPixel( getHDC(), (int) nX, (int) nY ); 724cdf0e10cSrcweir 725cdf0e10cSrcweir if ( CLR_INVALID == aWinCol ) 726cdf0e10cSrcweir return MAKE_SALCOLOR( 0, 0, 0 ); 727cdf0e10cSrcweir else 728cdf0e10cSrcweir return MAKE_SALCOLOR( GetRValue( aWinCol ), 729cdf0e10cSrcweir GetGValue( aWinCol ), 730cdf0e10cSrcweir GetBValue( aWinCol ) ); 731cdf0e10cSrcweir } 732cdf0e10cSrcweir 733cdf0e10cSrcweir // ----------------------------------------------------------------------- 734cdf0e10cSrcweir 735cdf0e10cSrcweir void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) 736cdf0e10cSrcweir { 737cdf0e10cSrcweir if ( nFlags & SAL_INVERT_TRACKFRAME ) 738cdf0e10cSrcweir { 739cdf0e10cSrcweir HPEN hDotPen = CreatePen( PS_DOT, 0, 0 ); 740*5f27b83cSArmin Le Grand HPEN hOldPen = SelectPen( getHDC(), hDotPen ); 741*5f27b83cSArmin Le Grand HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) ); 742*5f27b83cSArmin Le Grand int nOldROP = SetROP2( getHDC(), R2_NOT ); 743cdf0e10cSrcweir 744*5f27b83cSArmin Le Grand WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); 745cdf0e10cSrcweir 746*5f27b83cSArmin Le Grand SetROP2( getHDC(), nOldROP ); 747*5f27b83cSArmin Le Grand SelectPen( getHDC(), hOldPen ); 748*5f27b83cSArmin Le Grand SelectBrush( getHDC(), hOldBrush ); 749cdf0e10cSrcweir DeletePen( hDotPen ); 750cdf0e10cSrcweir } 751cdf0e10cSrcweir else if ( nFlags & SAL_INVERT_50 ) 752cdf0e10cSrcweir { 753cdf0e10cSrcweir SalData* pSalData = GetSalData(); 754cdf0e10cSrcweir if ( !pSalData->mh50Brush ) 755cdf0e10cSrcweir { 756cdf0e10cSrcweir if ( !pSalData->mh50Bmp ) 757cdf0e10cSrcweir pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); 758cdf0e10cSrcweir pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); 759cdf0e10cSrcweir } 760cdf0e10cSrcweir 761*5f27b83cSArmin Le Grand COLORREF nOldTextColor = ::SetTextColor( getHDC(), 0 ); 762*5f27b83cSArmin Le Grand HBRUSH hOldBrush = SelectBrush( getHDC(), pSalData->mh50Brush ); 763*5f27b83cSArmin Le Grand PatBlt( getHDC(), nX, nY, nWidth, nHeight, PATINVERT ); 764*5f27b83cSArmin Le Grand ::SetTextColor( getHDC(), nOldTextColor ); 765*5f27b83cSArmin Le Grand SelectBrush( getHDC(), hOldBrush ); 766cdf0e10cSrcweir } 767cdf0e10cSrcweir else 768cdf0e10cSrcweir { 769cdf0e10cSrcweir RECT aRect; 770cdf0e10cSrcweir aRect.left = (int)nX; 771cdf0e10cSrcweir aRect.top = (int)nY; 772cdf0e10cSrcweir aRect.right = (int)nX+nWidth; 773cdf0e10cSrcweir aRect.bottom = (int)nY+nHeight; 774*5f27b83cSArmin Le Grand ::InvertRect( getHDC(), &aRect ); 775cdf0e10cSrcweir } 776cdf0e10cSrcweir } 777cdf0e10cSrcweir 778cdf0e10cSrcweir // ----------------------------------------------------------------------- 779cdf0e10cSrcweir 780cdf0e10cSrcweir void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nSalFlags ) 781cdf0e10cSrcweir { 782cdf0e10cSrcweir HPEN hPen; 783cdf0e10cSrcweir HPEN hOldPen; 784cdf0e10cSrcweir HBRUSH hBrush; 785cdf0e10cSrcweir HBRUSH hOldBrush = 0; 786cdf0e10cSrcweir COLORREF nOldTextColor RGB(0,0,0); 787*5f27b83cSArmin Le Grand int nOldROP = SetROP2( getHDC(), R2_NOT ); 788cdf0e10cSrcweir 789cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 790cdf0e10cSrcweir hPen = CreatePen( PS_DOT, 0, 0 ); 791cdf0e10cSrcweir else 792cdf0e10cSrcweir { 793cdf0e10cSrcweir 794cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_50 ) 795cdf0e10cSrcweir { 796cdf0e10cSrcweir SalData* pSalData = GetSalData(); 797cdf0e10cSrcweir if ( !pSalData->mh50Brush ) 798cdf0e10cSrcweir { 799cdf0e10cSrcweir if ( !pSalData->mh50Bmp ) 800cdf0e10cSrcweir pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); 801cdf0e10cSrcweir pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); 802cdf0e10cSrcweir } 803cdf0e10cSrcweir 804cdf0e10cSrcweir hBrush = pSalData->mh50Brush; 805cdf0e10cSrcweir } 806cdf0e10cSrcweir else 807cdf0e10cSrcweir hBrush = GetStockBrush( BLACK_BRUSH ); 808cdf0e10cSrcweir 809cdf0e10cSrcweir hPen = GetStockPen( NULL_PEN ); 810*5f27b83cSArmin Le Grand nOldTextColor = ::SetTextColor( getHDC(), 0 ); 811*5f27b83cSArmin Le Grand hOldBrush = SelectBrush( getHDC(), hBrush ); 812cdf0e10cSrcweir } 813*5f27b83cSArmin Le Grand hOldPen = SelectPen( getHDC(), hPen ); 814cdf0e10cSrcweir 815cdf0e10cSrcweir POINT* pWinPtAry; 816cdf0e10cSrcweir // Unter NT koennen wir das Array direkt weiterreichen 817cdf0e10cSrcweir DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ), 818cdf0e10cSrcweir "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" ); 819cdf0e10cSrcweir 820cdf0e10cSrcweir pWinPtAry = (POINT*)pPtAry; 821cdf0e10cSrcweir // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl 822cdf0e10cSrcweir // von Punkten 823cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 824cdf0e10cSrcweir { 825*5f27b83cSArmin Le Grand if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) 826*5f27b83cSArmin Le Grand Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); 827cdf0e10cSrcweir } 828cdf0e10cSrcweir else 829cdf0e10cSrcweir { 830*5f27b83cSArmin Le Grand if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) 831*5f27b83cSArmin Le Grand WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); 832cdf0e10cSrcweir } 833cdf0e10cSrcweir 834*5f27b83cSArmin Le Grand SetROP2( getHDC(), nOldROP ); 835*5f27b83cSArmin Le Grand SelectPen( getHDC(), hOldPen ); 836cdf0e10cSrcweir 837cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME ) 838cdf0e10cSrcweir DeletePen( hPen ); 839cdf0e10cSrcweir else 840cdf0e10cSrcweir { 841*5f27b83cSArmin Le Grand ::SetTextColor( getHDC(), nOldTextColor ); 842*5f27b83cSArmin Le Grand SelectBrush( getHDC(), hOldBrush ); 843cdf0e10cSrcweir } 844cdf0e10cSrcweir } 845