1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salgdi2.cxx,v $
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 ************************************************************************/
34 #define _SV_SALGDI2_CXX
36 #include <saldata.hxx>
37 #ifndef _SV_SALIDS_HRC
42 #include <vcl/salbtype.hxx>
49 BOOL bFastTransparent
= FALSE
;
55 #define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16)))
56 #define TY( y ) (mnHeight-(y)-1)
62 bool Os2SalGraphics::supportsOperation( OutDevSupportType
) const
68 void Os2SalGraphics::copyBits( const SalTwoRect
* pPosAry
, SalGraphics
* pSrcGraphics
)
76 //hSrcPS = pSrcGraphics->mhPS;
77 //nSrcHeight = pSrcGraphics->mnHeight;
78 hSrcPS
= static_cast<Os2SalGraphics
*>(pSrcGraphics
)->mhPS
;
79 nSrcHeight
= static_cast<Os2SalGraphics
*>(pSrcGraphics
)->mnHeight
;
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
);
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
,
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
;
145 WinQueryWindowPos( mhWnd
, &aSWP
);
146 aVCLClipRect
.Right() = aSWP
.cx
-1;
147 aVCLClipRect
.Bottom() = aSWP
.cy
-1;
148 if ( !aVCLSrcRect
.Intersection( aVCLClipRect
).IsEmpty() )
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
165 long nScreenDX
= WinQuerySysValue( HWND_DESKTOP
, SV_CXSCREEN
);
166 long nScreenDY
= WinQuerySysValue( HWND_DESKTOP
, SV_CYSCREEN
);
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
;
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
);
193 aTempRect
.yBottom
= -31999;
194 aTempRect
.xRight
= 31999;
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
);
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
);
232 if ( hWnd
== hWndParent
)
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
);
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
)
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();
310 hDrawDIB
= rSalBitmap
.ImplGethDIB();
314 HANDLE hSubst
= rSalBitmap
.ImplGethDIB1Subst();
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
);
345 pBI
= (BITMAPINFO2
*) hSubst
;
346 pBIH
= (BITMAPINFOHEADER2
*) pBI
;
347 nInfoSize
= *(ULONG
*) pBI
+ rSalBitmap
.ImplGetDIBColorCount( hSubst
) * sizeof( RGB2
);
348 pBits
= (BYTE
*) pBI
+ nInfoSize
;
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
);
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
);
411 GpiDrawBits( hPS
, pBits
, pBI
, 4L, pts
, nDrawMode
, BBO_IGNORE
);
413 else if( hDrawDDB
&& !bPrintDDB
)
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
)
440 // -----------------------------------------------------------------------
442 void Os2SalGraphics::drawBitmap( const SalTwoRect
* pPosAry
,
443 const SalBitmap
& rSalBitmap
)
445 ImplDrawBitmap( mhPS
, mnHeight
,
446 pPosAry
, static_cast<const Os2SalBitmap
&>(rSalBitmap
),
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
);
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
;
488 DEVOPENSTRUC aDevOpenStruc
= { NULL
, (PSZ
)"DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
489 SIZEL aSizeL
= { nDstWidth
, nDstHeight
};
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;
508 aPtL
[ 1 ].x
= nDstWidth
;
509 aPtL
[ 1 ].y
= nDstHeight
;
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
);
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
);
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
557 // -----------------------------------------------------------------------
559 bool Os2SalGraphics::drawAlphaRect( long nX
, long nY
, long nWidth
,
560 long nHeight
, sal_uInt8 nTransparency
)
562 // TODO(P3) implement alpha blending
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
;
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
);
643 Ft2SetBitmap( hMemPS
, hMemOld
);
644 Ft2DestroyPS( hMemPS
);
648 DevCloseDC( hMemDC
);
650 if( lHits
== GPI_OK
)
652 pSalBitmap
= new Os2SalBitmap
;
654 if( !pSalBitmap
->Create( hMemBmp
, FALSE
, FALSE
) )
663 GpiDeleteBitmap( hMemBmp
);
665 // return pointer to SAL-Bitmap
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
)
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
);
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
);
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
);
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
)
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
);
763 drawPolyLine( nPoints
, pPtAry
);
765 // restore old values
766 Ft2SetAttrs( mhPS
, PRIM_LINE
, LBB_MIX_MODE
| LBB_TYPE
| LBB_COLOR
, 0, &oldLb
);
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
);
783 drawPolygon( nPoints
, pPtAry
);
785 // restore old values
786 Ft2SetAttrs( mhPS
, PRIM_AREA
, ABB_COLOR
| ABB_MIX_MODE
| ABB_SYMBOL
, 0, &oldAb
);