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