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
109f62ea84SAndrew Rist *
119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist *
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.
199f62ea84SAndrew Rist *
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
supportsOperation(OutDevSupportType eType) const40cdf0e10cSrcweir 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
copyBits(const SalTwoRect & rPosAry,SalGraphics * pSrcGraphics)625f27b83cSArmin Le Grand void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir HDC hSrcDC;
65cdf0e10cSrcweir DWORD nRop;
66cdf0e10cSrcweir
67cdf0e10cSrcweir if ( pSrcGraphics )
685f27b83cSArmin Le Grand hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC();
69cdf0e10cSrcweir else
705f27b83cSArmin Le Grand hSrcDC = getHDC();
71cdf0e10cSrcweir
72cdf0e10cSrcweir if ( mbXORMode )
73cdf0e10cSrcweir nRop = SRCINVERT;
74cdf0e10cSrcweir else
75cdf0e10cSrcweir nRop = SRCCOPY;
76cdf0e10cSrcweir
775f27b83cSArmin Le Grand if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
785f27b83cSArmin Le Grand (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
79cdf0e10cSrcweir {
805f27b83cSArmin Le Grand BitBlt( getHDC(),
815f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
825f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
83cdf0e10cSrcweir hSrcDC,
845f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
85cdf0e10cSrcweir nRop );
86cdf0e10cSrcweir }
87cdf0e10cSrcweir else
88cdf0e10cSrcweir {
895f27b83cSArmin Le Grand int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS );
905f27b83cSArmin Le Grand StretchBlt( getHDC(),
915f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
925f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
93cdf0e10cSrcweir hSrcDC,
945f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
955f27b83cSArmin Le Grand (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
96cdf0e10cSrcweir nRop );
975f27b83cSArmin Le Grand SetStretchBltMode( getHDC(), nOldStretchMode );
98cdf0e10cSrcweir }
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
101cdf0e10cSrcweir // -----------------------------------------------------------------------
102cdf0e10cSrcweir
ImplCalcOutSideRgn(const RECT & rSrcRect,int nLeft,int nTop,int nRight,int nBottom,HRGN & rhInvalidateRgn)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
copyArea(long nDestX,long nDestY,long nSrcX,long nSrcY,long nSrcWidth,long nSrcHeight,sal_uInt16 nFlags)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 );
2885f27b83cSArmin Le Grand nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn );
289cdf0e10cSrcweir
290cdf0e10cSrcweir bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate
2915f27b83cSArmin Le Grand ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF );
292cdf0e10cSrcweir }
293cdf0e10cSrcweir }
294cdf0e10cSrcweir }
295cdf0e10cSrcweir }
296cdf0e10cSrcweir
2975f27b83cSArmin Le Grand BitBlt( getHDC(),
298cdf0e10cSrcweir (int)nDestX, (int)nDestY,
299cdf0e10cSrcweir (int)nSrcWidth, (int)nSrcHeight,
3005f27b83cSArmin Le Grand getHDC(),
301cdf0e10cSrcweir (int)nSrcX, (int)nSrcY,
302cdf0e10cSrcweir SRCCOPY );
303cdf0e10cSrcweir
304cdf0e10cSrcweir if( bRestoreClipRgn )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir // restore old clip region
307cdf0e10cSrcweir if( nOldClipRgnType != ERROR )
3085f27b83cSArmin 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 );
3165f27b83cSArmin 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
ImplDrawBitmap(HDC hDC,const SalTwoRect & rPosAry,const WinSalBitmap & rSalBitmap,sal_Bool bPrinter,int nDrawMode)344cdf0e10cSrcweir void ImplDrawBitmap( HDC hDC,
3455f27b83cSArmin 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,
3735f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
3745f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
3755f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY),
3765f27b83cSArmin 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
3955f27b83cSArmin Le Grand if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
3965f27b83cSArmin Le Grand (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir BitBlt( hDC,
3995f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
4005f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
401cdf0e10cSrcweir hBmpDC,
4025f27b83cSArmin 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,
4105f27b83cSArmin Le Grand (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
4115f27b83cSArmin Le Grand (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
412cdf0e10cSrcweir hBmpDC,
4135f27b83cSArmin Le Grand (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
4145f27b83cSArmin 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
drawBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSalBitmap)4365f27b83cSArmin Le Grand void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
437cdf0e10cSrcweir {
4385f27b83cSArmin Le Grand bool bTryDirectPaint(!mbPrinter && !mbXORMode);
4395f27b83cSArmin Le Grand
4405f27b83cSArmin Le Grand if(bTryDirectPaint)
4415f27b83cSArmin Le Grand {
4425f27b83cSArmin Le Grand // only paint direct when no scaling and no MapMode, else the
4435f27b83cSArmin Le Grand // more expensive conversions may be done for short-time Bitmap/BitmapEx
4445f27b83cSArmin Le Grand // used for buffering only
4455f27b83cSArmin Le Grand if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
4465f27b83cSArmin Le Grand {
4475f27b83cSArmin Le Grand bTryDirectPaint = false;
4485f27b83cSArmin Le Grand }
4495f27b83cSArmin Le Grand }
4505f27b83cSArmin Le Grand
4515f27b83cSArmin Le Grand // try to draw using GdiPlus directly
4525f27b83cSArmin Le Grand if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap))
4535f27b83cSArmin Le Grand {
4545f27b83cSArmin Le Grand return;
4555f27b83cSArmin Le Grand }
4565f27b83cSArmin Le Grand
4575f27b83cSArmin Le Grand // fall back old stuff
4585f27b83cSArmin Le Grand ImplDrawBitmap(getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap),
4595f27b83cSArmin Le Grand mbPrinter,
4605f27b83cSArmin Le Grand mbXORMode ? SRCINVERT : SRCCOPY );
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
463cdf0e10cSrcweir // -----------------------------------------------------------------------
464cdf0e10cSrcweir
drawBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSSalBitmap,SalColor nTransparentColor)4655f27b83cSArmin 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 ) )
5145f27b83cSArmin Le Grand drawBitmap( rPosAry, rSalBitmap, *pMask );
515cdf0e10cSrcweir
516cdf0e10cSrcweir delete pMask;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
519cdf0e10cSrcweir // -----------------------------------------------------------------------
520cdf0e10cSrcweir
drawBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSSalBitmap,const SalBitmap & rSTransparentBitmap)5215f27b83cSArmin 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!" );
5265f27b83cSArmin Le Grand bool bTryDirectPaint(!mbPrinter && !mbXORMode);
5275f27b83cSArmin Le Grand
5285f27b83cSArmin Le Grand if(bTryDirectPaint)
5295f27b83cSArmin Le Grand {
5305f27b83cSArmin Le Grand // only paint direct when no scaling and no MapMode, else the
5315f27b83cSArmin Le Grand // more expensive conversions may be done for short-time Bitmap/BitmapEx
5325f27b83cSArmin Le Grand // used for buffering only
5335f27b83cSArmin Le Grand if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
5345f27b83cSArmin Le Grand {
5355f27b83cSArmin Le Grand bTryDirectPaint = false;
5365f27b83cSArmin Le Grand }
5375f27b83cSArmin Le Grand }
5385f27b83cSArmin Le Grand
5395f27b83cSArmin Le Grand // try to draw using GdiPlus directly
5405f27b83cSArmin Le Grand if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap))
5415f27b83cSArmin Le Grand {
5425f27b83cSArmin Le Grand return;
5435f27b83cSArmin Le Grand }
544cdf0e10cSrcweir
545cdf0e10cSrcweir const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
546cdf0e10cSrcweir const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap);
547cdf0e10cSrcweir
5485f27b83cSArmin 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;
5535f27b83cSArmin 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 ) )
5775f27b83cSArmin Le Grand ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY );
578cdf0e10cSrcweir }
579cdf0e10cSrcweir else
5805f27b83cSArmin 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 {
5875f27b83cSArmin 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
5965f27b83cSArmin 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
drawAlphaRect(long nX,long nY,long nWidth,long nHeight,sal_uInt8 nTransparency)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
6355f27b83cSArmin 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
drawMask(const SalTwoRect & rPosAry,const SalBitmap & rSSalBitmap,SalColor nMaskColor)6465f27b83cSArmin 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
6545f27b83cSArmin 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 );
6585f27b83cSArmin 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 ) )
6705f27b83cSArmin Le Grand ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL );
671cdf0e10cSrcweir }
672cdf0e10cSrcweir else
6735f27b83cSArmin Le Grand ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
674cdf0e10cSrcweir
675cdf0e10cSrcweir SelectBrush( hDC, hOldBrush );
676cdf0e10cSrcweir DeleteBrush( hMaskBrush );
677cdf0e10cSrcweir }
678cdf0e10cSrcweir
679cdf0e10cSrcweir // -----------------------------------------------------------------------
680cdf0e10cSrcweir
getBitmap(long nX,long nY,long nDX,long nDY)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
6905f27b83cSArmin 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
getPixel(long nX,long nY)721cdf0e10cSrcweir SalColor WinSalGraphics::getPixel( long nX, long nY )
722cdf0e10cSrcweir {
7235f27b83cSArmin 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
invert(long nX,long nY,long nWidth,long nHeight,SalInvert nFlags)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 );
7405f27b83cSArmin Le Grand HPEN hOldPen = SelectPen( getHDC(), hDotPen );
7415f27b83cSArmin Le Grand HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) );
7425f27b83cSArmin Le Grand int nOldROP = SetROP2( getHDC(), R2_NOT );
743cdf0e10cSrcweir
7445f27b83cSArmin Le Grand WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
745cdf0e10cSrcweir
7465f27b83cSArmin Le Grand SetROP2( getHDC(), nOldROP );
7475f27b83cSArmin Le Grand SelectPen( getHDC(), hOldPen );
7485f27b83cSArmin 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
7615f27b83cSArmin Le Grand COLORREF nOldTextColor = ::SetTextColor( getHDC(), 0 );
7625f27b83cSArmin Le Grand HBRUSH hOldBrush = SelectBrush( getHDC(), pSalData->mh50Brush );
7635f27b83cSArmin Le Grand PatBlt( getHDC(), nX, nY, nWidth, nHeight, PATINVERT );
7645f27b83cSArmin Le Grand ::SetTextColor( getHDC(), nOldTextColor );
7655f27b83cSArmin 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;
7745f27b83cSArmin Le Grand ::InvertRect( getHDC(), &aRect );
775cdf0e10cSrcweir }
776cdf0e10cSrcweir }
777cdf0e10cSrcweir
778cdf0e10cSrcweir // -----------------------------------------------------------------------
779cdf0e10cSrcweir
invert(sal_uInt32 nPoints,const SalPoint * pPtAry,SalInvert nSalFlags)780*54ae6a37SHerbert Dürr void WinSalGraphics::invert( sal_uInt32 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);
7875f27b83cSArmin 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 );
8105f27b83cSArmin Le Grand nOldTextColor = ::SetTextColor( getHDC(), 0 );
8115f27b83cSArmin Le Grand hOldBrush = SelectBrush( getHDC(), hBrush );
812cdf0e10cSrcweir }
8135f27b83cSArmin 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 {
8255f27b83cSArmin Le Grand if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
8265f27b83cSArmin Le Grand Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
827cdf0e10cSrcweir }
828cdf0e10cSrcweir else
829cdf0e10cSrcweir {
8305f27b83cSArmin Le Grand if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
8315f27b83cSArmin Le Grand WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
832cdf0e10cSrcweir }
833cdf0e10cSrcweir
8345f27b83cSArmin Le Grand SetROP2( getHDC(), nOldROP );
8355f27b83cSArmin Le Grand SelectPen( getHDC(), hOldPen );
836cdf0e10cSrcweir
837cdf0e10cSrcweir if ( nSalFlags & SAL_INVERT_TRACKFRAME )
838cdf0e10cSrcweir DeletePen( hPen );
839cdf0e10cSrcweir else
840cdf0e10cSrcweir {
8415f27b83cSArmin Le Grand ::SetTextColor( getHDC(), nOldTextColor );
8425f27b83cSArmin Le Grand SelectBrush( getHDC(), hOldBrush );
843cdf0e10cSrcweir }
844cdf0e10cSrcweir }
845