diff options
Diffstat (limited to 'vcl/os2/source/gdi/salgdi2.cxx')
-rw-r--r-- | vcl/os2/source/gdi/salgdi2.cxx | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/vcl/os2/source/gdi/salgdi2.cxx b/vcl/os2/source/gdi/salgdi2.cxx new file mode 100644 index 000000000000..37621ee1f6a8 --- /dev/null +++ b/vcl/os2/source/gdi/salgdi2.cxx @@ -0,0 +1,786 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <string.h> +#include <svpm.h> + +#define _SV_SALGDI2_CXX +#include <salbmp.h> +#include <saldata.hxx> +#ifndef _SV_SALIDS_HRC +#include <salids.hrc> +#endif +#include <salgdi.h> +#include <salvd.h> +#include <vcl/salbtype.hxx> + +#ifndef __H_FT2LIB +#include <wingdi.h> +#include <ft2lib.h> +#endif + +BOOL bFastTransparent = FALSE; + +// ----------- +// - Defines - +// ----------- + +#define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16))) +#define TY( y ) (mnHeight-(y)-1) + +// --------------- +// - SalGraphics - +// --------------- + +bool Os2SalGraphics::supportsOperation( OutDevSupportType ) const +{ + return false; +} + + +void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) +{ + HPS hSrcPS; + POINTL thePoints[4]; + long nSrcHeight; + + if ( pSrcGraphics ) + { + //hSrcPS = pSrcGraphics->mhPS; + //nSrcHeight = pSrcGraphics->mnHeight; + hSrcPS = static_cast<Os2SalGraphics*>(pSrcGraphics)->mhPS; + nSrcHeight = static_cast<Os2SalGraphics*>(pSrcGraphics)->mnHeight; + } + else + { + hSrcPS = mhPS; + nSrcHeight = mnHeight; + } + + // lower-left corner of target + thePoints[0].x = pPosAry->mnDestX; + thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 ); + + // upper-right corner of target + thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth; + thePoints[1].y = TY( pPosAry->mnDestY - 1 ); + + // lower-left corner of source + thePoints[2].x = pPosAry->mnSrcX; + thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); + + if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) ) + { + // upper-right corner of Source + thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; + thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight; + + GpiBitBlt( mhPS, hSrcPS, 4, thePoints, + mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); + } + else + { + GpiBitBlt( mhPS, hSrcPS, 3, thePoints, + mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); + } +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::copyArea( long nDestX, long nDestY, + long nSrcX, long nSrcY, + long nSrcWidth, long nSrcHeight, + USHORT nFlags ) +{ + POINTL thePoints[3]; + + // lower-left corner of target + thePoints[0].x = nDestX; + thePoints[0].y = TY( nDestY + nSrcHeight - 1 ); + + // upper-right corner of target + thePoints[1].x = nDestX + nSrcWidth; + thePoints[1].y = TY( nDestY - 1 ); + + // lower-left corner of source + thePoints[2].x = nSrcX; + thePoints[2].y = TY( nSrcY + nSrcHeight - 1); + + if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow ) + { + // Overlap-Bereich berechnen und invalidieren + Point aVCLSrcPos( nSrcX, nSrcY ); + Size aVCLSrcSize( nSrcWidth, nSrcHeight ); + Rectangle aVCLSrcRect( aVCLSrcPos, aVCLSrcSize ); + Rectangle aVCLClipRect; + SWP aSWP; + + WinQueryWindowPos( mhWnd, &aSWP ); + aVCLClipRect.Right() = aSWP.cx-1; + aVCLClipRect.Bottom() = aSWP.cy-1; + if ( !aVCLSrcRect.Intersection( aVCLClipRect ).IsEmpty() ) + { + RECTL aSrcRect; + RECTL aTempRect; + HRGN hInvalidateRgn; + HRGN hTempRgn; + HWND hWnd; + long nRgnType; + + long nVCLScrHeight = aVCLSrcRect.GetHeight(); + aSrcRect.xLeft = aVCLSrcRect.Left(); + aSrcRect.yBottom = TY( aVCLSrcRect.Top()+nVCLScrHeight-1 ); + aSrcRect.xRight = aSrcRect.xLeft+aVCLSrcRect.GetWidth(); + aSrcRect.yTop = aSrcRect.yBottom+nVCLScrHeight; + + // Rechteck in Screen-Koordinaaten umrechnen + POINTL aPt; + long nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); + long nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); + aPt.x = 0; + aPt.y = 0; + WinMapWindowPoints( mhWnd, HWND_DESKTOP, &aPt, 1 ); + aSrcRect.xLeft += aPt.x; + aSrcRect.yTop += aPt.y; + aSrcRect.xRight += aPt.x; + aSrcRect.yBottom += aPt.y; + hInvalidateRgn = 0; + // Bereiche ausserhalb des sichtbaren Bereiches berechnen + if ( aSrcRect.xLeft < 0 ) + { + if ( !hInvalidateRgn ) + hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + aTempRect.xLeft = -31999; + aTempRect.yBottom = 0; + aTempRect.xRight = 0; + aTempRect.yTop = 31999; + hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); + GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + } + if ( aSrcRect.yBottom < 0 ) + { + if ( !hInvalidateRgn ) + hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + aTempRect.xLeft = 0; + aTempRect.yBottom = -31999; + aTempRect.xRight = 31999; + aTempRect.yTop = 0; + hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); + GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + } + if ( aSrcRect.xRight > nScreenDX ) + { + if ( !hInvalidateRgn ) + hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + aTempRect.xLeft = nScreenDX; + aTempRect.yBottom = 0; + aTempRect.xRight = 31999; + aTempRect.yTop = 31999; + hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); + GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + } + if ( aSrcRect.yTop > nScreenDY ) + { + if ( !hInvalidateRgn ) + hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + aTempRect.xLeft = 0; + aTempRect.yBottom = nScreenDY; + aTempRect.xRight = 31999; + aTempRect.yTop = 31999; + hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); + GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + } + + // Bereiche die von anderen Fenstern ueberlagert werden berechnen + // Calculate areas that are overlapped by other windows + HWND hWndParent = WinQueryWindow( mhWnd, QW_PARENT ); + hWnd = WinQueryWindow( HWND_DESKTOP, QW_TOP ); + aVCLSrcRect = Rectangle( aSrcRect.xLeft, aSrcRect.yBottom, aSrcRect.xRight, aSrcRect.yTop ); + while ( hWnd ) + { + if ( hWnd == hWndParent ) + break; + if ( WinIsWindowVisible( hWnd ) ) + { + WinQueryWindowPos( hWnd, &aSWP ); + if ( !(aSWP.fl & SWP_MINIMIZE) ) + { + aVCLClipRect = Rectangle( Point( aSWP.x, aSWP.y ), Size( aSWP.cx, aSWP.cy ) ); + if ( aVCLSrcRect.IsOver( aVCLClipRect ) ) + { + if ( !hInvalidateRgn ) + hInvalidateRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + aTempRect.xLeft = aSWP.x; + aTempRect.yBottom = aSWP.y; + aTempRect.xRight = aTempRect.xLeft+aSWP.cx; + aTempRect.yTop = aTempRect.yBottom+aSWP.cy; + hTempRgn = GpiCreateRegion( mhPS, 1, &aTempRect ); + GpiCombineRegion( mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + } + } + } + hWnd = WinQueryWindow( hWnd, QW_NEXT ); + } + + if ( hInvalidateRgn ) + { + hTempRgn = GpiCreateRegion( mhPS, 1, &aSrcRect ); + nRgnType = GpiCombineRegion( mhPS, hInvalidateRgn, hTempRgn, hInvalidateRgn, CRGN_DIFF ); + GpiDestroyRegion( mhPS, hTempRgn ); + if ( (nRgnType != RGN_ERROR) && (nRgnType != RGN_NULL) ) + { + long nOffX = (nDestX-nSrcX); + long nOffY = (nSrcY-nDestY); + aPt.x = nOffX-aPt.x; + aPt.y = nOffY-aPt.y; + GpiOffsetRegion( mhPS, hInvalidateRgn, &aPt ); + WinInvalidateRegion( mhWnd, hInvalidateRgn, TRUE ); + // Hier loesen wir nur ein Update aus, wenn es der + // MainThread ist, damit es beim Bearbeiten der + // Paint-Message keinen Deadlock gibt, da der + // SolarMutex durch diesen Thread schon gelockt ist + SalData* pSalData = GetSalData(); + ULONG nCurThreadId = GetCurrentThreadId(); + if ( pSalData->mnAppThreadId == nCurThreadId ) + WinUpdateWindow( mhWnd ); + } + GpiDestroyRegion( mhPS, hInvalidateRgn ); + } + } + } + + GpiBitBlt( mhPS, mhPS, 3, thePoints, + ROP_SRCCOPY, BBO_IGNORE ); + +} + +// ----------------------------------------------------------------------- + +void ImplDrawBitmap( HPS hPS, long nScreenHeight, + const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap, + BOOL bPrinter, int nDrawMode ) +{ + if( hPS ) + { + HANDLE hDrawDIB; + HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); + Os2SalBitmap* pTmpSalBmp = NULL; + BOOL bPrintDDB = ( bPrinter && hDrawDDB ); + BOOL bDrawDDB1 = ( ( rSalBitmap.GetBitCount() == 1 ) && hDrawDDB ); + + if( bPrintDDB || bDrawDDB1 ) + { + pTmpSalBmp = new Os2SalBitmap; + pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() ); + hDrawDIB = pTmpSalBmp->ImplGethDIB(); + } + else + hDrawDIB = rSalBitmap.ImplGethDIB(); + + if( hDrawDIB ) + { + HANDLE hSubst = rSalBitmap.ImplGethDIB1Subst(); + POINTL pts[ 4 ]; + BITMAPINFO2* pBI = (BITMAPINFO2*) hDrawDIB; + BITMAPINFOHEADER2* pBIH = (BITMAPINFOHEADER2*) pBI; + const long nHeight = pBIH->cy; + long nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 ); + BYTE* pBits = (BYTE*) pBI + nInfoSize; + + pts[0].x = pPosAry->mnDestX; + pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; + pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; + pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; + + pts[2].x = pPosAry->mnSrcX; + pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); + pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; + pts[3].y = nHeight - pPosAry->mnSrcY; + + // if we've got a 1Bit DIB, we create a 4Bit substitute + if( ( pBIH->cBitCount == 1 ) && !hSubst ) + { + // create 4Bit substitute + hSubst = Os2SalBitmap::ImplCreateDIB4FromDIB1( hDrawDIB ); + + // replace substitute only, if it is no temporary SalBitmap + if( !( bPrintDDB || bDrawDDB1 ) ) + ( (Os2SalBitmap&) rSalBitmap ).ImplReplacehDIB1Subst( hSubst ); + } + + if( hSubst ) + { + pBI = (BITMAPINFO2*) hSubst; + pBIH = (BITMAPINFOHEADER2*) pBI; + nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hSubst ) * sizeof( RGB2 ); + pBits = (BYTE*) pBI + nInfoSize; + } + + if( bPrinter ) + { + BYTE* pDummy; + + // expand 8Bit-DIB's to 24Bit-DIB's, because some printer drivers + // have problems to print these DIB's (strange) + if( pBIH->cBitCount == 8 && pBIH->ulCompression == BCA_UNCOMP ) + { + const long nWidth = pBIH->cx; + const long nHeight = pBIH->cy; + const long nWidthAl8 = AlignedWidth4Bytes( nWidth * 8 ); + const long nWidthAl24 = AlignedWidth4Bytes( nWidth * 24 ); + const long nNewImageSize = nHeight * nWidthAl24; + BITMAPINFOHEADER2* pNewInfo; + + pDummy = new BYTE[ sizeof( BITMAPINFO2 ) + nNewImageSize ]; + memset( pDummy, 0, sizeof( BITMAPINFO2 ) ); + + pNewInfo = (BITMAPINFOHEADER2*) pDummy; + pNewInfo->cbFix = sizeof( BITMAPINFOHEADER2 ); + pNewInfo->cx = nWidth; + pNewInfo->cy = nHeight; + pNewInfo->cPlanes = 1; + pNewInfo->cBitCount = 24; + pNewInfo->ulCompression = BCA_UNCOMP; + pNewInfo->cbImage = nNewImageSize; + + BYTE* pBitsSrc = (BYTE*) pBIH + nInfoSize; + BYTE* pBitsDst = pDummy + sizeof( BITMAPINFO2 ); + + for( long nY = 0UL; nY < nHeight; nY++ ) + { + BYTE* pSrcLine = pBitsSrc + nY * nWidthAl8; + BYTE* pDstLine = pBitsDst + nY * nWidthAl24; + + for( long nX = 0UL; nX < nWidth; nX++ ) + { + const RGB2& rQuad = pBI->argbColor[ *pSrcLine++ ]; + + *pDstLine++ = rQuad.bBlue; + *pDstLine++ = rQuad.bGreen; + *pDstLine++ = rQuad.bRed; + } + } + + nInfoSize = sizeof( BITMAPINFO2 ); + } + else + { + const long nImageSize = ( pBIH->cbImage ? pBIH->cbImage : ( pBIH->cy * AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ) ); + const long nTotalSize = nInfoSize + nImageSize; + + pDummy = new BYTE[ nTotalSize ]; + memcpy( pDummy, pBI, nTotalSize ); + } + + GpiDrawBits( hPS, pDummy + nInfoSize, (BITMAPINFO2*) pDummy, 4L, pts, nDrawMode, BBO_IGNORE ); + delete[] pDummy; + } + else + GpiDrawBits( hPS, pBits, pBI, 4L, pts, nDrawMode, BBO_IGNORE ); + } + else if( hDrawDDB && !bPrintDDB ) + { + POINTL pts[ 4 ]; + + pts[0].x = pPosAry->mnDestX; + pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; + pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; + pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; + + pts[2].x = pPosAry->mnSrcX; + pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); + pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; + pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY; + + GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE ); +/* + HPS hDrawPS = ImplGetCachedPS( CACHED_HPS_DRAW, hDrawDDB ); + Ft2BitBlt( hPS, hDrawPS, 4, pts, nDrawMode, BBO_IGNORE ); + ImplReleaseCachedPS( CACHED_HPS_DRAW ); +*/ + } + + if( bPrintDDB || bDrawDDB1 ) + delete pTmpSalBmp; + } +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap ) +{ + ImplDrawBitmap( mhPS, mnHeight, + pPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap), + mbPrinter, + mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY ); +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nTransparentColor ) +{ + DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); + //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); + // an FM: kann erst einmal unberuecksichtigt bleiben + drawBitmap( pPosAry, rSalBitmap ); +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSSalBitmap, + const SalBitmap& rSTransparentBitmap ) +{ + DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); + + const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); + const Os2SalBitmap& rTransparentBitmap = static_cast<const Os2SalBitmap&>(rSTransparentBitmap); + + if( bFastTransparent ) + { + ImplDrawBitmap( mhPS, mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND ); + ImplDrawBitmap( mhPS, mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT ); + } + else + { + SalTwoRect aPosAry = *pPosAry; + int nDstX = (int) aPosAry.mnDestX; + int nDstY = (int) aPosAry.mnDestY; + int nDstWidth = (int) aPosAry.mnDestWidth; + int nDstHeight = (int) aPosAry.mnDestHeight; + HAB hAB = GetSalData()->mhAB; + HPS hPS = mhPS; + DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + SIZEL aSizeL = { nDstWidth, nDstHeight }; + POINTL aPtL[ 3 ]; + + HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); + HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); + HBITMAP hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 ); + HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, hMemBitmap ); + HDC hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); + HPS hMaskPS = Ft2CreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); + HBITMAP hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 ); + HBITMAP hMaskOld = (HBITMAP) Ft2SetBitmap( hMaskPS, hMaskBitmap ); +/* + HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 ); + HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 ); +*/ + aPosAry.mnDestX = aPosAry.mnDestY = 0L; + + aPtL[ 0 ].x = 0; + aPtL[ 0 ].y = 0; + aPtL[ 1 ].x = nDstWidth; + aPtL[ 1 ].y = nDstHeight; + aPtL[ 2 ].x = nDstX; + aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 ); + + GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); + ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY ); + + aPtL[ 2 ].x = 0; + aPtL[ 2 ].y = 0; + + GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE ); + ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE ); + GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE ); + + aPtL[ 0 ].x = nDstX; + aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 ); + aPtL[ 1 ].x = nDstX + nDstWidth; + aPtL[ 1 ].y = TY( nDstY - 1 ); + + GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); + + Ft2SetBitmap( hMaskPS, hMaskOld ); + Ft2DestroyPS( hMaskPS ); + DevCloseDC( hMaskDC ); + GpiDeleteBitmap( hMaskBitmap ); + + Ft2SetBitmap( hMemPS, hMemOld ); + Ft2DestroyPS( hMemPS ); + DevCloseDC( hMemDC ); + GpiDeleteBitmap( hMemBitmap ); + +/* + ImplReleaseCachedPS( CACHED_HPS_1 ); + ImplReleaseCachedPS( CACHED_HPS_2 ); +*/ + } +} + +// ----------------------------------------------------------------------- + +bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, + const SalBitmap& rSrcBitmap, + const SalBitmap& rAlphaBmp ) +{ + // TODO(P3) implement alpha blending + return false; +} + +// ----------------------------------------------------------------------- + +bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, + long nHeight, sal_uInt8 nTransparency ) +{ + // TODO(P3) implement alpha blending + return false; +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry, + const SalBitmap& rSSalBitmap, + SalColor nMaskColor ) +{ + DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); + + const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); + + SalTwoRect aPosAry = *pPosAry; + HPS hPS = mhPS; + IMAGEBUNDLE aBundle, aOldBundle; + AREABUNDLE aAreaBundle, aOldAreaBundle; + const ULONG nColor = RGBCOLOR( SALCOLOR_RED( nMaskColor ), + SALCOLOR_GREEN( nMaskColor ), + SALCOLOR_BLUE( nMaskColor ) ); + + GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle ); + aBundle.lColor = RGBCOLOR( 0, 0, 0 ); + aBundle.lBackColor = RGBCOLOR( 0xFF, 0xFF, 0xFF ); + Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle ); + + GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | + ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle ); + aAreaBundle.lColor = nColor; + aAreaBundle.lBackColor = nColor; + aAreaBundle.usSymbol = PATSYM_SOLID; + aAreaBundle.usMixMode = FM_OVERPAINT; + aAreaBundle.usBackMixMode = BM_OVERPAINT; + Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | + ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle ); + + ImplDrawBitmap( hPS, mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L ); + + Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle ); + Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | + ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle ); +} + +// ----------------------------------------------------------------------- + +SalBitmap* Os2SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) +{ + HAB hAB = GetSalData()->mhAB; + SIZEL size = { nDX, nDY }; + Os2SalBitmap* pSalBitmap = NULL; + + // create device context (at this time allways display compatible) + DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); + HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); + HBITMAP hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 ); + HBITMAP hMemOld = Ft2SetBitmap( hMemPS, hMemBmp ); + + // creation successfull? + if( hMemDC && hMemPS && hMemBmp ) + { + POINTL thePoints[ 3 ]; + + // lower-left corner of target + thePoints[ 0 ].x = 0; + thePoints[ 0 ].y = 0; + + // upper-right corner of target + thePoints[ 1 ].x = nDX; + thePoints[ 1 ].y = nDY; + + // lower-left corner of source + thePoints[ 2 ].x = nX; + thePoints[ 2 ].y = TY( nY + nDY - 1 ); + + long lHits = GpiBitBlt( hMemPS, mhPS, 3, thePoints, + mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); + + if( hMemPS ) + { + Ft2SetBitmap( hMemPS, hMemOld ); + Ft2DestroyPS( hMemPS ); + } + + if( hMemDC ) + DevCloseDC( hMemDC ); + + if( lHits == GPI_OK ) + { + pSalBitmap = new Os2SalBitmap; + + if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) ) + { + delete pSalBitmap; + pSalBitmap = NULL; + } + } + } + + if( !pSalBitmap ) + GpiDeleteBitmap( hMemBmp ); + + // return pointer to SAL-Bitmap + return pSalBitmap; +} + +// ----------------------------------------------------------------------- + +SalColor Os2SalGraphics::getPixel( long nX, long nY ) +{ + POINTL aPt = { nX, TY( nY ) }; + LONG nColor = Ft2QueryPel( mhPS, &aPt ); + + return MAKE_SALCOLOR( (BYTE) ( nColor >> 16 ), (BYTE) ( nColor >> 8 ), (BYTE) nColor ); +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) +{ + if( nFlags & SAL_INVERT_TRACKFRAME ) + { + // save old vylues + LINEBUNDLE oldLb; + LINEBUNDLE lb; + GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); + + // set linetype to short dash + lb.lColor = RGBCOLOR( 255, 255, 255 ); + lb.usMixMode = FM_XOR; + lb.usType = LINETYPE_ALTERNATE; + Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); + + // draw inverted box + POINTL aPt; + + aPt.x = nX; + aPt.y = TY( nY ); + + Ft2Move( mhPS, &aPt ); + + aPt.x = nX + nWidth - 1; + aPt.y = TY( nY + nHeight - 1 ); + + Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 ); + + // restore old values + Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); + + } + else + { + // save old values + AREABUNDLE oldAb; + AREABUNDLE ab; + + GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); + + // set fill color to black + ab.lColor = RGBCOLOR( 255, 255, 255 ); + ab.usMixMode = FM_XOR; + ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; + Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); + + // draw inverted box + POINTL aPt; + + aPt.x = nX; + aPt.y = TY( nY ); + + Ft2Move( mhPS, &aPt ); + + aPt.x = nX + nWidth - 1; + aPt.y = TY( nY + nHeight - 1 ); + + Ft2Box( mhPS, DRO_FILL, &aPt, 0, 0 ); + + // restore old values + Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); + } +} + +// ----------------------------------------------------------------------- + +void Os2SalGraphics::invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags ) +{ + if( nFlags & SAL_INVERT_TRACKFRAME ) + { + // save old vylues + LINEBUNDLE oldLb; + LINEBUNDLE lb; + GpiQueryAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb ); + + // set linetype to short dash + lb.lColor = RGBCOLOR( 255, 255, 255 ); + lb.usMixMode = FM_XOR; + lb.usType = LINETYPE_ALTERNATE; + Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb ); + + // Draw Polyline + drawPolyLine( nPoints, pPtAry ); + + // restore old values + Ft2SetAttrs( mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb ); + } + else + { + // save old values + AREABUNDLE oldAb; + AREABUNDLE ab; + + GpiQueryAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb ); + + // set fill color to black + ab.lColor = RGBCOLOR( 255, 255, 255 ); + ab.usMixMode = FM_XOR; + ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID; + Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab ); + + // Draw Polyline + drawPolygon( nPoints, pPtAry ); + + // restore old values + Ft2SetAttrs( mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb ); + } +} + |