merge the formfield patch from ooo-build
[ooovba.git] / vcl / os2 / source / gdi / salgdi2.cxx
blob0479e92e76c9c9ad2b28929f0a3257132c78eeea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salgdi2.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <string.h>
32 #include <svpm.h>
34 #define _SV_SALGDI2_CXX
35 #include <salbmp.h>
36 #include <saldata.hxx>
37 #ifndef _SV_SALIDS_HRC
38 #include <salids.hrc>
39 #endif
40 #include <salgdi.h>
41 #include <salvd.h>
42 #include <vcl/salbtype.hxx>
44 #ifndef __H_FT2LIB
45 #include <wingdi.h>
46 #include <ft2lib.h>
47 #endif
49 BOOL bFastTransparent = FALSE;
51 // -----------
52 // - Defines -
53 // -----------
55 #define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16)))
56 #define TY( y ) (mnHeight-(y)-1)
58 // ---------------
59 // - SalGraphics -
60 // ---------------
62 bool Os2SalGraphics::supportsOperation( OutDevSupportType ) const
64 return false;
68 void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
70 HPS hSrcPS;
71 POINTL thePoints[4];
72 long nSrcHeight;
74 if ( pSrcGraphics )
76 //hSrcPS = pSrcGraphics->mhPS;
77 //nSrcHeight = pSrcGraphics->mnHeight;
78 hSrcPS = static_cast<Os2SalGraphics*>(pSrcGraphics)->mhPS;
79 nSrcHeight = static_cast<Os2SalGraphics*>(pSrcGraphics)->mnHeight;
81 else
83 hSrcPS = mhPS;
84 nSrcHeight = mnHeight;
87 // lower-left corner of target
88 thePoints[0].x = pPosAry->mnDestX;
89 thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 );
91 // upper-right corner of target
92 thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth;
93 thePoints[1].y = TY( pPosAry->mnDestY - 1 );
95 // lower-left corner of source
96 thePoints[2].x = pPosAry->mnSrcX;
97 thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
99 if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) )
101 // upper-right corner of Source
102 thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
103 thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight;
105 GpiBitBlt( mhPS, hSrcPS, 4, thePoints,
106 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
108 else
110 GpiBitBlt( mhPS, hSrcPS, 3, thePoints,
111 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
115 // -----------------------------------------------------------------------
117 void Os2SalGraphics::copyArea( long nDestX, long nDestY,
118 long nSrcX, long nSrcY,
119 long nSrcWidth, long nSrcHeight,
120 USHORT nFlags )
122 POINTL thePoints[3];
124 // lower-left corner of target
125 thePoints[0].x = nDestX;
126 thePoints[0].y = TY( nDestY + nSrcHeight - 1 );
128 // upper-right corner of target
129 thePoints[1].x = nDestX + nSrcWidth;
130 thePoints[1].y = TY( nDestY - 1 );
132 // lower-left corner of source
133 thePoints[2].x = nSrcX;
134 thePoints[2].y = TY( nSrcY + nSrcHeight - 1);
136 if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow )
138 // Overlap-Bereich berechnen und invalidieren
139 Point aVCLSrcPos( nSrcX, nSrcY );
140 Size aVCLSrcSize( nSrcWidth, nSrcHeight );
141 Rectangle aVCLSrcRect( aVCLSrcPos, aVCLSrcSize );
142 Rectangle aVCLClipRect;
143 SWP aSWP;
145 WinQueryWindowPos( mhWnd, &aSWP );
146 aVCLClipRect.Right() = aSWP.cx-1;
147 aVCLClipRect.Bottom() = aSWP.cy-1;
148 if ( !aVCLSrcRect.Intersection( aVCLClipRect ).IsEmpty() )
150 RECTL aSrcRect;
151 RECTL aTempRect;
152 HRGN hInvalidateRgn;
153 HRGN hTempRgn;
154 HWND hWnd;
155 long nRgnType;
157 long nVCLScrHeight = aVCLSrcRect.GetHeight();
158 aSrcRect.xLeft = aVCLSrcRect.Left();
159 aSrcRect.yBottom = TY( aVCLSrcRect.Top()+nVCLScrHeight-1 );
160 aSrcRect.xRight = aSrcRect.xLeft+aVCLSrcRect.GetWidth();
161 aSrcRect.yTop = aSrcRect.yBottom+nVCLScrHeight;
163 // Rechteck in Screen-Koordinaaten umrechnen
164 POINTL aPt;
165 long nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
166 long nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
167 aPt.x = 0;
168 aPt.y = 0;
169 WinMapWindowPoints( mhWnd, HWND_DESKTOP, &aPt, 1 );
170 aSrcRect.xLeft += aPt.x;
171 aSrcRect.yTop += aPt.y;
172 aSrcRect.xRight += aPt.x;
173 aSrcRect.yBottom += aPt.y;
174 hInvalidateRgn = 0;
175 // Bereiche ausserhalb des sichtbaren Bereiches berechnen
176 if ( aSrcRect.xLeft < 0 )
178 if ( !hInvalidateRgn )
179 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
180 aTempRect.xLeft = -31999;
181 aTempRect.yBottom = 0;
182 aTempRect.xRight = 0;
183 aTempRect.yTop = 31999;
184 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
185 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
186 GpiDestroyRegion( mhPS, hTempRgn );
188 if ( aSrcRect.yBottom < 0 )
190 if ( !hInvalidateRgn )
191 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
192 aTempRect.xLeft = 0;
193 aTempRect.yBottom = -31999;
194 aTempRect.xRight = 31999;
195 aTempRect.yTop = 0;
196 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
197 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
198 GpiDestroyRegion( mhPS, hTempRgn );
200 if ( aSrcRect.xRight > nScreenDX )
202 if ( !hInvalidateRgn )
203 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
204 aTempRect.xLeft = nScreenDX;
205 aTempRect.yBottom = 0;
206 aTempRect.xRight = 31999;
207 aTempRect.yTop = 31999;
208 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
209 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
210 GpiDestroyRegion( mhPS, hTempRgn );
212 if ( aSrcRect.yTop > nScreenDY )
214 if ( !hInvalidateRgn )
215 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
216 aTempRect.xLeft = 0;
217 aTempRect.yBottom = nScreenDY;
218 aTempRect.xRight = 31999;
219 aTempRect.yTop = 31999;
220 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
221 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
222 GpiDestroyRegion( mhPS, hTempRgn );
225 // Bereiche die von anderen Fenstern ueberlagert werden berechnen
226 // Calculate areas that are overlapped by other windows
227 HWND hWndParent = WinQueryWindow( mhWnd, QW_PARENT );
228 hWnd = WinQueryWindow( HWND_DESKTOP, QW_TOP );
229 aVCLSrcRect = Rectangle( aSrcRect.xLeft, aSrcRect.yBottom, aSrcRect.xRight, aSrcRect.yTop );
230 while ( hWnd )
232 if ( hWnd == hWndParent )
233 break;
234 if ( WinIsWindowVisible( hWnd ) )
236 WinQueryWindowPos( hWnd, &aSWP );
237 if ( !(aSWP.fl & SWP_MINIMIZE) )
239 aVCLClipRect = Rectangle( Point( aSWP.x, aSWP.y ), Size( aSWP.cx, aSWP.cy ) );
240 if ( aVCLSrcRect.IsOver( aVCLClipRect ) )
242 if ( !hInvalidateRgn )
243 hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
244 aTempRect.xLeft = aSWP.x;
245 aTempRect.yBottom = aSWP.y;
246 aTempRect.xRight = aTempRect.xLeft+aSWP.cx;
247 aTempRect.yTop = aTempRect.yBottom+aSWP.cy;
248 hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect );
249 GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
250 GpiDestroyRegion( mhPS, hTempRgn );
254 hWnd = WinQueryWindow( hWnd, QW_NEXT );
257 if ( hInvalidateRgn )
259 hTempRgn = GpiCreateRegion( mhPS, 1, &aSrcRect );
260 nRgnType = GpiCombineRegion( mhPS, hInvalidateRgn, hTempRgn, hInvalidateRgn, CRGN_DIFF );
261 GpiDestroyRegion( mhPS, hTempRgn );
262 if ( (nRgnType != RGN_ERROR) && (nRgnType != RGN_NULL) )
264 long nOffX = (nDestX-nSrcX);
265 long nOffY = (nSrcY-nDestY);
266 aPt.x = nOffX-aPt.x;
267 aPt.y = nOffY-aPt.y;
268 GpiOffsetRegion( mhPS, hInvalidateRgn, &aPt );
269 WinInvalidateRegion( mhWnd, hInvalidateRgn, TRUE );
270 // Hier loesen wir nur ein Update aus, wenn es der
271 // MainThread ist, damit es beim Bearbeiten der
272 // Paint-Message keinen Deadlock gibt, da der
273 // SolarMutex durch diesen Thread schon gelockt ist
274 SalData* pSalData = GetSalData();
275 ULONG nCurThreadId = GetCurrentThreadId();
276 if ( pSalData->mnAppThreadId == nCurThreadId )
277 WinUpdateWindow( mhWnd );
279 GpiDestroyRegion( mhPS, hInvalidateRgn );
284 GpiBitBlt( mhPS, mhPS, 3, thePoints,
285 ROP_SRCCOPY, BBO_IGNORE );
289 // -----------------------------------------------------------------------
291 void ImplDrawBitmap( HPS hPS, long nScreenHeight,
292 const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap,
293 BOOL bPrinter, int nDrawMode )
295 if( hPS )
297 HANDLE hDrawDIB;
298 HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
299 Os2SalBitmap* pTmpSalBmp = NULL;
300 BOOL bPrintDDB = ( bPrinter && hDrawDDB );
301 BOOL bDrawDDB1 = ( ( rSalBitmap.GetBitCount() == 1 ) && hDrawDDB );
303 if( bPrintDDB || bDrawDDB1 )
305 pTmpSalBmp = new Os2SalBitmap;
306 pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
307 hDrawDIB = pTmpSalBmp->ImplGethDIB();
309 else
310 hDrawDIB = rSalBitmap.ImplGethDIB();
312 if( hDrawDIB )
314 HANDLE hSubst = rSalBitmap.ImplGethDIB1Subst();
315 POINTL pts[ 4 ];
316 BITMAPINFO2* pBI = (BITMAPINFO2*) hDrawDIB;
317 BITMAPINFOHEADER2* pBIH = (BITMAPINFOHEADER2*) pBI;
318 const long nHeight = pBIH->cy;
319 long nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 );
320 BYTE* pBits = (BYTE*) pBI + nInfoSize;
322 pts[0].x = pPosAry->mnDestX;
323 pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
324 pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
325 pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
327 pts[2].x = pPosAry->mnSrcX;
328 pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
329 pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
330 pts[3].y = nHeight - pPosAry->mnSrcY;
332 // if we've got a 1Bit DIB, we create a 4Bit substitute
333 if( ( pBIH->cBitCount == 1 ) && !hSubst )
335 // create 4Bit substitute
336 hSubst = Os2SalBitmap::ImplCreateDIB4FromDIB1( hDrawDIB );
338 // replace substitute only, if it is no temporary SalBitmap
339 if( !( bPrintDDB || bDrawDDB1 ) )
340 ( (Os2SalBitmap&) rSalBitmap ).ImplReplacehDIB1Subst( hSubst );
343 if( hSubst )
345 pBI = (BITMAPINFO2*) hSubst;
346 pBIH = (BITMAPINFOHEADER2*) pBI;
347 nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hSubst ) * sizeof( RGB2 );
348 pBits = (BYTE*) pBI + nInfoSize;
351 if( bPrinter )
353 BYTE* pDummy;
355 // expand 8Bit-DIB's to 24Bit-DIB's, because some printer drivers
356 // have problems to print these DIB's (strange)
357 if( pBIH->cBitCount == 8 && pBIH->ulCompression == BCA_UNCOMP )
359 const long nWidth = pBIH->cx;
360 const long nHeight = pBIH->cy;
361 const long nWidthAl8 = AlignedWidth4Bytes( nWidth * 8 );
362 const long nWidthAl24 = AlignedWidth4Bytes( nWidth * 24 );
363 const long nNewImageSize = nHeight * nWidthAl24;
364 BITMAPINFOHEADER2* pNewInfo;
366 pDummy = new BYTE[ sizeof( BITMAPINFO2 ) + nNewImageSize ];
367 memset( pDummy, 0, sizeof( BITMAPINFO2 ) );
369 pNewInfo = (BITMAPINFOHEADER2*) pDummy;
370 pNewInfo->cbFix = sizeof( BITMAPINFOHEADER2 );
371 pNewInfo->cx = nWidth;
372 pNewInfo->cy = nHeight;
373 pNewInfo->cPlanes = 1;
374 pNewInfo->cBitCount = 24;
375 pNewInfo->ulCompression = BCA_UNCOMP;
376 pNewInfo->cbImage = nNewImageSize;
378 BYTE* pBitsSrc = (BYTE*) pBIH + nInfoSize;
379 BYTE* pBitsDst = pDummy + sizeof( BITMAPINFO2 );
381 for( long nY = 0UL; nY < nHeight; nY++ )
383 BYTE* pSrcLine = pBitsSrc + nY * nWidthAl8;
384 BYTE* pDstLine = pBitsDst + nY * nWidthAl24;
386 for( long nX = 0UL; nX < nWidth; nX++ )
388 const RGB2& rQuad = pBI->argbColor[ *pSrcLine++ ];
390 *pDstLine++ = rQuad.bBlue;
391 *pDstLine++ = rQuad.bGreen;
392 *pDstLine++ = rQuad.bRed;
396 nInfoSize = sizeof( BITMAPINFO2 );
398 else
400 const long nImageSize = ( pBIH->cbImage ? pBIH->cbImage : ( pBIH->cy * AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ) );
401 const long nTotalSize = nInfoSize + nImageSize;
403 pDummy = new BYTE[ nTotalSize ];
404 memcpy( pDummy, pBI, nTotalSize );
407 GpiDrawBits( hPS, pDummy + nInfoSize, (BITMAPINFO2*) pDummy, 4L, pts, nDrawMode, BBO_IGNORE );
408 delete[] pDummy;
410 else
411 GpiDrawBits( hPS, pBits, pBI, 4L, pts, nDrawMode, BBO_IGNORE );
413 else if( hDrawDDB && !bPrintDDB )
415 POINTL pts[ 4 ];
417 pts[0].x = pPosAry->mnDestX;
418 pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
419 pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
420 pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
422 pts[2].x = pPosAry->mnSrcX;
423 pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
424 pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
425 pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY;
427 GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE );
429 HPS hDrawPS = ImplGetCachedPS( CACHED_HPS_DRAW, hDrawDDB );
430 Ft2BitBlt( hPS, hDrawPS, 4, pts, nDrawMode, BBO_IGNORE );
431 ImplReleaseCachedPS( CACHED_HPS_DRAW );
435 if( bPrintDDB || bDrawDDB1 )
436 delete pTmpSalBmp;
440 // -----------------------------------------------------------------------
442 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
443 const SalBitmap& rSalBitmap )
445 ImplDrawBitmap( mhPS, mnHeight,
446 pPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap),
447 mbPrinter,
448 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY );
451 // -----------------------------------------------------------------------
453 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
454 const SalBitmap& rSalBitmap,
455 SalColor nTransparentColor )
457 DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
458 //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
459 // an FM: kann erst einmal unberuecksichtigt bleiben
460 drawBitmap( pPosAry, rSalBitmap );
463 // -----------------------------------------------------------------------
465 void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry,
466 const SalBitmap& rSSalBitmap,
467 const SalBitmap& rSTransparentBitmap )
469 DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
471 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
472 const Os2SalBitmap& rTransparentBitmap = static_cast<const Os2SalBitmap&>(rSTransparentBitmap);
474 if( bFastTransparent )
476 ImplDrawBitmap( mhPS, mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND );
477 ImplDrawBitmap( mhPS, mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT );
479 else
481 SalTwoRect aPosAry = *pPosAry;
482 int nDstX = (int) aPosAry.mnDestX;
483 int nDstY = (int) aPosAry.mnDestY;
484 int nDstWidth = (int) aPosAry.mnDestWidth;
485 int nDstHeight = (int) aPosAry.mnDestHeight;
486 HAB hAB = GetSalData()->mhAB;
487 HPS hPS = mhPS;
488 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
489 SIZEL aSizeL = { nDstWidth, nDstHeight };
490 POINTL aPtL[ 3 ];
492 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
493 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
494 HBITMAP hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 );
495 HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, hMemBitmap );
496 HDC hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
497 HPS hMaskPS = Ft2CreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
498 HBITMAP hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 );
499 HBITMAP hMaskOld = (HBITMAP) Ft2SetBitmap( hMaskPS, hMaskBitmap );
501 HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 );
502 HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 );
504 aPosAry.mnDestX = aPosAry.mnDestY = 0L;
506 aPtL[ 0 ].x = 0;
507 aPtL[ 0 ].y = 0;
508 aPtL[ 1 ].x = nDstWidth;
509 aPtL[ 1 ].y = nDstHeight;
510 aPtL[ 2 ].x = nDstX;
511 aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 );
513 GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
514 ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY );
516 aPtL[ 2 ].x = 0;
517 aPtL[ 2 ].y = 0;
519 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE );
520 ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE );
521 GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE );
523 aPtL[ 0 ].x = nDstX;
524 aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 );
525 aPtL[ 1 ].x = nDstX + nDstWidth;
526 aPtL[ 1 ].y = TY( nDstY - 1 );
528 GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
530 Ft2SetBitmap( hMaskPS, hMaskOld );
531 Ft2DestroyPS( hMaskPS );
532 DevCloseDC( hMaskDC );
533 GpiDeleteBitmap( hMaskBitmap );
535 Ft2SetBitmap( hMemPS, hMemOld );
536 Ft2DestroyPS( hMemPS );
537 DevCloseDC( hMemDC );
538 GpiDeleteBitmap( hMemBitmap );
541 ImplReleaseCachedPS( CACHED_HPS_1 );
542 ImplReleaseCachedPS( CACHED_HPS_2 );
547 // -----------------------------------------------------------------------
549 bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
550 const SalBitmap& rSrcBitmap,
551 const SalBitmap& rAlphaBmp )
553 // TODO(P3) implement alpha blending
554 return false;
557 // -----------------------------------------------------------------------
559 bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
560 long nHeight, sal_uInt8 nTransparency )
562 // TODO(P3) implement alpha blending
563 return false;
566 // -----------------------------------------------------------------------
568 void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry,
569 const SalBitmap& rSSalBitmap,
570 SalColor nMaskColor )
572 DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
574 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
576 SalTwoRect aPosAry = *pPosAry;
577 HPS hPS = mhPS;
578 IMAGEBUNDLE aBundle, aOldBundle;
579 AREABUNDLE aAreaBundle, aOldAreaBundle;
580 const ULONG nColor = RGBCOLOR( SALCOLOR_RED( nMaskColor ),
581 SALCOLOR_GREEN( nMaskColor ),
582 SALCOLOR_BLUE( nMaskColor ) );
584 GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle );
585 aBundle.lColor = RGBCOLOR( 0, 0, 0 );
586 aBundle.lBackColor = RGBCOLOR( 0xFF, 0xFF, 0xFF );
587 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle );
589 GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
590 ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle );
591 aAreaBundle.lColor = nColor;
592 aAreaBundle.lBackColor = nColor;
593 aAreaBundle.usSymbol = PATSYM_SOLID;
594 aAreaBundle.usMixMode = FM_OVERPAINT;
595 aAreaBundle.usBackMixMode = BM_OVERPAINT;
596 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
597 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle );
599 ImplDrawBitmap( hPS, mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L );
601 Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle );
602 Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
603 ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle );
606 // -----------------------------------------------------------------------
608 SalBitmap* Os2SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
610 HAB hAB = GetSalData()->mhAB;
611 SIZEL size = { nDX, nDY };
612 Os2SalBitmap* pSalBitmap = NULL;
614 // create device context (at this time allways display compatible)
615 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
616 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
617 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
618 HBITMAP hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 );
619 HBITMAP hMemOld = Ft2SetBitmap( hMemPS, hMemBmp );
621 // creation successfull?
622 if( hMemDC && hMemPS && hMemBmp )
624 POINTL thePoints[ 3 ];
626 // lower-left corner of target
627 thePoints[ 0 ].x = 0;
628 thePoints[ 0 ].y = 0;
630 // upper-right corner of target
631 thePoints[ 1 ].x = nDX;
632 thePoints[ 1 ].y = nDY;
634 // lower-left corner of source
635 thePoints[ 2 ].x = nX;
636 thePoints[ 2 ].y = TY( nY + nDY - 1 );
638 long lHits = GpiBitBlt( hMemPS, mhPS, 3, thePoints,
639 mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
641 if( hMemPS )
643 Ft2SetBitmap( hMemPS, hMemOld );
644 Ft2DestroyPS( hMemPS );
647 if( hMemDC )
648 DevCloseDC( hMemDC );
650 if( lHits == GPI_OK )
652 pSalBitmap = new Os2SalBitmap;
654 if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) )
656 delete pSalBitmap;
657 pSalBitmap = NULL;
662 if( !pSalBitmap )
663 GpiDeleteBitmap( hMemBmp );
665 // return pointer to SAL-Bitmap
666 return pSalBitmap;
669 // -----------------------------------------------------------------------
671 SalColor Os2SalGraphics::getPixel( long nX, long nY )
673 POINTL aPt = { nX, TY( nY ) };
674 LONG nColor = Ft2QueryPel( mhPS, &aPt );
676 return MAKE_SALCOLOR( (BYTE) ( nColor >> 16 ), (BYTE) ( nColor >> 8 ), (BYTE) nColor );
679 // -----------------------------------------------------------------------
681 void Os2SalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
683 if( nFlags & SAL_INVERT_TRACKFRAME )
685 // save old vylues
686 LINEBUNDLE oldLb;
687 LINEBUNDLE lb;
688 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
690 // set linetype to short dash
691 lb.lColor = RGBCOLOR( 255, 255, 255 );
692 lb.usMixMode = FM_XOR;
693 lb.usType = LINETYPE_ALTERNATE;
694 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
696 // draw inverted box
697 POINTL aPt;
699 aPt.x = nX;
700 aPt.y = TY( nY );
702 Ft2Move( mhPS, &aPt );
704 aPt.x = nX + nWidth - 1;
705 aPt.y = TY( nY + nHeight - 1 );
707 Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 );
709 // restore old values
710 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
713 else
715 // save old values
716 AREABUNDLE oldAb;
717 AREABUNDLE ab;
719 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
721 // set fill color to black
722 ab.lColor = RGBCOLOR( 255, 255, 255 );
723 ab.usMixMode = FM_XOR;
724 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
725 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
727 // draw inverted box
728 POINTL aPt;
730 aPt.x = nX;
731 aPt.y = TY( nY );
733 Ft2Move( mhPS, &aPt );
735 aPt.x = nX + nWidth - 1;
736 aPt.y = TY( nY + nHeight - 1 );
738 Ft2Box( mhPS, DRO_FILL, &aPt, 0, 0 );
740 // restore old values
741 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );
745 // -----------------------------------------------------------------------
747 void Os2SalGraphics::invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags )
749 if( nFlags & SAL_INVERT_TRACKFRAME )
751 // save old vylues
752 LINEBUNDLE oldLb;
753 LINEBUNDLE lb;
754 GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
756 // set linetype to short dash
757 lb.lColor = RGBCOLOR( 255, 255, 255 );
758 lb.usMixMode = FM_XOR;
759 lb.usType = LINETYPE_ALTERNATE;
760 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
762 // Draw Polyline
763 drawPolyLine( nPoints, pPtAry );
765 // restore old values
766 Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
768 else
770 // save old values
771 AREABUNDLE oldAb;
772 AREABUNDLE ab;
774 GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
776 // set fill color to black
777 ab.lColor = RGBCOLOR( 255, 255, 255 );
778 ab.usMixMode = FM_XOR;
779 ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
780 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
782 // Draw Polyline
783 drawPolygon( nPoints, pPtAry );
785 // restore old values
786 Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );