xref: /AOO41X/main/vcl/win/source/gdi/salgdi2.cxx (revision 9f62ea84a806e17e6f2bbff75724a7257a0eb5d9)
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