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