xref: /trunk/main/vcl/os2/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 #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