xref: /aoo42x/main/vcl/os2/source/gdi/salgdi2.cxx (revision 9f62ea84)
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
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
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.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <string.h>
25cdf0e10cSrcweir #include <svpm.h>
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #define _SV_SALGDI2_CXX
28cdf0e10cSrcweir #include <salbmp.h>
29cdf0e10cSrcweir #include <saldata.hxx>
30cdf0e10cSrcweir #ifndef _SV_SALIDS_HRC
31cdf0e10cSrcweir #include <salids.hrc>
32cdf0e10cSrcweir #endif
33cdf0e10cSrcweir #include <salgdi.h>
34cdf0e10cSrcweir #include <salvd.h>
35cdf0e10cSrcweir #include <vcl/salbtype.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #ifndef __H_FT2LIB
38cdf0e10cSrcweir #include <wingdi.h>
39cdf0e10cSrcweir #include <ft2lib.h>
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir 
42cdf0e10cSrcweir BOOL bFastTransparent = FALSE;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir // -----------
45cdf0e10cSrcweir // - Defines -
46cdf0e10cSrcweir // -----------
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16)))
49cdf0e10cSrcweir #define TY( y ) 			(mnHeight-(y)-1)
50cdf0e10cSrcweir 
51cdf0e10cSrcweir // ---------------
52cdf0e10cSrcweir // - SalGraphics -
53cdf0e10cSrcweir // ---------------
54cdf0e10cSrcweir 
55cdf0e10cSrcweir bool Os2SalGraphics::supportsOperation( OutDevSupportType ) const
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     return false;
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 
61cdf0e10cSrcweir void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir 	HPS 	hSrcPS;
64cdf0e10cSrcweir 	POINTL	thePoints[4];
65cdf0e10cSrcweir 	long	nSrcHeight;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 	if ( pSrcGraphics )
68cdf0e10cSrcweir 	{
69cdf0e10cSrcweir 		//hSrcPS = pSrcGraphics->mhPS;
70cdf0e10cSrcweir 		//nSrcHeight = pSrcGraphics->mnHeight;
71cdf0e10cSrcweir 		hSrcPS = static_cast<Os2SalGraphics*>(pSrcGraphics)->mhPS;
72cdf0e10cSrcweir 		nSrcHeight = static_cast<Os2SalGraphics*>(pSrcGraphics)->mnHeight;
73cdf0e10cSrcweir 	}
74cdf0e10cSrcweir 	else
75cdf0e10cSrcweir 	{
76cdf0e10cSrcweir 		hSrcPS = mhPS;
77cdf0e10cSrcweir 		nSrcHeight = mnHeight;
78cdf0e10cSrcweir 	}
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 	// lower-left corner of target
81cdf0e10cSrcweir 	thePoints[0].x = pPosAry->mnDestX;
82cdf0e10cSrcweir 	thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 );
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 	// upper-right corner of target
85cdf0e10cSrcweir 	thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth;
86cdf0e10cSrcweir 	thePoints[1].y = TY( pPosAry->mnDestY - 1 );
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	// lower-left corner of source
89cdf0e10cSrcweir 	thePoints[2].x = pPosAry->mnSrcX;
90cdf0e10cSrcweir 	thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) )
93cdf0e10cSrcweir 	{
94cdf0e10cSrcweir 		// upper-right corner of Source
95cdf0e10cSrcweir 		thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
96cdf0e10cSrcweir 		thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 		GpiBitBlt( mhPS, hSrcPS, 4, thePoints,
99cdf0e10cSrcweir 				   mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
100cdf0e10cSrcweir 	}
101cdf0e10cSrcweir 	else
102cdf0e10cSrcweir 	{
103cdf0e10cSrcweir 		GpiBitBlt( mhPS, hSrcPS, 3, thePoints,
104cdf0e10cSrcweir 				   mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
105cdf0e10cSrcweir 	}
106cdf0e10cSrcweir }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir // -----------------------------------------------------------------------
109cdf0e10cSrcweir 
110cdf0e10cSrcweir void Os2SalGraphics::copyArea( long nDestX, long nDestY,
111cdf0e10cSrcweir 							long nSrcX, long nSrcY,
112cdf0e10cSrcweir 							long nSrcWidth, long nSrcHeight,
113cdf0e10cSrcweir 							USHORT nFlags )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir 	POINTL thePoints[3];
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 	// lower-left corner of target
118cdf0e10cSrcweir 	thePoints[0].x = nDestX;
119cdf0e10cSrcweir 	thePoints[0].y = TY( nDestY + nSrcHeight - 1 );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	// upper-right corner of target
122cdf0e10cSrcweir 	thePoints[1].x = nDestX + nSrcWidth;
123cdf0e10cSrcweir 	thePoints[1].y = TY( nDestY - 1 );
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 	// lower-left corner of source
126cdf0e10cSrcweir 	thePoints[2].x = nSrcX;
127cdf0e10cSrcweir 	thePoints[2].y = TY( nSrcY + nSrcHeight - 1);
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 	if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow )
130cdf0e10cSrcweir 	{
131cdf0e10cSrcweir 		// Overlap-Bereich berechnen und invalidieren
132cdf0e10cSrcweir 		Point		aVCLSrcPos( nSrcX, nSrcY );
133cdf0e10cSrcweir 		Size		aVCLSrcSize( nSrcWidth, nSrcHeight );
134cdf0e10cSrcweir 		Rectangle	aVCLSrcRect( aVCLSrcPos, aVCLSrcSize );
135cdf0e10cSrcweir 		Rectangle	aVCLClipRect;
136cdf0e10cSrcweir 		SWP 		aSWP;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 		WinQueryWindowPos( mhWnd, &aSWP );
139cdf0e10cSrcweir 		aVCLClipRect.Right()	= aSWP.cx-1;
140cdf0e10cSrcweir 		aVCLClipRect.Bottom()	= aSWP.cy-1;
141cdf0e10cSrcweir 		if ( !aVCLSrcRect.Intersection( aVCLClipRect ).IsEmpty() )
142cdf0e10cSrcweir 		{
143cdf0e10cSrcweir 			RECTL	aSrcRect;
144cdf0e10cSrcweir 			RECTL	aTempRect;
145cdf0e10cSrcweir 			HRGN	hInvalidateRgn;
146cdf0e10cSrcweir 			HRGN	hTempRgn;
147cdf0e10cSrcweir 			HWND	hWnd;
148cdf0e10cSrcweir 			long	nRgnType;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 			long nVCLScrHeight	= aVCLSrcRect.GetHeight();
151cdf0e10cSrcweir 			aSrcRect.xLeft		= aVCLSrcRect.Left();
152cdf0e10cSrcweir 			aSrcRect.yBottom	= TY( aVCLSrcRect.Top()+nVCLScrHeight-1 );
153cdf0e10cSrcweir 			aSrcRect.xRight 	= aSrcRect.xLeft+aVCLSrcRect.GetWidth();
154cdf0e10cSrcweir 			aSrcRect.yTop		= aSrcRect.yBottom+nVCLScrHeight;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 			// Rechteck in Screen-Koordinaaten umrechnen
157cdf0e10cSrcweir 			POINTL	aPt;
158cdf0e10cSrcweir 			long	nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
159cdf0e10cSrcweir 			long	nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
160cdf0e10cSrcweir 			aPt.x = 0;
161cdf0e10cSrcweir 			aPt.y = 0;
162cdf0e10cSrcweir 			WinMapWindowPoints( mhWnd, HWND_DESKTOP, &aPt, 1 );
163cdf0e10cSrcweir 			aSrcRect.xLeft	 += aPt.x;
164cdf0e10cSrcweir 			aSrcRect.yTop	 += aPt.y;
165cdf0e10cSrcweir 			aSrcRect.xRight  += aPt.x;
166cdf0e10cSrcweir 			aSrcRect.yBottom += aPt.y;
167cdf0e10cSrcweir 			hInvalidateRgn = 0;
168cdf0e10cSrcweir 			// Bereiche ausserhalb des sichtbaren Bereiches berechnen
169cdf0e10cSrcweir 			if ( aSrcRect.xLeft < 0 )
170cdf0e10cSrcweir 			{
171cdf0e10cSrcweir 				if ( !hInvalidateRgn )
172cdf0e10cSrcweir 					hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
173cdf0e10cSrcweir 				aTempRect.xLeft 	= -31999;
174cdf0e10cSrcweir 				aTempRect.yBottom	= 0;
175cdf0e10cSrcweir 				aTempRect.xRight	= 0;
176cdf0e10cSrcweir 				aTempRect.yTop		= 31999;
177cdf0e10cSrcweir 				hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
178cdf0e10cSrcweir 				GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
179cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hTempRgn );
180cdf0e10cSrcweir 			}
181cdf0e10cSrcweir 			if ( aSrcRect.yBottom < 0 )
182cdf0e10cSrcweir 			{
183cdf0e10cSrcweir 				if ( !hInvalidateRgn )
184cdf0e10cSrcweir 					hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
185cdf0e10cSrcweir 				aTempRect.xLeft 	= 0;
186cdf0e10cSrcweir 				aTempRect.yBottom	= -31999;
187cdf0e10cSrcweir 				aTempRect.xRight	= 31999;
188cdf0e10cSrcweir 				aTempRect.yTop		= 0;
189cdf0e10cSrcweir 				hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
190cdf0e10cSrcweir 				GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
191cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hTempRgn );
192cdf0e10cSrcweir 			}
193cdf0e10cSrcweir 			if ( aSrcRect.xRight > nScreenDX )
194cdf0e10cSrcweir 			{
195cdf0e10cSrcweir 				if ( !hInvalidateRgn )
196cdf0e10cSrcweir 					hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
197cdf0e10cSrcweir 				aTempRect.xLeft 	= nScreenDX;
198cdf0e10cSrcweir 				aTempRect.yBottom	= 0;
199cdf0e10cSrcweir 				aTempRect.xRight	= 31999;
200cdf0e10cSrcweir 				aTempRect.yTop		= 31999;
201cdf0e10cSrcweir 				hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
202cdf0e10cSrcweir 				GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
203cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hTempRgn );
204cdf0e10cSrcweir 			}
205cdf0e10cSrcweir 			if ( aSrcRect.yTop > nScreenDY )
206cdf0e10cSrcweir 			{
207cdf0e10cSrcweir 				if ( !hInvalidateRgn )
208cdf0e10cSrcweir 					hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
209cdf0e10cSrcweir 				aTempRect.xLeft 	= 0;
210cdf0e10cSrcweir 				aTempRect.yBottom	= nScreenDY;
211cdf0e10cSrcweir 				aTempRect.xRight	= 31999;
212cdf0e10cSrcweir 				aTempRect.yTop		= 31999;
213cdf0e10cSrcweir 				hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
214cdf0e10cSrcweir 				GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
215cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hTempRgn );
216cdf0e10cSrcweir 			}
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 			// Bereiche die von anderen Fenstern ueberlagert werden berechnen
219cdf0e10cSrcweir 			// Calculate areas that are overlapped by other windows
220cdf0e10cSrcweir 			HWND hWndParent = WinQueryWindow( mhWnd, QW_PARENT );
221cdf0e10cSrcweir 			hWnd = WinQueryWindow( HWND_DESKTOP, QW_TOP );
222cdf0e10cSrcweir 			aVCLSrcRect = Rectangle( aSrcRect.xLeft, aSrcRect.yBottom, aSrcRect.xRight, aSrcRect.yTop );
223cdf0e10cSrcweir 			while ( hWnd )
224cdf0e10cSrcweir 			{
225cdf0e10cSrcweir 				if ( hWnd == hWndParent )
226cdf0e10cSrcweir 					break;
227cdf0e10cSrcweir 				if ( WinIsWindowVisible( hWnd ) )
228cdf0e10cSrcweir 				{
229cdf0e10cSrcweir 					WinQueryWindowPos( hWnd, &aSWP );
230cdf0e10cSrcweir 					if ( !(aSWP.fl & SWP_MINIMIZE) )
231cdf0e10cSrcweir 					{
232cdf0e10cSrcweir 						aVCLClipRect = Rectangle( Point( aSWP.x, aSWP.y ), Size( aSWP.cx, aSWP.cy ) );
233cdf0e10cSrcweir 						if ( aVCLSrcRect.IsOver( aVCLClipRect ) )
234cdf0e10cSrcweir 						{
235cdf0e10cSrcweir 							if ( !hInvalidateRgn )
236cdf0e10cSrcweir 								hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
237cdf0e10cSrcweir 							aTempRect.xLeft 	= aSWP.x;
238cdf0e10cSrcweir 							aTempRect.yBottom	= aSWP.y;
239cdf0e10cSrcweir 							aTempRect.xRight	= aTempRect.xLeft+aSWP.cx;
240cdf0e10cSrcweir 							aTempRect.yTop		= aTempRect.yBottom+aSWP.cy;
241cdf0e10cSrcweir 							hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
242cdf0e10cSrcweir 							GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
243cdf0e10cSrcweir 							GpiDestroyRegion( mhPS, hTempRgn );
244cdf0e10cSrcweir 						}
245cdf0e10cSrcweir 					}
246cdf0e10cSrcweir 				}
247cdf0e10cSrcweir 				hWnd = WinQueryWindow( hWnd, QW_NEXT );
248cdf0e10cSrcweir 			}
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 			if ( hInvalidateRgn )
251cdf0e10cSrcweir 			{
252cdf0e10cSrcweir 				hTempRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
253cdf0e10cSrcweir 				nRgnType = GpiCombineRegion( mhPS, hInvalidateRgn, hTempRgn, hInvalidateRgn, CRGN_DIFF );
254cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hTempRgn );
255cdf0e10cSrcweir 				if ( (nRgnType != RGN_ERROR) && (nRgnType != RGN_NULL) )
256cdf0e10cSrcweir 				{
257cdf0e10cSrcweir 					long nOffX = (nDestX-nSrcX);
258cdf0e10cSrcweir 					long nOffY = (nSrcY-nDestY);
259cdf0e10cSrcweir 					aPt.x = nOffX-aPt.x;
260cdf0e10cSrcweir 					aPt.y = nOffY-aPt.y;
261cdf0e10cSrcweir 					GpiOffsetRegion( mhPS, hInvalidateRgn, &aPt );
262cdf0e10cSrcweir 					WinInvalidateRegion( mhWnd, hInvalidateRgn, TRUE );
263cdf0e10cSrcweir 					// Hier loesen wir nur ein Update aus, wenn es der
264cdf0e10cSrcweir 					// MainThread ist, damit es beim Bearbeiten der
265cdf0e10cSrcweir 					// Paint-Message keinen Deadlock gibt, da der
266cdf0e10cSrcweir 					// SolarMutex durch diesen Thread schon gelockt ist
267cdf0e10cSrcweir 					SalData*	pSalData = GetSalData();
268cdf0e10cSrcweir 					ULONG		nCurThreadId = GetCurrentThreadId();
269cdf0e10cSrcweir 					if ( pSalData->mnAppThreadId == nCurThreadId )
270cdf0e10cSrcweir 						WinUpdateWindow( mhWnd );
271cdf0e10cSrcweir 				}
272cdf0e10cSrcweir 				GpiDestroyRegion( mhPS, hInvalidateRgn );
273cdf0e10cSrcweir 			}
274cdf0e10cSrcweir 		}
275cdf0e10cSrcweir 	}
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 	GpiBitBlt( mhPS, mhPS, 3, thePoints,
278cdf0e10cSrcweir 			   ROP_SRCCOPY, BBO_IGNORE );
279cdf0e10cSrcweir 
280cdf0e10cSrcweir }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir // -----------------------------------------------------------------------
283cdf0e10cSrcweir 
284cdf0e10cSrcweir void ImplDrawBitmap( HPS hPS, long nScreenHeight,
285cdf0e10cSrcweir 					 const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap,
286cdf0e10cSrcweir 					 BOOL bPrinter, int nDrawMode )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir 	if( hPS )
289cdf0e10cSrcweir 	{
290cdf0e10cSrcweir 		HANDLE		hDrawDIB;
291cdf0e10cSrcweir 		HBITMAP 	hDrawDDB = rSalBitmap.ImplGethDDB();
292cdf0e10cSrcweir 		Os2SalBitmap*	pTmpSalBmp = NULL;
293cdf0e10cSrcweir 		BOOL		bPrintDDB = ( bPrinter && hDrawDDB );
294cdf0e10cSrcweir 		BOOL		bDrawDDB1 = ( ( rSalBitmap.GetBitCount() == 1 ) && hDrawDDB );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 		if( bPrintDDB || bDrawDDB1 )
297cdf0e10cSrcweir 		{
298cdf0e10cSrcweir 			pTmpSalBmp = new Os2SalBitmap;
299cdf0e10cSrcweir 			pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
300cdf0e10cSrcweir 			hDrawDIB = pTmpSalBmp->ImplGethDIB();
301cdf0e10cSrcweir 		}
302cdf0e10cSrcweir 		else
303cdf0e10cSrcweir 			hDrawDIB = rSalBitmap.ImplGethDIB();
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 		if( hDrawDIB )
306cdf0e10cSrcweir 		{
307cdf0e10cSrcweir 			HANDLE				hSubst = rSalBitmap.ImplGethDIB1Subst();
308cdf0e10cSrcweir 			POINTL				pts[ 4 ];
309cdf0e10cSrcweir 			BITMAPINFO2*		pBI = (BITMAPINFO2*) hDrawDIB;
310cdf0e10cSrcweir 			BITMAPINFOHEADER2*	pBIH = (BITMAPINFOHEADER2*) pBI;
311cdf0e10cSrcweir 			const long			nHeight = pBIH->cy;
312cdf0e10cSrcweir 			long				nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 );
313cdf0e10cSrcweir 			BYTE*				pBits = (BYTE*) pBI + nInfoSize;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 			pts[0].x = pPosAry->mnDestX;
316cdf0e10cSrcweir 			pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
317cdf0e10cSrcweir 			pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
318cdf0e10cSrcweir 			pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 			pts[2].x = pPosAry->mnSrcX;
321cdf0e10cSrcweir 			pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
322cdf0e10cSrcweir 			pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
323cdf0e10cSrcweir 			pts[3].y = nHeight - pPosAry->mnSrcY;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 			// if we've got a 1Bit DIB, we create a 4Bit substitute
326cdf0e10cSrcweir 			if( ( pBIH->cBitCount == 1 ) && !hSubst )
327cdf0e10cSrcweir 			{
328cdf0e10cSrcweir 				// create 4Bit substitute
329cdf0e10cSrcweir 				hSubst = Os2SalBitmap::ImplCreateDIB4FromDIB1( hDrawDIB );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 				// replace substitute only, if it is no temporary SalBitmap
332cdf0e10cSrcweir 				if( !( bPrintDDB || bDrawDDB1 ) )
333cdf0e10cSrcweir 					( (Os2SalBitmap&) rSalBitmap ).ImplReplacehDIB1Subst( hSubst );
334cdf0e10cSrcweir 			}
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 			if( hSubst )
337cdf0e10cSrcweir 			{
338cdf0e10cSrcweir 				pBI = (BITMAPINFO2*) hSubst;
339cdf0e10cSrcweir 				pBIH = (BITMAPINFOHEADER2*) pBI;
340cdf0e10cSrcweir 				nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hSubst ) * sizeof( RGB2 );
341cdf0e10cSrcweir 				pBits = (BYTE*) pBI + nInfoSize;
342cdf0e10cSrcweir 			}
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 			if( bPrinter )
345cdf0e10cSrcweir 			{
346cdf0e10cSrcweir 				BYTE* pDummy;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 				// expand 8Bit-DIB's to 24Bit-DIB's, because some printer drivers
349cdf0e10cSrcweir 				// have problems to print these DIB's (strange)
350cdf0e10cSrcweir 				if( pBIH->cBitCount == 8 && pBIH->ulCompression == BCA_UNCOMP )
351cdf0e10cSrcweir 				{
352cdf0e10cSrcweir 					const long			nWidth = pBIH->cx;
353cdf0e10cSrcweir 					const long			nHeight = pBIH->cy;
354cdf0e10cSrcweir 					const long			nWidthAl8 = AlignedWidth4Bytes( nWidth * 8 );
355cdf0e10cSrcweir 					const long			nWidthAl24 = AlignedWidth4Bytes( nWidth * 24 );
356cdf0e10cSrcweir 					const long			nNewImageSize = nHeight * nWidthAl24;
357cdf0e10cSrcweir 					BITMAPINFOHEADER2*	pNewInfo;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 					pDummy = new BYTE[ sizeof( BITMAPINFO2 ) + nNewImageSize ];
360cdf0e10cSrcweir 					memset( pDummy, 0, sizeof( BITMAPINFO2 ) );
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 					pNewInfo = (BITMAPINFOHEADER2*) pDummy;
363cdf0e10cSrcweir 					pNewInfo->cbFix = sizeof( BITMAPINFOHEADER2 );
364cdf0e10cSrcweir 					pNewInfo->cx = nWidth;
365cdf0e10cSrcweir 					pNewInfo->cy = nHeight;
366cdf0e10cSrcweir 					pNewInfo->cPlanes = 1;
367cdf0e10cSrcweir 					pNewInfo->cBitCount = 24;
368cdf0e10cSrcweir 					pNewInfo->ulCompression = BCA_UNCOMP;
369cdf0e10cSrcweir 					pNewInfo->cbImage = nNewImageSize;
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 					BYTE* pBitsSrc = (BYTE*) pBIH + nInfoSize;
372cdf0e10cSrcweir 					BYTE* pBitsDst = pDummy + sizeof( BITMAPINFO2 );
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 					for( long nY = 0UL; nY < nHeight; nY++ )
375cdf0e10cSrcweir 					{
376cdf0e10cSrcweir 						BYTE* pSrcLine = pBitsSrc + nY * nWidthAl8;
377cdf0e10cSrcweir 						BYTE* pDstLine = pBitsDst + nY * nWidthAl24;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 						for( long nX = 0UL; nX < nWidth; nX++ )
380cdf0e10cSrcweir 						{
381cdf0e10cSrcweir 							const RGB2& rQuad = pBI->argbColor[ *pSrcLine++ ];
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 							*pDstLine++ = rQuad.bBlue;
384cdf0e10cSrcweir 							*pDstLine++ = rQuad.bGreen;
385cdf0e10cSrcweir 							*pDstLine++ = rQuad.bRed;
386cdf0e10cSrcweir 						}
387cdf0e10cSrcweir 					}
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 					nInfoSize = sizeof( BITMAPINFO2 );
390cdf0e10cSrcweir 				}
391cdf0e10cSrcweir 				else
392cdf0e10cSrcweir 				{
393cdf0e10cSrcweir 					const long nImageSize = ( pBIH->cbImage ? pBIH->cbImage : ( pBIH->cy * AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ) );
394cdf0e10cSrcweir 					const long nTotalSize = nInfoSize + nImageSize;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 					pDummy = new BYTE[ nTotalSize ];
397cdf0e10cSrcweir 					memcpy( pDummy, pBI, nTotalSize );
398cdf0e10cSrcweir 				}
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 				GpiDrawBits( hPS, pDummy + nInfoSize, (BITMAPINFO2*) pDummy, 4L, pts, nDrawMode, BBO_IGNORE );
401cdf0e10cSrcweir 				delete[] pDummy;
402cdf0e10cSrcweir 			}
403cdf0e10cSrcweir 			else
404cdf0e10cSrcweir 				GpiDrawBits( hPS, pBits, pBI, 4L, pts, nDrawMode, BBO_IGNORE );
405cdf0e10cSrcweir 		}
406cdf0e10cSrcweir 		else if( hDrawDDB && !bPrintDDB )
407cdf0e10cSrcweir 		{
408cdf0e10cSrcweir 			POINTL pts[ 4 ];
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 			pts[0].x = pPosAry->mnDestX;
411cdf0e10cSrcweir 			pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
412cdf0e10cSrcweir 			pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
413cdf0e10cSrcweir 			pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 			pts[2].x = pPosAry->mnSrcX;
416cdf0e10cSrcweir 			pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
417cdf0e10cSrcweir 			pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
418cdf0e10cSrcweir 			pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 			GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE );
421cdf0e10cSrcweir /*
422cdf0e10cSrcweir 			HPS hDrawPS = ImplGetCachedPS( CACHED_HPS_DRAW, hDrawDDB );
423cdf0e10cSrcweir 			Ft2BitBlt( hPS, hDrawPS, 4, pts, nDrawMode, BBO_IGNORE );
424cdf0e10cSrcweir 			ImplReleaseCachedPS( CACHED_HPS_DRAW );
425cdf0e10cSrcweir */
426cdf0e10cSrcweir 		}
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 		if( bPrintDDB || bDrawDDB1 )
429cdf0e10cSrcweir 			delete pTmpSalBmp;
430cdf0e10cSrcweir 	}
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir // -----------------------------------------------------------------------
434cdf0e10cSrcweir 
435cdf0e10cSrcweir void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
436cdf0e10cSrcweir 							  const SalBitmap& rSalBitmap )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir 	ImplDrawBitmap( mhPS, mnHeight,
439cdf0e10cSrcweir 					pPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap),
440cdf0e10cSrcweir 					mbPrinter,
441cdf0e10cSrcweir 					mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY );
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir // -----------------------------------------------------------------------
445cdf0e10cSrcweir 
446cdf0e10cSrcweir void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
447cdf0e10cSrcweir 							  const SalBitmap& rSalBitmap,
448cdf0e10cSrcweir 							  SalColor nTransparentColor )
449cdf0e10cSrcweir {
450cdf0e10cSrcweir 	DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
451cdf0e10cSrcweir     //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
452cdf0e10cSrcweir 	// an FM: kann erst einmal unberuecksichtigt bleiben
453cdf0e10cSrcweir 	drawBitmap( pPosAry, rSalBitmap );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir // -----------------------------------------------------------------------
457cdf0e10cSrcweir 
458cdf0e10cSrcweir void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
459cdf0e10cSrcweir 							  const SalBitmap& rSSalBitmap,
460cdf0e10cSrcweir 							  const SalBitmap& rSTransparentBitmap )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir 	DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
463cdf0e10cSrcweir 
464cdf0e10cSrcweir     const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
465cdf0e10cSrcweir     const Os2SalBitmap& rTransparentBitmap = static_cast<const Os2SalBitmap&>(rSTransparentBitmap);
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 	if( bFastTransparent )
468cdf0e10cSrcweir 	{
469cdf0e10cSrcweir 		ImplDrawBitmap( mhPS, mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND );
470cdf0e10cSrcweir 		ImplDrawBitmap( mhPS, mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT );
471cdf0e10cSrcweir 	}
472cdf0e10cSrcweir 	else
473cdf0e10cSrcweir 	{
474cdf0e10cSrcweir 		SalTwoRect		aPosAry = *pPosAry;
475cdf0e10cSrcweir 		int 			nDstX = (int) aPosAry.mnDestX;
476cdf0e10cSrcweir 		int 			nDstY = (int) aPosAry.mnDestY;
477cdf0e10cSrcweir 		int 			nDstWidth = (int) aPosAry.mnDestWidth;
478cdf0e10cSrcweir 		int 			nDstHeight = (int) aPosAry.mnDestHeight;
479cdf0e10cSrcweir 		HAB 			hAB = GetSalData()->mhAB;
480cdf0e10cSrcweir 		HPS 			hPS = mhPS;
481cdf0e10cSrcweir 		DEVOPENSTRUC	aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
482cdf0e10cSrcweir 		SIZEL			aSizeL = { nDstWidth, nDstHeight };
483cdf0e10cSrcweir 		POINTL			aPtL[ 3 ];
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 		HDC 			   hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
486cdf0e10cSrcweir 		HPS 			   hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
487cdf0e10cSrcweir 		HBITMAP 		   hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 );
488cdf0e10cSrcweir 		HBITMAP 		   hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, hMemBitmap );
489cdf0e10cSrcweir 		HDC 			   hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
490cdf0e10cSrcweir 		HPS 			   hMaskPS = Ft2CreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
491cdf0e10cSrcweir 		HBITMAP 		   hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 );
492cdf0e10cSrcweir 		HBITMAP 		   hMaskOld = (HBITMAP) Ft2SetBitmap( hMaskPS, hMaskBitmap );
493cdf0e10cSrcweir /*
494cdf0e10cSrcweir 		HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 );
495cdf0e10cSrcweir 		HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 );
496cdf0e10cSrcweir */
497cdf0e10cSrcweir 		aPosAry.mnDestX = aPosAry.mnDestY = 0L;
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 		aPtL[ 0 ].x = 0;
500cdf0e10cSrcweir 		aPtL[ 0 ].y = 0;
501cdf0e10cSrcweir 		aPtL[ 1 ].x = nDstWidth;
502cdf0e10cSrcweir 		aPtL[ 1 ].y = nDstHeight;
503cdf0e10cSrcweir 		aPtL[ 2 ].x = nDstX;
504cdf0e10cSrcweir 		aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 );
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 		GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
507cdf0e10cSrcweir 		ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 		aPtL[ 2 ].x = 0;
510cdf0e10cSrcweir 		aPtL[ 2 ].y = 0;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 		GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE );
513cdf0e10cSrcweir 		ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE );
514cdf0e10cSrcweir 		GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE );
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 		aPtL[ 0 ].x = nDstX;
517cdf0e10cSrcweir 		aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 );
518cdf0e10cSrcweir 		aPtL[ 1 ].x = nDstX + nDstWidth;
519cdf0e10cSrcweir 		aPtL[ 1 ].y = TY( nDstY - 1 );
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 		GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 		Ft2SetBitmap( hMaskPS, hMaskOld );
524cdf0e10cSrcweir 		Ft2DestroyPS( hMaskPS );
525cdf0e10cSrcweir 		DevCloseDC( hMaskDC );
526cdf0e10cSrcweir 		GpiDeleteBitmap( hMaskBitmap );
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 		Ft2SetBitmap( hMemPS, hMemOld );
529cdf0e10cSrcweir 		Ft2DestroyPS( hMemPS );
530cdf0e10cSrcweir 		DevCloseDC( hMemDC );
531cdf0e10cSrcweir 		GpiDeleteBitmap( hMemBitmap );
532cdf0e10cSrcweir 
533cdf0e10cSrcweir /*
534cdf0e10cSrcweir 		ImplReleaseCachedPS( CACHED_HPS_1 );
535cdf0e10cSrcweir 		ImplReleaseCachedPS( CACHED_HPS_2 );
536cdf0e10cSrcweir */
537cdf0e10cSrcweir 	}
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir // -----------------------------------------------------------------------
541cdf0e10cSrcweir 
542cdf0e10cSrcweir bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
543cdf0e10cSrcweir 				      const SalBitmap&  rSrcBitmap,
544cdf0e10cSrcweir 				      const SalBitmap&  rAlphaBmp )
545cdf0e10cSrcweir {
546cdf0e10cSrcweir 	// TODO(P3) implement alpha blending
547cdf0e10cSrcweir 	return false;
548cdf0e10cSrcweir }
549cdf0e10cSrcweir 
550cdf0e10cSrcweir // -----------------------------------------------------------------------
551cdf0e10cSrcweir 
552cdf0e10cSrcweir bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
553cdf0e10cSrcweir                                     long nHeight, sal_uInt8 nTransparency )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir 	// TODO(P3) implement alpha blending
556cdf0e10cSrcweir 	return false;
557cdf0e10cSrcweir }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir // -----------------------------------------------------------------------
560cdf0e10cSrcweir 
561cdf0e10cSrcweir void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry,
562cdf0e10cSrcweir 							const SalBitmap& rSSalBitmap,
563cdf0e10cSrcweir 							SalColor nMaskColor )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir 	DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 	SalTwoRect	aPosAry = *pPosAry;
570cdf0e10cSrcweir 	HPS 		hPS = mhPS;
571cdf0e10cSrcweir 	IMAGEBUNDLE aBundle, aOldBundle;
572cdf0e10cSrcweir 	AREABUNDLE	aAreaBundle, aOldAreaBundle;
573cdf0e10cSrcweir 	const ULONG    nColor = RGBCOLOR( SALCOLOR_RED( nMaskColor ),
574cdf0e10cSrcweir 									SALCOLOR_GREEN( nMaskColor ),
575cdf0e10cSrcweir 									SALCOLOR_BLUE( nMaskColor ) );
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle );
578cdf0e10cSrcweir 	aBundle.lColor = RGBCOLOR( 0, 0, 0 );
579cdf0e10cSrcweir 	aBundle.lBackColor = RGBCOLOR( 0xFF, 0xFF, 0xFF );
580cdf0e10cSrcweir 	Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle );
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
583cdf0e10cSrcweir 				   ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle );
584cdf0e10cSrcweir 	aAreaBundle.lColor = nColor;
585cdf0e10cSrcweir 	aAreaBundle.lBackColor = nColor;
586cdf0e10cSrcweir 	aAreaBundle.usSymbol = PATSYM_SOLID;
587cdf0e10cSrcweir 	aAreaBundle.usMixMode = FM_OVERPAINT;
588cdf0e10cSrcweir 	aAreaBundle.usBackMixMode = BM_OVERPAINT;
589cdf0e10cSrcweir 	Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
590cdf0e10cSrcweir 				 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle );
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 	ImplDrawBitmap( hPS, mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L );
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 	Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle );
595cdf0e10cSrcweir 	Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
596cdf0e10cSrcweir 				 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle );
597cdf0e10cSrcweir }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir // -----------------------------------------------------------------------
600cdf0e10cSrcweir 
601cdf0e10cSrcweir SalBitmap* Os2SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
602cdf0e10cSrcweir {
603cdf0e10cSrcweir 	HAB 		   hAB = GetSalData()->mhAB;
604cdf0e10cSrcweir 	SIZEL		 size = { nDX, nDY };
605cdf0e10cSrcweir 	Os2SalBitmap*	  pSalBitmap = NULL;
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 	// create device context (at this time allways display compatible)
608cdf0e10cSrcweir 	DEVOPENSTRUC	aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
609cdf0e10cSrcweir 	HDC 			hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
610cdf0e10cSrcweir 	HPS 			hMemPS = Ft2CreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
611cdf0e10cSrcweir 	HBITMAP 		hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 );
612cdf0e10cSrcweir 	HBITMAP 		hMemOld = Ft2SetBitmap( hMemPS, hMemBmp );
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 	// creation successfull?
615cdf0e10cSrcweir 	if( hMemDC && hMemPS && hMemBmp )
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		POINTL thePoints[ 3 ];
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 		// lower-left corner of target
620cdf0e10cSrcweir 		thePoints[ 0 ].x = 0;
621cdf0e10cSrcweir 		thePoints[ 0 ].y = 0;
622cdf0e10cSrcweir 
623cdf0e10cSrcweir 		// upper-right corner of target
624cdf0e10cSrcweir 		thePoints[ 1 ].x = nDX;
625cdf0e10cSrcweir 		thePoints[ 1 ].y = nDY;
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 		// lower-left corner of source
628cdf0e10cSrcweir 		thePoints[ 2 ].x = nX;
629cdf0e10cSrcweir 		thePoints[ 2 ].y = TY( nY + nDY - 1 );
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 		long lHits = GpiBitBlt( hMemPS, mhPS, 3, thePoints,
632cdf0e10cSrcweir 								mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 		if( hMemPS )
635cdf0e10cSrcweir 		{
636cdf0e10cSrcweir 			Ft2SetBitmap( hMemPS, hMemOld );
637cdf0e10cSrcweir 			Ft2DestroyPS( hMemPS );
638cdf0e10cSrcweir 		}
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 		if( hMemDC )
641cdf0e10cSrcweir 			DevCloseDC( hMemDC );
642cdf0e10cSrcweir 
643cdf0e10cSrcweir 		if( lHits == GPI_OK )
644cdf0e10cSrcweir 		{
645cdf0e10cSrcweir 			pSalBitmap = new Os2SalBitmap;
646cdf0e10cSrcweir 
647cdf0e10cSrcweir 			if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) )
648cdf0e10cSrcweir 			{
649cdf0e10cSrcweir 				delete pSalBitmap;
650cdf0e10cSrcweir 				pSalBitmap = NULL;
651cdf0e10cSrcweir 			}
652cdf0e10cSrcweir 		}
653cdf0e10cSrcweir 	}
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 	if( !pSalBitmap )
656cdf0e10cSrcweir 		GpiDeleteBitmap( hMemBmp );
657cdf0e10cSrcweir 
658cdf0e10cSrcweir 	// return pointer to SAL-Bitmap
659cdf0e10cSrcweir 	return pSalBitmap;
660cdf0e10cSrcweir }
661cdf0e10cSrcweir 
662cdf0e10cSrcweir // -----------------------------------------------------------------------
663cdf0e10cSrcweir 
664cdf0e10cSrcweir SalColor Os2SalGraphics::getPixel( long nX, long nY )
665cdf0e10cSrcweir {
666cdf0e10cSrcweir 	POINTL	  aPt = { nX, TY( nY ) };
667cdf0e10cSrcweir 	LONG	nColor = Ft2QueryPel( mhPS, &aPt );
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 	return MAKE_SALCOLOR( (BYTE) ( nColor >> 16 ), (BYTE) ( nColor >> 8 ), (BYTE) nColor );
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir // -----------------------------------------------------------------------
673cdf0e10cSrcweir 
674cdf0e10cSrcweir void Os2SalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
675cdf0e10cSrcweir {
676cdf0e10cSrcweir 	if( nFlags & SAL_INVERT_TRACKFRAME )
677cdf0e10cSrcweir 	{
678cdf0e10cSrcweir 		// save old vylues
679cdf0e10cSrcweir 		LINEBUNDLE oldLb;
680cdf0e10cSrcweir 		LINEBUNDLE lb;
681cdf0e10cSrcweir 		GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 		// set linetype to short dash
684cdf0e10cSrcweir 		lb.lColor = RGBCOLOR( 255, 255, 255 );
685cdf0e10cSrcweir 		lb.usMixMode = FM_XOR;
686cdf0e10cSrcweir 		lb.usType = LINETYPE_ALTERNATE;
687cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
688cdf0e10cSrcweir 
689cdf0e10cSrcweir 		// draw inverted box
690cdf0e10cSrcweir 		POINTL aPt;
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 		aPt.x = nX;
693cdf0e10cSrcweir 		aPt.y = TY( nY );
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 		Ft2Move( mhPS, &aPt );
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 		aPt.x = nX + nWidth - 1;
698cdf0e10cSrcweir 		aPt.y = TY( nY + nHeight - 1 );
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 		Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 );
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 		// restore old values
703cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 	}
706cdf0e10cSrcweir 	else
707cdf0e10cSrcweir 	{
708cdf0e10cSrcweir 		// save old values
709cdf0e10cSrcweir 		AREABUNDLE oldAb;
710cdf0e10cSrcweir 		AREABUNDLE ab;
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 		GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
713cdf0e10cSrcweir 
714cdf0e10cSrcweir 		// set fill color to black
715cdf0e10cSrcweir 		ab.lColor = RGBCOLOR( 255, 255, 255 );
716cdf0e10cSrcweir 		ab.usMixMode = FM_XOR;
717cdf0e10cSrcweir 		ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
718cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
719cdf0e10cSrcweir 
720cdf0e10cSrcweir 		// draw inverted box
721cdf0e10cSrcweir 		POINTL aPt;
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 		aPt.x = nX;
724cdf0e10cSrcweir 		aPt.y = TY( nY );
725cdf0e10cSrcweir 
726cdf0e10cSrcweir 		Ft2Move( mhPS, &aPt );
727cdf0e10cSrcweir 
728cdf0e10cSrcweir 		aPt.x = nX + nWidth - 1;
729cdf0e10cSrcweir 		aPt.y = TY( nY + nHeight - 1 );
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 		Ft2Box( mhPS, DRO_FILL, &aPt, 0, 0 );
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 		// restore old values
734cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );
735cdf0e10cSrcweir 	}
736cdf0e10cSrcweir }
737cdf0e10cSrcweir 
738cdf0e10cSrcweir // -----------------------------------------------------------------------
739cdf0e10cSrcweir 
740cdf0e10cSrcweir void Os2SalGraphics::invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags )
741cdf0e10cSrcweir {
742cdf0e10cSrcweir 	if( nFlags & SAL_INVERT_TRACKFRAME )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir 		// save old vylues
745cdf0e10cSrcweir 		LINEBUNDLE oldLb;
746cdf0e10cSrcweir 		LINEBUNDLE lb;
747cdf0e10cSrcweir 		GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
748cdf0e10cSrcweir 
749cdf0e10cSrcweir 		// set linetype to short dash
750cdf0e10cSrcweir 		lb.lColor = RGBCOLOR( 255, 255, 255 );
751cdf0e10cSrcweir 		lb.usMixMode = FM_XOR;
752cdf0e10cSrcweir 		lb.usType = LINETYPE_ALTERNATE;
753cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 		// Draw Polyline
756cdf0e10cSrcweir 		drawPolyLine( nPoints, pPtAry );
757cdf0e10cSrcweir 
758cdf0e10cSrcweir 		// restore old values
759cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
760cdf0e10cSrcweir 	}
761cdf0e10cSrcweir 	else
762cdf0e10cSrcweir 	{
763cdf0e10cSrcweir 		// save old values
764cdf0e10cSrcweir 		AREABUNDLE oldAb;
765cdf0e10cSrcweir 		AREABUNDLE ab;
766cdf0e10cSrcweir 
767cdf0e10cSrcweir 		GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 		// set fill color to black
770cdf0e10cSrcweir 		ab.lColor = RGBCOLOR( 255, 255, 255 );
771cdf0e10cSrcweir 		ab.usMixMode = FM_XOR;
772cdf0e10cSrcweir 		ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
773cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 		// Draw Polyline
776cdf0e10cSrcweir 		drawPolygon( nPoints, pPtAry );
777cdf0e10cSrcweir 
778cdf0e10cSrcweir 		// restore old values
779cdf0e10cSrcweir 		Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );
780cdf0e10cSrcweir 	}
781cdf0e10cSrcweir }
782cdf0e10cSrcweir 
783