diff options
Diffstat (limited to 'vcl/win/source/gdi/salgdi2.cxx')
-rw-r--r-- | vcl/win/source/gdi/salgdi2.cxx | 728 |
1 files changed, 13 insertions, 715 deletions
diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx index 16f262fa41c6..f00945164f3e 100644 --- a/vcl/win/source/gdi/salgdi2.cxx +++ b/vcl/win/source/gdi/salgdi2.cxx @@ -33,6 +33,7 @@ #include "vcl/salbtype.hxx" #include "vcl/bmpacc.hxx" #include "outdata.hxx" +#include "salgdiimpl.hxx" bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const { @@ -56,82 +57,7 @@ bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { - HDC hSrcDC; - DWORD nRop; - - if ( pSrcGraphics ) - hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC(); - else - hSrcDC = getHDC(); - - if ( mbXORMode ) - nRop = SRCINVERT; - else - nRop = SRCCOPY; - - if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && - (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) - { - BitBlt( getHDC(), - (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, - (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, - hSrcDC, - (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, - nRop ); - } - else - { - int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS ); - StretchBlt( getHDC(), - (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, - (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, - hSrcDC, - (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, - (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, - nRop ); - SetStretchBltMode( getHDC(), nOldStretchMode ); - } -} - -void ImplCalcOutSideRgn( const RECT& rSrcRect, - int nLeft, int nTop, int nRight, int nBottom, - HRGN& rhInvalidateRgn ) -{ - HRGN hTempRgn; - - // calculate area outside the visible region - if ( rSrcRect.left < nLeft ) - { - if ( !rhInvalidateRgn ) - rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); - hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 ); - CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - } - if ( rSrcRect.top < nTop ) - { - if ( !rhInvalidateRgn ) - rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); - hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop ); - CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - } - if ( rSrcRect.right > nRight ) - { - if ( !rhInvalidateRgn ) - rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); - hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 ); - CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - } - if ( rSrcRect.bottom > nBottom ) - { - if ( !rhInvalidateRgn ) - rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect ); - hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 ); - CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - } + mpImpl->copyBits( rPosAry, pSrcGraphics ); } void WinSalGraphics::copyArea( long nDestX, long nDestY, @@ -139,688 +65,60 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ) { - bool bRestoreClipRgn = false; - HRGN hOldClipRgn = 0; - int nOldClipRgnType = ERROR; - HRGN hInvalidateRgn = 0; - - // do we have to invalidate also the overlapping regions? - if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow ) - { - // compute and invalidate those parts that were either off-screen or covered by other windows - // while performing the above BitBlt - // those regions then have to be invalidated as they contain useless/wrong data - RECT aSrcRect; - RECT aClipRect; - RECT aTempRect; - RECT aTempRect2; - HRGN hTempRgn; - HWND hWnd; - - // restrict srcRect to this window (calc intersection) - aSrcRect.left = (int)nSrcX; - aSrcRect.top = (int)nSrcY; - aSrcRect.right = aSrcRect.left+(int)nSrcWidth; - aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight; - GetClientRect( mhWnd, &aClipRect ); - if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) ) - { - // transform srcRect to screen coordinates - POINT aPt; - aPt.x = 0; - aPt.y = 0; - ClientToScreen( mhWnd, &aPt ); - aSrcRect.left += aPt.x; - aSrcRect.top += aPt.y; - aSrcRect.right += aPt.x; - aSrcRect.bottom += aPt.y; - hInvalidateRgn = 0; - - // compute the parts that are off screen (ie invisible) - RECT theScreen; - ImplSalGetWorkArea( NULL, &theScreen, NULL ); // find the screen area taking multiple monitors into account - ImplCalcOutSideRgn( aSrcRect, theScreen.left, theScreen.top, theScreen.right, theScreen.bottom, hInvalidateRgn ); - - // calculate regions that are covered by other windows - HRGN hTempRgn2 = 0; - HWND hWndTopWindow = mhWnd; - // Find the TopLevel Window, because only Windows which are in - // in the foreground of our TopLevel window must be considered - if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD ) - { - RECT aTempRect3 = aSrcRect; - do - { - hWndTopWindow = ::GetParent( hWndTopWindow ); - - // Test if the Parent clips our window - GetClientRect( hWndTopWindow, &aTempRect ); - POINT aPt2; - aPt2.x = 0; - aPt2.y = 0; - ClientToScreen( hWndTopWindow, &aPt2 ); - aTempRect.left += aPt2.x; - aTempRect.top += aPt2.y; - aTempRect.right += aPt2.x; - aTempRect.bottom += aPt2.y; - IntersectRect( &aTempRect3, &aTempRect3, &aTempRect ); - } - while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD ); - - // If one or more Parents clip our window, than we must - // calculate the outside area - if ( !EqualRect( &aSrcRect, &aTempRect3 ) ) - { - ImplCalcOutSideRgn( aSrcRect, - aTempRect3.left, aTempRect3.top, - aTempRect3.right, aTempRect3.bottom, - hInvalidateRgn ); - } - } - // retrieve the top-most (z-order) child window - hWnd = GetWindow( GetDesktopWindow(), GW_CHILD ); - while ( hWnd ) - { - if ( hWnd == hWndTopWindow ) - break; - if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) ) - { - GetWindowRect( hWnd, &aTempRect ); - if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) ) - { - // hWnd covers part or all of aSrcRect - if ( !hInvalidateRgn ) - hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect ); - - // get full bounding box of hWnd - hTempRgn = CreateRectRgnIndirect( &aTempRect ); - - // get region of hWnd (the window may be shaped) - if ( !hTempRgn2 ) - hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 ); - int nRgnType = GetWindowRgn( hWnd, hTempRgn2 ); - if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) ) - { - // convert window region to screen coordinates - OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top ); - // and intersect with the window's bounding box - CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND ); - } - // finally compute that part of aSrcRect which is not covered by any parts of hWnd - CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - } - } - // retrieve the next window in the z-order, i.e. the window below hwnd - hWnd = GetWindow( hWnd, GW_HWNDNEXT ); - } - if ( hTempRgn2 ) - DeleteRegion( hTempRgn2 ); - if ( hInvalidateRgn ) - { - // hInvalidateRgn contains the fully visible parts of the original srcRect - hTempRgn = CreateRectRgnIndirect( &aSrcRect ); - // substract it from the original rect to get the occluded parts - int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF ); - DeleteRegion( hTempRgn ); - - if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) ) - { - // move the occluded parts to the destination pos - int nOffX = (int)(nDestX-nSrcX); - int nOffY = (int)(nDestY-nSrcY); - OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y ); - - // by excluding hInvalidateRgn from the system's clip region - // we will prevent bitblt from copying useless data - // epsecially now shadows from overlapping windows will appear (#i36344) - hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 ); - nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn ); - - bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate - ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF ); - } - } - } - } - - BitBlt( getHDC(), - (int)nDestX, (int)nDestY, - (int)nSrcWidth, (int)nSrcHeight, - getHDC(), - (int)nSrcX, (int)nSrcY, - SRCCOPY ); - - if( bRestoreClipRgn ) - { - // restore old clip region - if( nOldClipRgnType != ERROR ) - SelectClipRgn( getHDC(), hOldClipRgn); - DeleteRegion( hOldClipRgn ); - - // invalidate regions that were not copied - bool bInvalidate = true; - - // Combine Invalidate vcl::Region with existing ClipRegion - HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 ); - if ( GetClipRgn( getHDC(), hTempRgn ) == 1 ) - { - int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND ); - if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) ) - bInvalidate = false; - } - DeleteRegion( hTempRgn ); - - if ( bInvalidate ) - { - InvalidateRgn( mhWnd, hInvalidateRgn, TRUE ); - // here we only initiate an update if this is the MainThread, - // so that there is no deadlock when handling the Paint event, - // as the SolarMutex is already held by this Thread - SalData* pSalData = GetSalData(); - DWORD nCurThreadId = GetCurrentThreadId(); - if ( pSalData->mnAppThreadId == nCurThreadId ) - UpdateWindow( mhWnd ); - } - - DeleteRegion( hInvalidateRgn ); - } - -} - -void ImplDrawBitmap( HDC hDC, - const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap, - bool bPrinter, int nDrawMode ) -{ - if( hDC ) - { - HGLOBAL hDrawDIB; - HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); - WinSalBitmap* pTmpSalBmp = NULL; - bool bPrintDDB = ( bPrinter && hDrawDDB ); - - if( bPrintDDB ) - { - pTmpSalBmp = new WinSalBitmap; - pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() ); - hDrawDIB = pTmpSalBmp->ImplGethDIB(); - } - else - hDrawDIB = rSalBitmap.ImplGethDIB(); - - if( hDrawDIB ) - { - PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB ); - PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI; - PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI + - rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD ); - const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); - - StretchDIBits( hDC, - (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, - (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, - (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY), - (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, - pBits, pBI, DIB_RGB_COLORS, nDrawMode ); - - GlobalUnlock( hDrawDIB ); - SetStretchBltMode( hDC, nOldStretchMode ); - } - else if( hDrawDDB && !bPrintDDB ) - { - HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB ); - COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF); - COLORREF nOldTextColor = RGB(0,0,0); - bool bMono = ( rSalBitmap.GetBitCount() == 1 ); - - if( bMono ) - { - COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF ); - COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 ); - //fdo#33455 handle 1 bit depth pngs with palette entries - //to set fore/back colors - if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(true)) - { - const BitmapPalette& rPalette = pBitmapBuffer->maPalette; - if (rPalette.GetEntryCount() == 2) - { - SalColor nCol; - nCol = ImplColorToSal(rPalette[0]); - nTextColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) ); - nCol = ImplColorToSal(rPalette[1]); - nBkColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) ); - } - } - nOldBkColor = SetBkColor( hDC, nBkColor ); - nOldTextColor = ::SetTextColor( hDC, nTextColor ); - } - - if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && - (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) - { - BitBlt( hDC, - (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, - (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, - hBmpDC, - (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, - nDrawMode ); - } - else - { - const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); - - StretchBlt( hDC, - (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, - (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, - hBmpDC, - (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, - (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, - nDrawMode ); - - SetStretchBltMode( hDC, nOldStretchMode ); - } - - if( bMono ) - { - SetBkColor( hDC, nOldBkColor ); - ::SetTextColor( hDC, nOldTextColor ); - } - - ImplReleaseCachedDC( CACHED_HDC_DRAW ); - } - - if( bPrintDDB ) - delete pTmpSalBmp; - } + mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY, + nSrcWidth, nSrcHeight, nFlags ); } void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) { - bool bTryDirectPaint(!mbPrinter && !mbXORMode); - - if(bTryDirectPaint) - { - // only paint direct when no scaling and no MapMode, else the - // more expensive conversions may be done for short-time Bitmap/BitmapEx - // used for buffering only - if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) - { - bTryDirectPaint = false; - } - } - - // try to draw using GdiPlus directly - if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap)) - { - return; - } - - // fall back old stuff - ImplDrawBitmap(getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), - mbPrinter, - mbXORMode ? SRCINVERT : SRCCOPY ); + mpImpl->drawBitmap( rPosAry, rSalBitmap ); } void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nTransparentColor ) { - DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); - - const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - - WinSalBitmap* pMask = new WinSalBitmap; - const Point aPoint; - const Size aSize( rSalBitmap.GetSize() ); - HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL ); - HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap ); - const BYTE cRed = SALCOLOR_RED( nTransparentColor ); - const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor ); - const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor ); - - if( rSalBitmap.ImplGethDDB() ) - { - HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() ); - COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); - - BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); - - SetBkColor( hSrcDC, aOldCol ); - ImplReleaseCachedDC( CACHED_HDC_2 ); - } - else - { - WinSalBitmap* pTmpSalBmp = new WinSalBitmap; - - if( pTmpSalBmp->Create( rSalBitmap, this ) ) - { - HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() ); - COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) ); - - BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY ); - - SetBkColor( hSrcDC, aOldCol ); - ImplReleaseCachedDC( CACHED_HDC_2 ); - } - - delete pTmpSalBmp; - } - - ImplReleaseCachedDC( CACHED_HDC_1 ); - - // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE ) - if( pMask->Create( hMaskBitmap, FALSE, FALSE ) ) - drawBitmap( rPosAry, rSalBitmap, *pMask ); - - delete pMask; + mpImpl->drawBitmap( rPosAry, rSSalBitmap, nTransparentColor ); } void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, const SalBitmap& rSTransparentBitmap ) { - DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); - bool bTryDirectPaint(!mbPrinter && !mbXORMode); - - if(bTryDirectPaint) - { - // only paint direct when no scaling and no MapMode, else the - // more expensive conversions may be done for short-time Bitmap/BitmapEx - // used for buffering only - if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) - { - bTryDirectPaint = false; - } - } - - // try to draw using GdiPlus directly - if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap)) - { - return; - } - - const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap); - - SalTwoRect aPosAry = rPosAry; - int nDstX = (int)aPosAry.mnDestX; - int nDstY = (int)aPosAry.mnDestY; - int nDstWidth = (int)aPosAry.mnDestWidth; - int nDstHeight = (int)aPosAry.mnDestHeight; - HDC hDC = getHDC(); - HBITMAP hMemBitmap = 0; - HBITMAP hMaskBitmap = 0; - - if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) ) - { - hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); - hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight ); - } - - HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap ); - HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap ); - - aPosAry.mnDestX = aPosAry.mnDestY = 0; - BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY ); - - // WIN/WNT seems to have a minor problem mapping the correct color of the - // mask to the palette if we draw the DIB directly ==> draw DDB - if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 ) - { - WinSalBitmap aTmp; - - if( aTmp.Create( rTransparentBitmap, this ) ) - ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY ); - } - else - ImplDrawBitmap( hMaskDC, aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); - - // now MemDC contains background, MaskDC the transparency mask - - // #105055# Respect XOR mode - if( mbXORMode ) - { - ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); - // now MaskDC contains the bitmap area with black background - BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT ); - // now MemDC contains background XORed bitmap area ontop - } - else - { - BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND ); - // now MemDC contains background with masked-out bitmap area - ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); - // now MaskDC contains the bitmap area with black background - BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT ); - // now MemDC contains background and bitmap merged together - } - // copy to output DC - BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY ); - - ImplReleaseCachedDC( CACHED_HDC_1 ); - ImplReleaseCachedDC( CACHED_HDC_2 ); - - // hMemBitmap != 0 ==> hMaskBitmap != 0 - if( hMemBitmap ) - { - DeleteObject( hMemBitmap ); - DeleteObject( hMaskBitmap ); - } + mpImpl->drawBitmap( rPosAry, rSSalBitmap, rSTransparentBitmap ); } bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { - if( mbPen || !mbBrush || mbXORMode ) - return false; // can only perform solid fills without XOR. - - HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 ); - SetPixel( hMemDC, (int)0, (int)0, mnBrushColor ); - - BLENDFUNCTION aFunc = { - AC_SRC_OVER, - 0, - sal::static_int_cast<sal_uInt8>(255 - 255L*nTransparency/100), - 0 - }; - - // hMemDC contains a 1x1 bitmap of the right color - stretch-blit - // that to dest hdc - bool bRet = AlphaBlend( getHDC(), nX, nY, nWidth, nHeight, - hMemDC, 0,0,1,1, - aFunc ) == TRUE; - - ImplReleaseCachedDC( CACHED_HDC_1 ); - - return bRet; + return mpImpl->drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency ); } void WinSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nMaskColor ) { - DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); - - const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - - SalTwoRect aPosAry = rPosAry; - const BYTE cRed = SALCOLOR_RED( nMaskColor ); - const BYTE cGreen = SALCOLOR_GREEN( nMaskColor ); - const BYTE cBlue = SALCOLOR_BLUE( nMaskColor ); - HDC hDC = getHDC(); - HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) ); - HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush ); - - // WIN/WNT seems to have a minor problem mapping the correct color of the - // mask to the palette if we draw the DIB directly ==> draw DDB - if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 ) - { - WinSalBitmap aTmp; - - if( aTmp.Create( rSalBitmap, this ) ) - ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL ); - } - else - ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); - - SelectBrush( hDC, hOldBrush ); - DeleteBrush( hMaskBrush ); + mpImpl->drawMask( rPosAry, rSSalBitmap, nMaskColor ); } SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) { - DBG_ASSERT( !mbPrinter, "No ::GetBitmap() from printer possible!" ); - - WinSalBitmap* pSalBitmap = NULL; - - nDX = labs( nDX ); - nDY = labs( nDY ); - - HDC hDC = getHDC(); - HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); - HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); - bool bRet; - - bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE; - ImplReleaseCachedDC( CACHED_HDC_1 ); - - if( bRet ) - { - pSalBitmap = new WinSalBitmap; - - if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) ) - { - delete pSalBitmap; - pSalBitmap = NULL; - } - } - else - { - // #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers) - DeleteBitmap( hBmpBitmap ); - } - - return pSalBitmap; + return mpImpl->getBitmap( nX, nY, nDX, nDY ); } SalColor WinSalGraphics::getPixel( long nX, long nY ) { - COLORREF aWinCol = ::GetPixel( getHDC(), (int) nX, (int) nY ); - - if ( CLR_INVALID == aWinCol ) - return MAKE_SALCOLOR( 0, 0, 0 ); - else - return MAKE_SALCOLOR( GetRValue( aWinCol ), - GetGValue( aWinCol ), - GetBValue( aWinCol ) ); + return mpImpl->getPixel( nX, nY ); } void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) { - if ( nFlags & SAL_INVERT_TRACKFRAME ) - { - HPEN hDotPen = CreatePen( PS_DOT, 0, 0 ); - HPEN hOldPen = SelectPen( getHDC(), hDotPen ); - HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) ); - int nOldROP = SetROP2( getHDC(), R2_NOT ); - - WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); - - SetROP2( getHDC(), nOldROP ); - SelectPen( getHDC(), hOldPen ); - SelectBrush( getHDC(), hOldBrush ); - DeletePen( hDotPen ); - } - else if ( nFlags & SAL_INVERT_50 ) - { - SalData* pSalData = GetSalData(); - if ( !pSalData->mh50Brush ) - { - if ( !pSalData->mh50Bmp ) - pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); - pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); - } - - COLORREF nOldTextColor = ::SetTextColor( getHDC(), 0 ); - HBRUSH hOldBrush = SelectBrush( getHDC(), pSalData->mh50Brush ); - PatBlt( getHDC(), nX, nY, nWidth, nHeight, PATINVERT ); - ::SetTextColor( getHDC(), nOldTextColor ); - SelectBrush( getHDC(), hOldBrush ); - } - else - { - RECT aRect; - aRect.left = (int)nX; - aRect.top = (int)nY; - aRect.right = (int)nX+nWidth; - aRect.bottom = (int)nY+nHeight; - ::InvertRect( getHDC(), &aRect ); - } + mpImpl->invert( nX, nY, nWidth, nHeight, nFlags ); } void WinSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nSalFlags ) { - HPEN hPen; - HPEN hOldPen; - HBRUSH hBrush; - HBRUSH hOldBrush = 0; - COLORREF nOldTextColor RGB(0,0,0); - int nOldROP = SetROP2( getHDC(), R2_NOT ); - - if ( nSalFlags & SAL_INVERT_TRACKFRAME ) - hPen = CreatePen( PS_DOT, 0, 0 ); - else - { - - if ( nSalFlags & SAL_INVERT_50 ) - { - SalData* pSalData = GetSalData(); - if ( !pSalData->mh50Brush ) - { - if ( !pSalData->mh50Bmp ) - pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 ); - pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); - } - - hBrush = pSalData->mh50Brush; - } - else - hBrush = GetStockBrush( BLACK_BRUSH ); - - hPen = GetStockPen( NULL_PEN ); - nOldTextColor = ::SetTextColor( getHDC(), 0 ); - hOldBrush = SelectBrush( getHDC(), hBrush ); - } - hOldPen = SelectPen( getHDC(), hPen ); - - POINT* pWinPtAry; - // for NT, we can handover the array directly - DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ), - "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" ); - - pWinPtAry = (POINT*)pPtAry; - // for Windows 95 and its maximum number of points - if ( nSalFlags & SAL_INVERT_TRACKFRAME ) - { - if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); - } - else - { - if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); - } - - SetROP2( getHDC(), nOldROP ); - SelectPen( getHDC(), hOldPen ); - - if ( nSalFlags & SAL_INVERT_TRACKFRAME ) - DeletePen( hPen ); - else - { - ::SetTextColor( getHDC(), nOldTextColor ); - SelectBrush( getHDC(), hOldBrush ); - } + mpImpl->invert( nPoints, pPtAry, nSalFlags ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |