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