diff options
author | Armin Le Grand <alg@apache.org> | 2013-01-23 13:27:50 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-06-14 16:00:13 +0100 |
commit | 9bb96049addebd8907854730713d8a3f5f033e34 (patch) | |
tree | 35d257ff64e579fbcd19767c744e1672704fda79 /vcl | |
parent | 39fee18a1142850107b49cf0823cfdb85743aa49 (diff) |
Resolves: #i121534# Reintegrating changes for rotated bitmap support
(cherry picked from commit b2cc0de3fc9adee90787ca760e86869f9255b380)
Conflicts:
canvas/source/vcl/spritecanvashelper.cxx
drawinglayer/Library_drawinglayer.mk
drawinglayer/source/processor2d/vclhelperbitmaprender.cxx
drawinglayer/source/processor2d/vclhelperbitmaprender.hxx
drawinglayer/source/processor2d/vclhelperbitmaptransform.cxx
drawinglayer/source/processor2d/vclhelperbitmaptransform.hxx
drawinglayer/source/processor2d/vclprocessor2d.cxx
officecfg/registry/schema/org/openoffice/Office/Draw.xcs
svx/source/svdraw/svdograf.cxx
vcl/aqua/source/gdi/salgdi.cxx
vcl/inc/aqua/salgdi.h
vcl/inc/os2/salgdi.h
vcl/inc/salgdi.hxx
vcl/inc/unx/pspgraphics.h
vcl/inc/vcl/bitmapex.hxx
vcl/inc/vcl/outdev.hxx
vcl/inc/vcl/salbtype.hxx
vcl/os2/source/gdi/salgdi2.cxx
vcl/source/gdi/bitmapex.cxx
vcl/source/gdi/outdev2.cxx
vcl/source/gdi/salgdilayout.cxx
vcl/source/gdi/salmisc.cxx
vcl/unx/generic/gdi/pspgraphics.cxx
vcl/unx/generic/gdi/salgdi2.cxx
vcl/unx/headless/svpgdi.cxx
vcl/unx/headless/svpgdi.hxx
vcl/unx/headless/svppspgraphics.cxx
vcl/unx/headless/svppspgraphics.hxx
vcl/win/source/gdi/salbmp.cxx
vcl/win/source/gdi/salgdi.cxx
vcl/win/source/gdi/salgdi3.cxx
vcl/win/source/gdi/salgdi_gdiplus.cxx
vcl/win/source/gdi/winlayout.cxx
Change-Id: I871d1d107b019758f3913e5eb63bc9bc0ba403fd
Do not name unused arguments to prevent compiler warnings.
(cherry picked from commit f3118889a0cd941f193e9b6557c0792015d77a34)
Change-Id: I482d1f96d695c7bf9912ec464bb39e7fdd14adef
Related: #i121534# fix graphite-enabled windows build
(cherry picked from commit c90a6ca92b1239d01a2892e15488e4a183a88b1a)
Conflicts:
vcl/win/source/gdi/winlayout.cxx
Change-Id: I95fd41ad6f7187f34ba9474674a471fb4fc65314
Diffstat (limited to 'vcl')
31 files changed, 1903 insertions, 589 deletions
diff --git a/vcl/aqua/source/gdi/salgdicommon.cxx b/vcl/aqua/source/gdi/salgdicommon.cxx index f449b365facc..a7b3f32e63c3 100644 --- a/vcl/aqua/source/gdi/salgdicommon.cxx +++ b/vcl/aqua/source/gdi/salgdicommon.cxx @@ -284,7 +284,7 @@ static inline void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_ o_fY = static_cast<float>(i_pIn->mnY ) + 0.5; } -void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGraphics ) +void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGraphics ) { if( !pSrcGraphics ) { @@ -292,10 +292,10 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap } //from unix salgdi2.cxx //[FIXME] find a better way to prevent calc from crashing when width and height are negative - if( pPosAry->mnSrcWidth <= 0 - || pPosAry->mnSrcHeight <= 0 - || pPosAry->mnDestWidth <= 0 - || pPosAry->mnDestHeight <= 0 ) + if( rPosAry.mnSrcWidth <= 0 + || rPosAry.mnSrcHeight <= 0 + || rPosAry.mnDestWidth <= 0 + || rPosAry.mnDestHeight <= 0 ) { return; } @@ -304,17 +304,17 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap /*const*/ AquaSalGraphics* pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics); const bool bSameGraphics = (this == pSrc) || (mbWindow && mpFrame && pSrc->mbWindow && (mpFrame == pSrc->mpFrame)); - if( bSameGraphics && - (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && - (pPosAry->mnSrcHeight == pPosAry->mnDestHeight)) + if( bSameGraphics + && (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) + && (rPosAry.mnSrcHeight == rPosAry.mnDestHeight)) { // short circuit if there is nothing to do - if( (pPosAry->mnSrcX == pPosAry->mnDestX) && - (pPosAry->mnSrcY == pPosAry->mnDestY)) + if( (rPosAry.mnSrcX == rPosAry.mnDestX) + && (rPosAry.mnSrcY == rPosAry.mnDestY)) return; // use copyArea() if source and destination context are identical - copyArea( pPosAry->mnDestX, pPosAry->mnDestY, pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, 0 ); + copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 ); return; } @@ -323,9 +323,9 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" ); - const CGPoint aDstPoint = { static_cast<CGFloat>(+pPosAry->mnDestX - pPosAry->mnSrcX), static_cast<CGFloat>(pPosAry->mnDestY - pPosAry->mnSrcY) }; - if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && - pPosAry->mnSrcHeight == pPosAry->mnDestHeight) && + const CGPoint aDstPoint = { static_cast<CGFloat>(+rPosAry.mnDestX - rPosAry.mnSrcX), static_cast<CGFloat>(rPosAry.mnDestY - rPosAry.mnSrcY) }; + if( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth && + rPosAry.mnSrcHeight == rPosAry.mnDestHeight) && (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher { // in XOR mode the drawing context is redirected to the XOR mask @@ -339,7 +339,7 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap } } CGContextSaveGState( xCopyContext ); - const CGRect aDstRect = { { static_cast<CGFloat>(pPosAry->mnDestX), static_cast<CGFloat>(pPosAry->mnDestY) }, { static_cast<CGFloat>(pPosAry->mnDestWidth), static_cast<CGFloat>(pPosAry->mnDestHeight) } }; + const CGRect aDstRect = { { static_cast<CGFloat>(rPosAry.mnDestX), static_cast<CGFloat>(rPosAry.mnDestY) }, { static_cast<CGFloat>(rPosAry.mnDestWidth), static_cast<CGFloat>(rPosAry.mnDestHeight) } }; CGContextClipToRect( xCopyContext, aDstRect ); // draw at new destination @@ -356,15 +356,15 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap } else { - SalBitmap* pBitmap = pSrc->getBitmap( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ); + SalBitmap* pBitmap = pSrc->getBitmap( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ); if( pBitmap ) { - SalTwoRect aPosAry( *pPosAry ); + SalTwoRect aPosAry( rPosAry ); aPosAry.mnSrcX = 0; aPosAry.mnSrcY = 0; - drawBitmap( &aPosAry, *pBitmap ); + drawBitmap( aPosAry, *pBitmap ); delete pBitmap; } } @@ -530,6 +530,19 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, return true; } +bool AquaSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + + bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -558,33 +571,33 @@ bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, return true; } -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { if( !CheckContext() ) { return; } const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap); - CGImageRef xImage = rBitmap.CreateCroppedImage( (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight ); + CGImageRef xImage = rBitmap.CreateCroppedImage( (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight ); if( !xImage ) { return; } - const CGRect aDstRect = { { static_cast<CGFloat>(pPosAry->mnDestX), static_cast<CGFloat>(pPosAry->mnDestY) }, - { static_cast<CGFloat>(pPosAry->mnDestWidth), static_cast<CGFloat>(pPosAry->mnDestHeight) } }; + const CGRect aDstRect = { { static_cast<CGFloat>(rPosAry.mnDestX), static_cast<CGFloat>(rPosAry.mnDestY) }, + { static_cast<CGFloat>(rPosAry.mnDestWidth), static_cast<CGFloat>(rPosAry.mnDestHeight) } }; CGContextDrawImage( mrContext, aDstRect, xImage ); CGImageRelease( xImage ); RefreshRect( aDstRect ); } -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,SalColor ) +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,SalColor ) { OSL_FAIL("not implemented for color masking!"); - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap, +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ) { if( !CheckContext() ) @@ -593,14 +606,14 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rS } const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap); const QuartzSalBitmap& rMask = static_cast<const QuartzSalBitmap&>(rTransparentBitmap); - CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) ); + CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) ); if( !xMaskedImage ) { return; } - const CGRect aDstRect = { { static_cast<CGFloat>(pPosAry->mnDestX), static_cast<CGFloat>(pPosAry->mnDestY)}, - { static_cast<CGFloat>(pPosAry->mnDestWidth), static_cast<CGFloat>(pPosAry->mnDestHeight) } }; + const CGRect aDstRect = { { static_cast<CGFloat>(rPosAry.mnDestX), static_cast<CGFloat>(rPosAry.mnDestY)}, + { static_cast<CGFloat>(rPosAry.mnDestWidth), static_cast<CGFloat>(rPosAry.mnDestHeight) } }; CGContextDrawImage( mrContext, aDstRect, xMaskedImage ); CGImageRelease( xMaskedImage ); RefreshRect( aDstRect ); @@ -672,24 +685,22 @@ void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) Rectangle aRefreshRect( nX1, nY1, nX2, nY2 ); } -void AquaSalGraphics::drawMask( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap, - SalColor nMaskColor ) +void AquaSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) { if( !CheckContext() ) { return; } const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap); - CGImageRef xImage = rBitmap.CreateColorMask( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, + CGImageRef xImage = rBitmap.CreateColorMask( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, nMaskColor ); if( !xImage ) { return; } - const CGRect aDstRect = { { static_cast<CGFloat>(pPosAry->mnDestX), static_cast<CGFloat>(pPosAry->mnDestY) }, - { static_cast<CGFloat>(pPosAry->mnDestWidth), static_cast<CGFloat>(pPosAry->mnDestHeight) } }; + const CGRect aDstRect = { { static_cast<CGFloat>(rPosAry.mnDestX), static_cast<CGFloat>(rPosAry.mnDestY) }, + { static_cast<CGFloat>(rPosAry.mnDestWidth), static_cast<CGFloat>(rPosAry.mnDestHeight) } }; CGContextDrawImage( mrContext, aDstRect, xImage ); CGImageRelease( xImage ); RefreshRect( aDstRect ); diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx index b84ed324f6cc..a62b2712d0ca 100644 --- a/vcl/generic/print/genpspgraphics.cxx +++ b/vcl/generic/print/genpspgraphics.cxx @@ -496,7 +496,7 @@ sal_Bool GenPspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize ); } -void GenPspGraphics::copyBits( const SalTwoRect*, +void GenPspGraphics::copyBits( const SalTwoRect&, SalGraphics* ) { OSL_FAIL( "Error: PrinterGfx::CopyBits() not implemented" ); @@ -507,12 +507,12 @@ void GenPspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 ) OSL_FAIL( "Error: PrinterGfx::CopyArea() not implemented" ); } -void GenPspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void GenPspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { - Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY), - Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight)); - Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY), - Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight)); + Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY), + Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight)); + Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY), + Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight)); BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True); @@ -522,21 +522,21 @@ void GenPspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True); } -void GenPspGraphics::drawBitmap( const SalTwoRect*, +void GenPspGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap& ) { OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap"); } -void GenPspGraphics::drawBitmap( const SalTwoRect*, +void GenPspGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent color"); } -void GenPspGraphics::drawMask( const SalTwoRect*, +void GenPspGraphics::drawMask( const SalTwoRect&, const SalBitmap &, SalColor ) { @@ -1338,6 +1338,19 @@ bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&, return false; } +bool GenPspGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + + bool GenPspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 ) { return false; diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index e193ec21d53d..c7d75a0f67ab 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -68,6 +68,18 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSou return false; } +bool SvpSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ ) { // TODO(P3) implement alpha blending @@ -554,7 +566,7 @@ void SvpSalGraphics::copyArea( long nDestX, dbgOut( m_aDevice ); } -void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, +void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { if( !m_aDevice.get() ) @@ -562,12 +574,12 @@ void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, SvpSalGraphics* pSrc = pSrcGraphics ? static_cast<SvpSalGraphics*>(pSrcGraphics) : this; - basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); SvpSalGraphics::ClipUndoHandle aUndo( this ); if( !isClippedSetup( aDestRect, aUndo ) ) @@ -575,16 +587,16 @@ void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, dbgOut( m_aDevice ); } -void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); - basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); SvpSalGraphics::ClipUndoHandle aUndo( this ); if( !isClippedSetup( aDestRect, aUndo ) ) @@ -592,25 +604,25 @@ void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, dbgOut( m_aDevice ); } -void SvpSalGraphics::drawBitmap( const SalTwoRect*, +void SvpSalGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { // SNI, as in X11 plugin } -void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap); - basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); SvpSalGraphics::ClipUndoHandle aUndo( this ); if( !isClippedSetup( aDestRect, aUndo ) ) m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), @@ -618,21 +630,21 @@ void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, dbgOut( m_aDevice ); } -void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry, +void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); - basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - basegfx::B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY ); + basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + basegfx::B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY ); // BitmapDevice::drawMaskedColor works with 0==transparent, // 255==opaque. drawMask() semantic is the other way // around. Therefore, invert mask. basebmp::BitmapDeviceSharedPtr aCopy = - cloneBitmapDevice( basegfx::B2IVector( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ), + cloneBitmapDevice( basegfx::B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ), rSrc.getBitmap() ); basebmp::Color aBgColor( COL_WHITE ); aCopy->clear(aBgColor); @@ -640,7 +652,7 @@ void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry, aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, basegfx::B2IPoint() ); basebmp::Color aColor( nMaskColor ); - basegfx::B2IBox aSrcRect2( 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ); + basegfx::B2IBox aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ); const basegfx::B2IBox aClipRect( aDestPoint, basegfx::B2ITuple( aSrcRect.getWidth(), aSrcRect.getHeight() ) ); SvpSalGraphics::ClipUndoHandle aUndo( this ); diff --git a/vcl/inc/aqua/atsui/salgdi.h b/vcl/inc/aqua/atsui/salgdi.h index 2591521b9739..567d90c907a5 100644 --- a/vcl/inc/aqua/atsui/salgdi.h +++ b/vcl/inc/aqua/atsui/salgdi.h @@ -185,15 +185,15 @@ public: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -209,6 +209,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); diff --git a/vcl/inc/coretext/salgdi2.h b/vcl/inc/coretext/salgdi2.h index 01cf18a69cdb..77ed73984b1b 100644 --- a/vcl/inc/coretext/salgdi2.h +++ b/vcl/inc/coretext/salgdi2.h @@ -242,15 +242,15 @@ public: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -267,6 +267,13 @@ public: const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); + virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h index 4a1d8a00aa2b..07bdb01c5605 100644 --- a/vcl/inc/generic/genpspgraphics.h +++ b/vcl/inc/generic/genpspgraphics.h @@ -156,17 +156,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); @@ -180,6 +180,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); virtual SystemGraphicsData GetGraphicsData() const; diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 275789958c7f..c0fdb4e4e853 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -98,6 +98,12 @@ protected: #endif virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); public: @@ -190,17 +196,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 3422dce11abb..093e923cd36c 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -85,8 +85,9 @@ class VCL_PLUGIN_PUBLIC SalGraphics int m_nLayout; // 0: mirroring off, 1: mirror x-axis protected: + /// bitfield // flags which hold the SetAntialiasing() value from OutputDevice - bool m_bAntiAliasB2DDraw; + bool m_bAntiAliasB2DDraw : 1; public: void setAntiAliasB2DDraw(bool bNew) { m_bAntiAliasB2DDraw = bNew; } @@ -122,20 +123,20 @@ protected: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap, - SalColor nTransparentColor ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap, - const SalBitmap& rMaskBitmap ) = 0; - virtual void drawMask( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap, - SalColor nMaskColor ) = 0; - - virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) = 0; - virtual SalColor getPixel( long nX, long nY ) = 0; + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) = 0; + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) = 0; + virtual void drawBitmap( const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + SalColor nTransparentColor ) = 0; + virtual void drawBitmap( const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rMaskBitmap ) = 0; + virtual void drawMask( const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ) = 0; + + virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) = 0; + virtual SalColor getPixel( long nX, long nY ) = 0; // invert --> ClipRegion (only Windows or VirDevs) virtual void invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags) = 0; @@ -165,9 +166,18 @@ protected: otherwise. In this case, clients should try to emulate alpha compositing themselves */ - virtual bool drawAlphaBitmap( const SalTwoRect&, - const SalBitmap& rSourceBitmap, - const SalBitmap& rAlphaBitmap ) = 0; + virtual bool drawAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSourceBitmap, + const SalBitmap& rAlphaBitmap ) = 0; + + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) = 0; + /** Render solid rectangle with given transparency @param nTransparency @@ -408,19 +418,19 @@ public: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - void CopyBits( const SalTwoRect* pPosAry, + void CopyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev ); - void DrawBitmap( const SalTwoRect* pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const OutputDevice *pOutDev ); - void DrawBitmap( const SalTwoRect* pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev ); - void DrawMask( const SalTwoRect* pPosAry, + void DrawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor, const OutputDevice *pOutDev ); @@ -487,6 +497,14 @@ public: const SalBitmap& rAlphaBitmap, const OutputDevice *pOutDev ); + bool DrawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap, + const OutputDevice* pOutDev ); + bool DrawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency, const OutputDevice *pOutDev ); diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx index d41713afdaf2..6c9fea6f9545 100644 --- a/vcl/inc/unx/gtk/gtkgdi.hxx +++ b/vcl/inc/unx/gtk/gtkgdi.hxx @@ -147,7 +147,7 @@ public: // a control is painted; but presentation effects need // the background set to None; workaround: set the background // before copyBits - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); protected: diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 3a20ff6a338c..583651f736bd 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -163,7 +163,7 @@ protected: inline GC GetStippleGC(); using SalGraphics::DrawBitmap; - void DrawBitmap( const SalTwoRect *pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, SalGraphics *pThis, const SalBitmap &rSalBitmap, const SalBitmap &rTransparentBitmap, @@ -172,7 +172,7 @@ protected: GC GetFontGC(); bool setFont( const FontSelectPattern* pEntry, int nFallbackLevel ); - void drawMaskedBitmap( const SalTwoRect* pPosAry, + void drawMaskedBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); @@ -298,17 +298,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rMaskBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); @@ -321,6 +321,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); diff --git a/vcl/inc/win/salbmp.h b/vcl/inc/win/salbmp.h index 59ae69c8f8c4..4a9d721aa8fc 100644 --- a/vcl/inc/win/salbmp.h +++ b/vcl/inc/win/salbmp.h @@ -23,6 +23,7 @@ #include <tools/gen.hxx> #include <win/wincomp.hxx> #include <salbmp.hxx> +#include <boost/shared_ptr.hpp> // -------------- // - SalBitmap - @@ -32,24 +33,38 @@ struct BitmapBuffer; class BitmapColor; class BitmapPalette; class SalGraphics; +namespace Gdiplus { class Bitmap; } +typedef boost::shared_ptr< Gdiplus::Bitmap > GdiPlusBmpPtr; class WinSalBitmap : public SalBitmap { private: + friend class GdiPlusBuffer; // allow buffer to remove maGdiPlusBitmap eventually Size maSize; HGLOBAL mhDIB; HBITMAP mhDDB; - sal_uInt16 mnBitCount; + + // the buffered evtl. used Gdiplus::Bitmap instance. It is managed by + // GdiPlusBuffer. To make this safe, it is only handed out as shared + // pointer; the GdiPlusBuffer may delete the local instance + GdiPlusBmpPtr maGdiPlusBitmap; + + sal_uInt16 mnBitCount; + + Gdiplus::Bitmap* ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource); + Gdiplus::Bitmap* ImplCreateGdiPlusBitmap(); public: HGLOBAL ImplGethDIB() const { return mhDIB; } HBITMAP ImplGethDDB() const { return mhDDB; } + GdiPlusBmpPtr ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource = 0) const; + static HGLOBAL ImplCreateDIB( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ); static HANDLE ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB ); - static sal_uInt16 ImplGetDIBColorCount( HGLOBAL hDIB ); + static sal_uInt16 ImplGetDIBColorCount( HGLOBAL hDIB ); static void ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf, const Size& rSizePixel, bool bRLE4 ); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 31a04dce6ee9..f9fd488ee484 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -140,8 +140,14 @@ public: class WinSalGraphics : public SalGraphics { +private: + HDC mhLocalDC; // HDC + +public: + HDC getHDC() const { return mhLocalDC; } + void setHDC(HDC aNew) { mhLocalDC = aNew; } + public: - HDC mhDC; // HDC HWND mhWnd; // Window-Handle, when Window-Graphics HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks const ImplWinFontData* mpWinFontData[ MAX_FALLBACK ]; // pointer to the most recent font face @@ -168,15 +174,17 @@ public: KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of the current Font int mnPenWidth; // Linienbreite - sal_Bool mbStockPen; // is Pen a stockpen - sal_Bool mbStockBrush; // is Brush a stcokbrush - sal_Bool mbPen; // is Pen (FALSE == NULL_PEN) - sal_Bool mbBrush; // is Brush (FALSE == NULL_BRUSH) - sal_Bool mbPrinter; // is Printer - sal_Bool mbVirDev; // is VirDev - sal_Bool mbWindow; // is Window - sal_Bool mbScreen; // is Screen compatible - bool mbXORMode; // _every_ output with RasterOp XOR + + /// bitfield + bool mbStockPen : 1; // is Pen a stockpen + bool mbStockBrush : 1; // is Brush a stcokbrush + bool mbPen : 1; // is Pen (FALSE == NULL_PEN) + bool mbBrush : 1; // is Brush (FALSE == NULL_BRUSH) + bool mbPrinter : 1; // is Printer + bool mbVirDev : 1; // is VirDev + bool mbWindow : 1; // is Window + bool mbScreen : 1; // is Screen compatible + bool mbXORMode : 1; // _every_ output with RasterOp XOR // remember RGB values for SetLineColor/SetFillColor SalColor maLineColor; @@ -215,15 +223,15 @@ protected: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -249,8 +257,18 @@ protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); +private: + // local helpers + bool tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap); + public: // public SalGraphics methods, the interface to the independent vcl part diff --git a/vcl/inc/win/salvd.h b/vcl/inc/win/salvd.h index cb761d8b65ee..c6f5b1e4e2f5 100644 --- a/vcl/inc/win/salvd.h +++ b/vcl/inc/win/salvd.h @@ -30,8 +30,14 @@ class WinSalGraphics; class WinSalVirtualDevice : public SalVirtualDevice { +private: + HDC mhLocalDC; // HDC or 0 for Cache Device + +public: + HDC getHDC() { return mhLocalDC; } + void setHDC(HDC aNew) { mhLocalDC = aNew; } + public: - HDC mhDC; // HDC or 0 for Cache Device HBITMAP mhBmp; // Memory Bitmap HBITMAP mhDefBmp; // Default Bitmap WinSalGraphics* mpGraphics; // current VirDev graphics diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index eeb68d2c101e..6e81c065a320 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -36,6 +36,7 @@ #include <image.h> #include <impimagetree.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> // BitmapEx::Create #include <salbmp.hxx> @@ -850,4 +851,371 @@ bool BitmapEx::Create( const ::com::sun::star::uno::Reference< return false; } +// ------------------------------------------------------------------ + +namespace +{ + void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead) + { + double fDeltaX(rSource.getX() - nIntX); + double fDeltaY(rSource.getY() - nIntY); + sal_Int32 nIndX(0L); + sal_Int32 nIndY(0L); + + if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width()) + { + nIndX++; + } + else if(fDeltaX < 0.0 && nIntX >= 1L) + { + fDeltaX = -fDeltaX; + nIndX--; + } + + if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height()) + { + nIndY++; + } + else if(fDeltaY < 0.0 && nIntY >= 1L) + { + fDeltaY = -fDeltaY; + nIndY--; + } + + if(nIndX || nIndY) + { + const double fColorToReal(1.0 / 255.0); + double fR(rValue.GetRed() * fColorToReal); + double fG(rValue.GetGreen() * fColorToReal); + double fB(rValue.GetBlue() * fColorToReal); + double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0); + + if(nIndX) + { + const double fMulA(fDeltaX * fColorToReal); + double fMulB(1.0 - fDeltaX); + const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX)); + + fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA); + fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA); + fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA); + + if(nIndY) + { + fMulB *= fColorToReal; + const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); + const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX)); + + fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA); + fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA); + fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA); + } + } + + if(nIndY) + { + if(!nIndX) + { + const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); + + fRBottom = aBottom.GetRed() * fColorToReal; + fGBottom = aBottom.GetGreen() * fColorToReal; + fBBottom = aBottom.GetBlue() * fColorToReal; + } + + const double fMulB(1.0 - fDeltaY); + + fR = (fR * fMulB) + (fRBottom * fDeltaY); + fG = (fG * fMulB) + (fGBottom * fDeltaY); + fB = (fB * fMulB) + (fBBottom * fDeltaY); + } + + rValue.SetRed((sal_uInt8)(fR * 255.0)); + rValue.SetGreen((sal_uInt8)(fG * 255.0)); + rValue.SetBlue((sal_uInt8)(fB * 255.0)); + } + } + + Bitmap impTransformBitmap( + const Bitmap& rSource, + const Size aDestinationSize, + const basegfx::B2DHomMatrix& rTransform, + bool bSmooth) + { + Bitmap aDestination(aDestinationSize, 24); + BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess(); + + if(pWrite) + { + const Size aContentSizePixel(rSource.GetSizePixel()); + BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); + + if(pRead) + { + const Size aDestinationSizePixel(aDestination.GetSizePixel()); + bool bWorkWithIndex(rSource.GetBitCount() <= 8); + BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); + + for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) + { + for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) + { + const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); + const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX())); + + if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth()) + { + const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY())); + + if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight()) + { + // inside pixel + BitmapColor aValue; + + if(bWorkWithIndex) + { + aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX)); + } + else + { + aValue = pRead->GetPixel(nIntY, nIntX); + } + + if(bSmooth) + { + impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead); + } + + pWrite->SetPixel(y, x, aValue); + continue; + } + } + + // here are outside pixels. Complete mask + if(bWorkWithIndex) + { + pWrite->SetPixel(y, x, aOutside); + } + } + } + + delete pRead; + } + + delete pWrite; + } + + rSource.AdaptBitCount(aDestination); + + return aDestination; + } +} // end of anonymous namespace +BitmapEx BitmapEx::TransformBitmapEx( + double fWidth, + double fHeight, + const basegfx::B2DHomMatrix& rTransformation) const +{ + if(fWidth <= 1 || fHeight <= 1) + return BitmapEx(); + + // force destination to 24 bit, we want to smooth output + const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight)); + static bool bDoSmoothAtAll(true); + const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + + // create mask + if(IsTransparent()) + { + if(IsAlpha()) + { + const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + return BitmapEx(aDestination, AlphaMask(aAlpha)); + } + else + { + const Bitmap aLclMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false)); + return BitmapEx(aDestination, aLclMask); + } + } + + return BitmapEx(aDestination); +} + +// ------------------------------------------------------------------ + +BitmapEx BitmapEx::getTransformed( + const basegfx::B2DHomMatrix& rTransformation, + double fMaximumArea) const +{ + BitmapEx aRetval; + + if(IsEmpty()) + return aRetval; + + const sal_uInt32 nSourceWidth(GetSizePixel().Width()); + const sal_uInt32 nSourceHeight(GetSizePixel().Height()); + + if(!nSourceWidth || !nSourceHeight) + return aRetval; + + // Get dest range + basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); + aOutlineRange.transform(rTransformation); + + // get target size + double fWidth(aOutlineRange.getWidth()); + double fHeight(aOutlineRange.getHeight()); + + if(fWidth < 1.0 || fHeight < 1.0) + return aRetval; + + // test if discrete size (pixel) maybe too big and limit it + const double fArea(fWidth * fHeight); + const bool bNeedToReduce(fArea > fMaximumArea); + double fReduceFactor(1.0); + + if(bNeedToReduce) + { + fReduceFactor = sqrt(fMaximumArea / fArea); + fWidth *= fReduceFactor; + fHeight *= fReduceFactor; + } + + // Build complete transform from source pixels to target pixels. + // Start by scaling from source pixel size to unit coordinates + basegfx::B2DHomMatrix aTransform( + basegfx::tools::createScaleB2DHomMatrix( + 1.0 / nSourceWidth, + 1.0 / nSourceHeight)); + + // multiply with given transform which leads from unit coordinates inside + // aOutlineRange + aTransform = rTransformation * aTransform; + + // substract top-left of aOutlineRange + aTransform.translate(-aOutlineRange.getMinX(), -aOutlineRange.getMinY()); + + // scale to target pixels (if needed) + if(bNeedToReduce) + { + aTransform.scale(fReduceFactor, fReduceFactor); + } + + // invert to get transformation from target pixel coordiates to source pixels + aTransform.invert(); + + // create bitmap using source, destination and linear back-transformation + aRetval = TransformBitmapEx(fWidth, fHeight, aTransform); + + return aRetval; +} + +// ------------------------------------------------------------------ + +BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const +{ + Bitmap aChangedBitmap(GetBitmap()); + bool bDone(false); + + for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; ) + { + const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a); + + switch(rModifier.getMode()) + { + case basegfx::BCOLORMODIFYMODE_REPLACE : + { + // complete replace + if(IsTransparent()) + { + // clear bitmap with dest color + if(aChangedBitmap.GetBitCount() <= 8) + { + // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given + // erase color is determined and used -> this may be different from what is + // wanted here. Better create a new bitmap with the needed color explicitely + BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess(); + OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?"); + + if(pReadAccess) + { + BitmapPalette aNewPalette(pReadAccess->GetPalette()); + aNewPalette[0] = BitmapColor(Color(rModifier.getBColor())); + aChangedBitmap = Bitmap( + aChangedBitmap.GetSizePixel(), + aChangedBitmap.GetBitCount(), + &aNewPalette); + delete pReadAccess; + } + } + else + { + aChangedBitmap.Erase(Color(rModifier.getBColor())); + } + } + else + { + // erase bitmap, caller will know to paint direct + aChangedBitmap.SetEmpty(); + } + + bDone = true; + break; + } + + default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE + { + BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess(); + + if(pContent) + { + const double fConvertColor(1.0 / 255.0); + + for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++) + { + for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++) + { + const BitmapColor aBMCol(pContent->GetColor(y, x)); + const basegfx::BColor aBSource( + (double)aBMCol.GetRed() * fConvertColor, + (double)aBMCol.GetGreen() * fConvertColor, + (double)aBMCol.GetBlue() * fConvertColor); + const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource)); + + pContent->SetPixel(y, x, BitmapColor(Color(aBDest))); + } + } + + delete pContent; + } + + break; + } + } + } + + if(aChangedBitmap.IsEmpty()) + { + return BitmapEx(); + } + else + { + if(IsTransparent()) + { + if(IsAlpha()) + { + return BitmapEx(aChangedBitmap, GetAlpha()); + } + else + { + return BitmapEx(aChangedBitmap, GetMask()); + } + } + else + { + return BitmapEx(aChangedBitmap); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx index cc610069a904..72936098f194 100644 --- a/vcl/source/gdi/outdev2.cxx +++ b/vcl/source/gdi/outdev2.cxx @@ -18,7 +18,6 @@ */ #include <tools/debug.hxx> - #include <vcl/bitmap.hxx> #include <vcl/bitmapex.hxx> #include <vcl/window.hxx> @@ -28,7 +27,6 @@ #include <vcl/bmpacc.hxx> #include <vcl/outdev.hxx> #include <vcl/image.hxx> - #include <bmpfast.hxx> #include <salbmp.hxx> #include <salgdi.hxx> @@ -38,6 +36,7 @@ #include <outdev.h> #include <window.h> #include <outdata.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> DBG_NAMEEX( OutputDevice ) @@ -157,9 +156,8 @@ void ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Rectangle& rValidSrcRect ) } } -void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoidPosAry ) +void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry ) { - SalTwoRect* pPosAry = (SalTwoRect*)pVoidPosAry; SalGraphics* pGraphics2; if ( this == pSrcDev ) @@ -204,9 +202,9 @@ void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoi const Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ), Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) ); - ImplAdjustTwoRect( *pPosAry, aSrcOutRect ); + ImplAdjustTwoRect( rPosAry, aSrcOutRect ); - if ( pPosAry->mnSrcWidth && pPosAry->mnSrcHeight && pPosAry->mnDestWidth && pPosAry->mnDestHeight ) + if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight ) { // --- RTL --- if this is no window, but pSrcDev is a window // mirroring may be required @@ -214,12 +212,12 @@ void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoi // mirroring is performed here if( (GetOutDevType() != OUTDEV_WINDOW) && pGraphics2 && (pGraphics2->GetLayout() & SAL_LAYOUT_BIDI_RTL) ) { - SalTwoRect pPosAry2 = *pPosAry; - pGraphics2->mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcDev ); - mpGraphics->CopyBits( &pPosAry2, pGraphics2, this, pSrcDev ); + SalTwoRect aPosAry2 = rPosAry; + pGraphics2->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev ); + mpGraphics->CopyBits( aPosAry2, pGraphics2, this, pSrcDev ); } else - mpGraphics->CopyBits( pPosAry, pGraphics2, this, pSrcDev ); + mpGraphics->CopyBits( rPosAry, pGraphics2, this, pSrcDev ); } } @@ -268,7 +266,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, ImplAdjustTwoRect( aPosAry, aSrcOutRect ); if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight ) - mpGraphics->CopyBits( &aPosAry, NULL, this, NULL ); + mpGraphics->CopyBits( aPosAry, NULL, this, NULL ); } if( mpAlphaVDev ) @@ -324,7 +322,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, } else { - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); // #i32109#: make destination rectangle opaque - source has no alpha mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) ); @@ -340,7 +338,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, else { // no alpha at all, neither in source nor destination device - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); } } } @@ -398,7 +396,7 @@ void OutputDevice::CopyArea( const Point& rDestPt, { aPosAry.mnDestWidth = aPosAry.mnSrcWidth; aPosAry.mnDestHeight = aPosAry.mnSrcHeight; - mpGraphics->CopyBits( &aPosAry, NULL, this, NULL ); + mpGraphics->CopyBits( aPosAry, NULL, this, NULL ); } } } @@ -445,7 +443,7 @@ void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, cons aPosAry.mnDestY = rPt.Y(); aPosAry.mnDestWidth = rDevSize.Width(); aPosAry.mnDestHeight = rDevSize.Height(); - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); // Ensure that ClipRegion is recalculated and set mbInitClipRegion = true; @@ -517,18 +515,19 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); - Bitmap aBmp( rBitmap ); - if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) ) { return; } - else if ( ROP_INVERT == meRasterOp ) + if ( ROP_INVERT == meRasterOp ) { DrawRect( Rectangle( rDestPt, rDestSize ) ); return; } - else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | + + Bitmap aBmp( rBitmap ); + + if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) ) { if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) ) @@ -612,7 +611,7 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, aPosAry.mnSrcWidth = aPosAry.mnDestWidth; aPosAry.mnSrcHeight = aPosAry.mnDestHeight; } - mpGraphics->DrawBitmap( &aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this ); + mpGraphics->DrawBitmap( aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this ); } } } @@ -625,7 +624,9 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, return; if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rBitmapEx.GetBitmap() ); + } else { const Size aSizePix( rBitmapEx.GetSizePixel() ); @@ -640,9 +641,13 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, return; if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() ); + } else + { ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION ); + } } void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, @@ -653,9 +658,117 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, return; if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() ); + } else + { ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION ); + } +} + +// ------------------------------------------------------------------ + +void OutputDevice::DrawTransformedBitmapEx( + const basegfx::B2DHomMatrix& rTransformation, + const BitmapEx& rBitmapEx) +{ + OSL_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" ); + + if( ImplIsRecordLayout() ) + return; + + if(rBitmapEx.IsEmpty()) + return; + + if ( mnDrawMode & DRAWMODE_NOBITMAP ) + return; + + // decompose matrix to check rotation and shear + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rTransformation.decompose(aScale, aTranslate, fRotate, fShearX); + const bool bRotated(!basegfx::fTools::equalZero(fRotate)); + const bool bSheared(!basegfx::fTools::equalZero(fShearX)); + const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0)); + const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0)); + + if(!bRotated && !bSheared && !bMirroredX && !bMirroredY) + { + // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx + // do *not* execute the mirroring here, it's done in the fallback + const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY())); + + DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); + return; + } + + // we have rotation,shear or mirror, check if some crazy mode needs the + // created transformed bitmap + const bool bInvert(ROP_INVERT == meRasterOp); + const bool bBitmapChangedColor(mnDrawMode & (DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP)); + const bool bMetafile(mpMetaFile); + const bool bPrinter(OUTDEV_PRINTER == meOutDevType); + bool bDone(false); + const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); + const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter); + + if(bTryDirectPaint) + { + // try to paint directly + const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0)); + const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0)); + const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0)); + SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap(); + SalBitmap* pSalAlphaBmp = 0; + + if(rBitmapEx.IsTransparent()) + { + if(rBitmapEx.IsAlpha()) + { + pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + else + { + pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + } + + bDone = mpGraphics->DrawTransformedBitmap( + aNull, + aTopX, + aTopY, + *pSalSrcBmp, + pSalAlphaBmp, + this); + } + + if(!bDone) + { + // take the fallback when no rotate and shear, but mirror (else we would have done this above) + if(!bRotated && !bSheared) + { + // with no rotation or shear it can be mapped to DrawBitmapEx + // do *not* execute the mirroring here, it's done in the fallback + const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY())); + + DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); + return; + } + + // fallback; create transformed bitmap the hard way (back-transform + // the pixels) and paint + basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); + const double fMaximumArea(bMetafile ? 800000.0 : 200000.0); + const BitmapEx aTransformed(rBitmapEx.getTransformed(aFullTransform, fMaximumArea)); + aTargetRange.transform(rTransformation); + const Point aDestPt(basegfx::fround(aTargetRange.getMinX()), basegfx::fround(aTargetRange.getMinY())); + const Size aDestSize(basegfx::fround(aTargetRange.getWidth()), basegfx::fround(aTargetRange.getHeight())); + + DrawBitmapEx(aDestPt, aDestSize, aTransformed); + } } void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize, @@ -663,17 +776,20 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize const BitmapEx& rBitmapEx, const sal_uLong nAction ) { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); - - BitmapEx aBmpEx( rBitmapEx ); + OSL_ENSURE(TRANSPARENT_NONE != rBitmapEx.GetTransparentType(), "ImplDrawBitmapEx not needed, no transparency in BitmapEx (!)"); if ( mnDrawMode & DRAWMODE_NOBITMAP ) return; - else if ( ROP_INVERT == meRasterOp ) + + if ( ROP_INVERT == meRasterOp ) { DrawRect( Rectangle( rDestPt, rDestSize ) ); return; } - else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | + + BitmapEx aBmpEx( rBitmapEx ); + + if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) ) { if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) ) @@ -752,9 +868,11 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize aBmp.Replace( aMask, Color( COL_WHITE ) ); ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel ); } + return; } - else if( aBmpEx.IsAlpha() ) + + if(aBmpEx.IsAlpha()) { ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel ); return; @@ -781,70 +899,92 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize if( nMirrFlags ) aBmpEx.Mirror( nMirrFlags ); - const ImpBitmap* pImpBmp = aBmpEx.ImplGetBitmapImpBitmap(); + const SalBitmap* pSalSrcBmp = aBmpEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap(); const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap(); if ( pMaskBmp ) { - // #4919452# reduce operation area to bounds of - // cliprect. since masked transparency involves - // creation of a large vdev and copying the screen - // content into that (slooow read from framebuffer), - // that should considerably increase performance for - // large bitmaps and small clippings. - - // Note that this optimisation is a workaround for a - // Writer peculiarity, namely, to decompose background - // graphics into myriads of disjunct, tiny - // rectangles. That otherwise kills us here, since for - // transparent output, SAL always prepares the whole - // bitmap, if aPosAry contains the whole bitmap (and - // it's _not_ to blame for that). - - // Note the call to ImplPixelToDevicePixel(), since - // aPosAry already contains the mnOutOff-offsets, they - // also have to be applied to the region - Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() ); - - // TODO: Also respect scaling (that's a bit tricky, - // since the source points have to move fractional - // amounts (which is not possible, thus has to be - // emulated by increases copy area) - // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth ); - // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight ); - - // for now, only identity scales allowed - if( !aClipRegionBounds.IsEmpty() && - aPosAry.mnDestWidth == aPosAry.mnSrcWidth && - aPosAry.mnDestHeight == aPosAry.mnSrcHeight ) + SalBitmap* pSalAlphaBmp = pMaskBmp->ImplGetSalBitmap(); + bool bTryDirectPaint(pSalSrcBmp && pSalAlphaBmp); + + if(bTryDirectPaint) { - // now intersect dest rect with clip region - aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, - aPosAry.mnDestY, - aPosAry.mnDestX + aPosAry.mnDestWidth - 1, - aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) ); - - // Note: I could theoretically optimize away the - // DrawBitmap below, if the region is empty - // here. Unfortunately, cannot rule out that - // somebody relies on the side effects. - if( !aClipRegionBounds.IsEmpty() ) + // 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(!IsMapMode() && aPosAry.mnSrcWidth == aPosAry.mnDestWidth && aPosAry.mnSrcHeight == aPosAry.mnDestHeight) { - aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX; - aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY; - aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth(); - aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight(); - - aPosAry.mnDestX = aClipRegionBounds.Left(); - aPosAry.mnDestY = aClipRegionBounds.Top(); - aPosAry.mnDestWidth = aClipRegionBounds.GetWidth(); - aPosAry.mnDestHeight = aClipRegionBounds.GetHeight(); + bTryDirectPaint = false; } } - mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), - *pMaskBmp->ImplGetSalBitmap(), - this ); + if(bTryDirectPaint && mpGraphics->DrawAlphaBitmap(aPosAry, *pSalSrcBmp, *pSalAlphaBmp, this)) + { + // tried to paint as alpha directly. If tis worked, we are done (except + // alpha, see below) + } + else + { + // #4919452# reduce operation area to bounds of + // cliprect. since masked transparency involves + // creation of a large vdev and copying the screen + // content into that (slooow read from framebuffer), + // that should considerably increase performance for + // large bitmaps and small clippings. + + // Note that this optimisation is a workaround for a + // Writer peculiarity, namely, to decompose background + // graphics into myriads of disjunct, tiny + // rectangles. That otherwise kills us here, since for + // transparent output, SAL always prepares the whole + // bitmap, if aPosAry contains the whole bitmap (and + // it's _not_ to blame for that). + + // Note the call to ImplPixelToDevicePixel(), since + // aPosAry already contains the mnOutOff-offsets, they + // also have to be applied to the region + Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() ); + + // TODO: Also respect scaling (that's a bit tricky, + // since the source points have to move fractional + // amounts (which is not possible, thus has to be + // emulated by increases copy area) + // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth ); + // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight ); + + // for now, only identity scales allowed + if( !aClipRegionBounds.IsEmpty() && + aPosAry.mnDestWidth == aPosAry.mnSrcWidth && + aPosAry.mnDestHeight == aPosAry.mnSrcHeight ) + { + // now intersect dest rect with clip region + aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, + aPosAry.mnDestY, + aPosAry.mnDestX + aPosAry.mnDestWidth - 1, + aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) ); + + // Note: I could theoretically optimize away the + // DrawBitmap below, if the region is empty + // here. Unfortunately, cannot rule out that + // somebody relies on the side effects. + if( !aClipRegionBounds.IsEmpty() ) + { + aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX; + aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY; + aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth(); + aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight(); + + aPosAry.mnDestX = aClipRegionBounds.Left(); + aPosAry.mnDestY = aClipRegionBounds.Top(); + aPosAry.mnDestWidth = aClipRegionBounds.GetWidth(); + aPosAry.mnDestHeight = aClipRegionBounds.GetHeight(); + } + } + + mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, + *pMaskBmp->ImplGetSalBitmap(), + this ); + } // #110958# Paint mask to alpha channel. Luckily, the // black and white representation of the mask maps to @@ -863,7 +1003,7 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize } else { - mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), this ); + mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, this ); if( mpAlphaVDev ) { @@ -1017,11 +1157,11 @@ void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize, { Bitmap aTmp( rBitmap ); aTmp.Mirror( nMirrFlags ); - mpGraphics->DrawMask( &aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(), + mpGraphics->DrawMask( aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(), ImplColorToSal( rMaskColor ) , this); } else - mpGraphics->DrawMask( &aPosAry, *pImpBmp->ImplGetSalBitmap(), + mpGraphics->DrawMask( aPosAry, *pImpBmp->ImplGetSalBitmap(), ImplColorToSal( rMaskColor ), this ); } @@ -1217,7 +1357,7 @@ Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const aPosAry.mnDestHeight = nHeight; if ( (nWidth > 0) && (nHeight > 0) ) - (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( &aPosAry, mpGraphics, this, this ); + (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( aPosAry, mpGraphics, this, this ); aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() ); } @@ -1754,7 +1894,22 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA"); // #i83087# Naturally, system alpha blending cannot work with // separate alpha VDev - if( !mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr ) + bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr); + +#ifdef WNT + 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(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height()) + { + bTryDirectPaint = false; + } + } +#endif + + if(bTryDirectPaint) { Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY ); SalTwoRect aTR = { diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx index 6a10498a8ebd..98614c85eaa3 100644 --- a/vcl/source/gdi/outmap.cxx +++ b/vcl/source/gdi/outmap.cxx @@ -756,7 +756,7 @@ void OutputDevice::SetMapMode( const MapMode& rNewMapMode ) mpAlphaVDev->SetMapMode( rNewMapMode ); // Ist Default-MapMode, dann bereche nichts - sal_Bool bOldMap = mbMap; + bool bOldMap = mbMap; mbMap = !rNewMapMode.IsDefault(); if ( mbMap ) { diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 269f71096dd6..9d5457316f6a 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -80,6 +80,19 @@ SalGraphics::~SalGraphics() // ---------------------------------------------------------------------------- +bool SalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& /* rNull */, + const basegfx::B2DPoint& /* rX */, + const basegfx::B2DPoint& /* rY */, + const SalBitmap& /* rSourceBitmap */, + const SalBitmap* /* pAlphaBitmap */) +{ + // here direct support for transformed bitmaps can be impemented + return false; +} + +// ---------------------------------------------------------------------------- + void SalGraphics::mirror( long& x, const OutputDevice *pOutDev, bool bBack ) const { long w; @@ -554,59 +567,59 @@ void SalGraphics::CopyArea( long nDestX, long nDestY, } copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, nFlags ); } -void SalGraphics::CopyBits( const SalTwoRect* pPosAry, +void SalGraphics::CopyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev ) { if( ( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) || (pSrcGraphics && ( (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) ) ) { - SalTwoRect pPosAry2 = *pPosAry; + SalTwoRect aPosAry2 = rPosAry; if( (pSrcGraphics && (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) - mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcOutDev ); + mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcOutDev ); if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - copyBits( &pPosAry2, pSrcGraphics ); + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + copyBits( aPosAry2, pSrcGraphics ); } else - copyBits( pPosAry, pSrcGraphics ); + copyBits( rPosAry, pSrcGraphics ); } -void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, +void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawBitmap( &pPosAry2, rSalBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawBitmap( aPosAry2, rSalBitmap ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } -void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, +void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawBitmap( &pPosAry2, rSalBitmap, rTransparentBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawBitmap( aPosAry2, rSalBitmap, rTransparentBitmap ); } else - drawBitmap( pPosAry, rSalBitmap, rTransparentBitmap ); + drawBitmap( rPosAry, rSalBitmap, rTransparentBitmap ); } -void SalGraphics::DrawMask( const SalTwoRect* pPosAry, +void SalGraphics::DrawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawMask( &pPosAry2, rSalBitmap, nMaskColor ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawMask( aPosAry2, rSalBitmap, nMaskColor ); } else - drawMask( pPosAry, rSalBitmap, nMaskColor ); + drawMask( rPosAry, rSalBitmap, nMaskColor ); } SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev ) { @@ -744,14 +757,40 @@ bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry, { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = rPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - return drawAlphaBitmap( pPosAry2, rSourceBitmap, rAlphaBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + return drawAlphaBitmap( aPosAry2, rSourceBitmap, rAlphaBitmap ); } else return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap ); } +bool SalGraphics::DrawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap, + const OutputDevice* pOutDev) +{ + if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) + { + basegfx::B2DPoint aNull(rNull); + basegfx::B2DPoint aX(rX); + basegfx::B2DPoint aY(rY); + + mirror(aNull, pOutDev); + mirror(aX, pOutDev); + mirror(aY, pOutDev); + + return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, pAlphaBitmap); + } + else + { + return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap); + } +} + bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency, const OutputDevice *pOutDev ) { diff --git a/vcl/source/gdi/salmisc.cxx b/vcl/source/gdi/salmisc.cxx index 79e554e47fab..9720c6420920 100644 --- a/vcl/source/gdi/salmisc.cxx +++ b/vcl/source/gdi/salmisc.cxx @@ -250,8 +250,9 @@ static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffe delete[] pColToPalMap; } -BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, - sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask ) +BitmapBuffer* StretchAndConvert( + const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, + sal_uLong nDstBitmapFormat, const BitmapPalette* pDstPal, const ColorMask* pDstMask ) { FncGetPixel pFncGetPixel; FncSetPixel pFncSetPixel; diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx index 35595507ea9c..4ef94b9ce462 100644 --- a/vcl/source/gdi/virdev.cxx +++ b/vcl/source/gdi/virdev.cxx @@ -281,7 +281,7 @@ sal_Bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, sal_B aPosAry.mnDestWidth = nWidth; aPosAry.mnDestHeight = nHeight; - pGraphics->CopyBits( &aPosAry, mpGraphics, this, this ); + pGraphics->CopyBits( aPosAry, mpGraphics, this, this ); pNewVirDev->ReleaseGraphics( pGraphics ); ImplReleaseGraphics(); pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev ); diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 0288e0555771..6ec682954a6f 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -45,7 +45,7 @@ { \ XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(), \ 0, 0, \ - pPosAry->mnDestWidth, pPosAry->mnDestHeight, \ + rPosAry.mnDestWidth, rPosAry.mnDestHeight, \ 0, 0 ); \ } #else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS @@ -279,17 +279,17 @@ void X11SalGraphics::YieldGraphicsExpose() } while( aEvent.xgraphicsexpose.count != 0 ); } -void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, +void X11SalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSSrcGraphics ) { X11SalGraphics* pSrcGraphics = pSSrcGraphics ? static_cast<X11SalGraphics*>(pSSrcGraphics) : this; - if( pPosAry->mnSrcWidth <= 0 - || pPosAry->mnSrcHeight <= 0 - || pPosAry->mnDestWidth <= 0 - || pPosAry->mnDestHeight <= 0 ) + if( rPosAry.mnSrcWidth <= 0 + || rPosAry.mnSrcHeight <= 0 + || rPosAry.mnDestWidth <= 0 + || rPosAry.mnDestHeight <= 0 ) { return; } @@ -322,8 +322,8 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, n = 0; if( n == 2 - && pPosAry->mnSrcWidth == pPosAry->mnDestWidth - && pPosAry->mnSrcHeight == pPosAry->mnDestHeight + && rPosAry.mnSrcWidth == rPosAry.mnDestWidth + && rPosAry.mnSrcHeight == rPosAry.mnDestHeight ) { // #i60699# Need to generate graphics exposures (to repaint @@ -341,7 +341,7 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, { Pixmap hPixmap = limitXCreatePixmap( GetXDisplay(), pSrcGraphics->GetDrawable(), // source - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, pSrcGraphics->GetBitCount() ); pCopyGC = GetDisplay()->GetCopyGC( m_nXScreen ); @@ -355,16 +355,16 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, pSrcGraphics->GetDrawable(), // source hPixmap, // destination pCopyGC, // no clipping - pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, + rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0, 0 ); // destination XCopyArea( GetXDisplay(), hPixmap, // source GetDrawable(), // destination GetInvertGC(), // destination clipping 0, 0, // source - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); XFreePixmap( GetXDisplay(), hPixmap ); } else @@ -380,9 +380,9 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, pSrcGraphics->GetDrawable(), // source GetDrawable(), // destination pCopyGC, // destination clipping - pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); } if( bNeedGraphicsExposures ) @@ -400,10 +400,10 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, // #i60699# No chance to handle graphics exposures - we copy // to a temp bitmap first, into which no repaints are // technically possible. - SalBitmap *pDDB = pSrcGraphics->getBitmap( pPosAry->mnSrcX, - pPosAry->mnSrcY, - pPosAry->mnSrcWidth, - pPosAry->mnSrcHeight ); + SalBitmap *pDDB = pSrcGraphics->getBitmap( rPosAry.mnSrcX, + rPosAry.mnSrcY, + rPosAry.mnSrcWidth, + rPosAry.mnSrcHeight ); if( !pDDB ) { @@ -411,10 +411,10 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, return; } - SalTwoRect aPosAry( *pPosAry ); + SalTwoRect aPosAry( rPosAry ); aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0; - drawBitmap( &aPosAry, *pDDB ); + drawBitmap( aPosAry, *pDDB ); delete pDDB; } @@ -442,10 +442,10 @@ void X11SalGraphics::copyArea ( long nDestX, long nDestY, aPosAry.mnSrcWidth = nSrcWidth; aPosAry.mnSrcHeight = nSrcHeight; - copyBits ( &aPosAry, 0 ); + copyBits ( aPosAry, 0 ); } -void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { const SalDisplay* pSalDisp = GetDisplay(); Display* pXDisp = pSalDisp->GetDisplay(); @@ -479,14 +479,14 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa XChangeGC( pXDisp, aGC, nValues, &aNewVal ); } - static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nXScreen, nDepth, *pPosAry, aGC ); + static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nXScreen, nDepth, rPosAry, aGC ); if( rSalBitmap.GetBitCount() == 1 ) XChangeGC( pXDisp, aGC, nValues, &aOldVal ); XFlush( pXDisp ); } -void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSrcBitmap, const SalBitmap& rMaskBitmap ) { @@ -499,13 +499,13 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, int nMaskFormat = pAlphaBuffer->mnFormat; const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, sal_True ); if( nMaskFormat == BMP_FORMAT_8BIT_PAL ) - drawAlphaBitmap( *pPosAry, rSrcBitmap, rMaskBitmap ); + drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap ); } - drawMaskedBitmap( pPosAry, rSrcBitmap, rMaskBitmap ); + drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap ); } -void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, +void X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransBitmap ) { @@ -519,10 +519,10 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, const sal_uInt16 nDepth( m_pVDev ? m_pVDev->GetDepth() : pSalDisp->GetVisual( m_nXScreen ).GetDepth() ); - Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth, - pPosAry->mnDestHeight, nDepth ) ); - Pixmap aBG( limitXCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth, - pPosAry->mnDestHeight, nDepth ) ); + Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth, + rPosAry.mnDestHeight, nDepth ) ); + Pixmap aBG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth, + rPosAry.mnDestHeight, nDepth ) ); if( aFG && aBG ) { @@ -531,7 +531,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, const SalColormap& rColMap = pSalDisp->GetColormap( m_nXScreen ); const int nBlack = rColMap.GetBlackPixel(), nWhite = rColMap.GetWhitePixel(); const int nValues = GCFunction | GCForeground | GCBackground; - SalTwoRect aTmpRect( *pPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0; + SalTwoRect aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0; // draw paint bitmap in pixmap #1 aValues.function = GXcopy, aValues.foreground = nWhite, aValues.background = nBlack; @@ -541,8 +541,8 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, // draw background in pixmap #2 XCopyArea( pXDisp, aDrawable, aBG, aTmpGC, - pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, + rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestWidth, rPosAry.mnDestHeight, 0, 0 ); DBG_TESTTRANS( aBG ); @@ -570,7 +570,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, XChangeGC( pXDisp, aTmpGC, nValues, &aValues ); XCopyArea( pXDisp, aFG, aBG, aTmpGC, 0, 0, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, + rPosAry.mnDestWidth, rPosAry.mnDestHeight, 0, 0 ); DBG_TESTTRANS( aBG ); @@ -581,8 +581,8 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, // copy pixmap #2 (result) to background XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(), 0, 0, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnDestWidth, rPosAry.mnDestHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); DBG_TESTTRANS( aBG ); @@ -592,7 +592,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, XFlush( pXDisp ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); if( aFG ) XFreePixmap( pXDisp, aFG ); @@ -728,6 +728,18 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, return true; } +bool X11SalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -757,14 +769,14 @@ bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, return true; } -void X11SalGraphics::drawBitmap( const SalTwoRect*, +void X11SalGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { OSL_FAIL( "::DrawBitmap with transparent color not supported" ); } -void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, +void X11SalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap &rSalBitmap, SalColor nMaskColor ) { @@ -772,12 +784,12 @@ void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, Display* pXDisp = pSalDisp->GetDisplay(); Drawable aDrawable( GetDrawable() ); Pixmap aStipple( limitXCreatePixmap( pXDisp, aDrawable, - pPosAry->mnDestWidth, - pPosAry->mnDestHeight, 1 ) ); + rPosAry.mnDestWidth, + rPosAry.mnDestHeight, 1 ) ); if( aStipple ) { - SalTwoRect aTwoRect( *pPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0; + SalTwoRect aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0; GC aTmpGC; XGCValues aValues; @@ -791,19 +803,19 @@ void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, // Set stipple and draw rectangle GC aStippleGC( GetStippleGC() ); - int nX = pPosAry->mnDestX, nY = pPosAry->mnDestY; + int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY; XSetStipple( pXDisp, aStippleGC, aStipple ); XSetTSOrigin( pXDisp, aStippleGC, nX, nY ); XSetForeground( pXDisp, aStippleGC, GetPixel( nMaskColor ) ); XFillRectangle( pXDisp, aDrawable, aStippleGC, nX, nY, - pPosAry->mnDestWidth, pPosAry->mnDestHeight ); + rPosAry.mnDestWidth, rPosAry.mnDestHeight ); XFreePixmap( pXDisp, aStipple ); XFlush( pXDisp ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 1dc547863e4a..bdc5ede7682a 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -521,7 +521,7 @@ bool GtkSalGraphics::setClipRegion( const Region& i_rClip ) return bRet; } -void GtkSalGraphics::copyBits( const SalTwoRect* pPosAry, +void GtkSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { GtkSalFrame* pFrame = GetGtkFrame(); @@ -539,7 +539,7 @@ void GtkSalGraphics::copyBits( const SalTwoRect* pPosAry, None ); } } - X11SalGraphics::copyBits( pPosAry, pSrcGraphics ); + X11SalGraphics::copyBits( rPosAry, pSrcGraphics ); if( pFrame && pFrame->getBackgroundPixmap() != None ) XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(), aWin, diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx index b4679bfa2245..a00dfded7e09 100644 --- a/vcl/win/source/gdi/salbmp.cxx +++ b/vcl/win/source/gdi/salbmp.cxx @@ -19,21 +19,22 @@ #include <svsys.h> - #include <vcl/bitmap.hxx> // for BitmapSystemData #include <vcl/salbtype.hxx> #include <com/sun/star/beans/XFastPropertySet.hpp> - #include <win/wincomp.hxx> #include <win/salgdi.h> #include <win/saldata.hxx> #include <win/salbmp.h> - #include <string.h> +#include <vcl/timer.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <map> + +#include <gdiplus.h> -// ----------- +// ------------------------------------------------------------------ // - Inlines - -// ----------- inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex ) { @@ -43,14 +44,139 @@ inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex ) ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) ); } -// ---------------- +// ------------------------------------------------------------------ +// Helper class to manage Gdiplus::Bitmap instances inside of +// WinSalBitmap + +struct Comparator +{ + bool operator()(WinSalBitmap* pA, WinSalBitmap* pB) const + { + return pA < pB; + } +}; + +typedef ::std::map< WinSalBitmap*, sal_uInt32, Comparator > EntryMap; +static const sal_uInt32 nDefaultCycles(60); + +class GdiPlusBuffer : protected comphelper::OBaseMutex, public Timer +{ +private: + EntryMap maEntries; + +public: + GdiPlusBuffer() + : Timer(), + maEntries() + { + SetTimeout(1000); + Stop(); + } + + ~GdiPlusBuffer() + { + Stop(); + } + + void addEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound == maEntries.end()) + { + if(maEntries.empty()) + { + Start(); + } + + maEntries[&rEntry] = nDefaultCycles; + } + } + + void remEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound != maEntries.end()) + { + maEntries.erase(aFound); + + if(maEntries.empty()) + { + Stop(); + } + } + } + + void touchEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound != maEntries.end()) + { + aFound->second = nDefaultCycles; + } + } + + // from parent Timer + virtual void Timeout() + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aIter(maEntries.begin()); + + while(aIter != maEntries.end()) + { + if(aIter->second) + { + aIter->second--; + aIter++; + } + else + { + EntryMap::iterator aDelete(aIter); + WinSalBitmap* pSource = aDelete->first; + aIter++; + maEntries.erase(aDelete); + + if(maEntries.empty()) + { + Stop(); + } + + // delete at WinSalBitmap after entry is removed; this + // way it would not hurt to call remEntry from there, too + if(pSource->maGdiPlusBitmap.get()) + { + pSource->maGdiPlusBitmap.reset(); + } + } + } + + if(!maEntries.empty()) + { + Start(); + } + } +}; + +// ------------------------------------------------------------------ +// Global instance of GdiPlusBuffer which manages Gdiplus::Bitmap +// instances + +static GdiPlusBuffer aGdiPlusBuffer; + +// ------------------------------------------------------------------ // - WinSalBitmap - -// ---------------- -WinSalBitmap::WinSalBitmap() : - mhDIB ( 0 ), - mhDDB ( 0 ), - mnBitCount ( 0 ) +WinSalBitmap::WinSalBitmap() +: maSize(), + mhDIB(0), + mhDDB(0), + maGdiPlusBitmap(), + mnBitCount(0) { } @@ -63,6 +189,292 @@ WinSalBitmap::~WinSalBitmap() // ------------------------------------------------------------------ +void WinSalBitmap::Destroy() +{ + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.remEntry(*this); + } + + if( mhDIB ) + GlobalFree( mhDIB ); + else if( mhDDB ) + DeleteObject( mhDDB ); + + maSize = Size(); + mnBitCount = 0; +} + +// ------------------------------------------------------------------ + +GdiPlusBmpPtr WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const +{ + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.touchEntry(const_cast< WinSalBitmap& >(*this)); + } + else + { + if(maSize.Width() > 0 && maSize.Height() > 0) + { + WinSalBitmap* pThat = const_cast< WinSalBitmap* >(this); + + if(pAlphaSource) + { + pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap(*pAlphaSource)); + } + else + { + pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap()); + } + + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.addEntry(*pThat); + } + } + } + + return maGdiPlusBitmap; +} + +// ------------------------------------------------------------------ + +Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap() +{ + Gdiplus::Bitmap* pRetval(0); + WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this); + WinSalBitmap* pExtraWinSalRGB = 0; + + if(!pSalRGB->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalRGB = new WinSalBitmap(); + pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount()); + pSalRGB = pExtraWinSalRGB; + } + + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pExtraRGB = 0; + + if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight; + + pExtraRGB = StretchAndConvert( + *pRGB, + aSalTwoRect, + BMP_FORMAT_24BIT_TC_BGR, + 0); + + pSalRGB->ReleaseBuffer(pRGB, true); + pRGB = pExtraRGB; + } + + if(pRGB + && pRGB->mnWidth > 0 + && pRGB->mnHeight > 0 + && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + const sal_uInt32 nW(pRGB->mnWidth); + const sal_uInt32 nH(pRGB->mnHeight); + + pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat24bppRGB); + + if(pRetval) + { + sal_uInt8* pSrcRGB(pRGB->mpBits); + const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); + const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN); + + for(sal_uInt32 y(0); y < nH; y++) + { + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + + for(sal_uInt32 x(0); x < nW; x++) + { + const sal_uInt8 nB(*pSrcRGB++); + const sal_uInt8 nG(*pSrcRGB++); + const sal_uInt8 nR(*pSrcRGB++); + + pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nR, nG, nB)); + } + + pSrcRGB += nExtraRGB; + } + } + } + + if(pExtraRGB) + { + delete pExtraRGB; + } + else + { + pSalRGB->ReleaseBuffer(pRGB, true); + } + + if(pExtraWinSalRGB) + { + delete pExtraWinSalRGB; + } + + return pRetval; +} + +// ------------------------------------------------------------------ + +Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource) +{ + Gdiplus::Bitmap* pRetval(0); + WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this); + WinSalBitmap* pExtraWinSalRGB = 0; + + if(!pSalRGB->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalRGB = new WinSalBitmap(); + pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount()); + pSalRGB = pExtraWinSalRGB; + } + + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pExtraRGB = 0; + + if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight; + + pExtraRGB = StretchAndConvert( + *pRGB, + aSalTwoRect, + BMP_FORMAT_24BIT_TC_BGR, + 0); + + pSalRGB->ReleaseBuffer(pRGB, true); + pRGB = pExtraRGB; + } + + WinSalBitmap* pSalA = const_cast< WinSalBitmap* >(&rAlphaSource); + WinSalBitmap* pExtraWinSalA = 0; + + if(!pSalA->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalA = new WinSalBitmap(); + pExtraWinSalA->Create(*pSalA, pSalA->GetBitCount()); + pSalA = pExtraWinSalA; + } + + BitmapBuffer* pA = pSalA->AcquireBuffer(true); + BitmapBuffer* pExtraA = 0; + + if(pA && BMP_FORMAT_8BIT_PAL != (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert alpha bitmap to BMP_FORMAT_8BIT_PAL format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pA->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pA->mnHeight; + const BitmapPalette& rTargetPalette = Bitmap::GetGreyPalette(256); + + pExtraA = StretchAndConvert( + *pA, + aSalTwoRect, + BMP_FORMAT_8BIT_PAL, + &rTargetPalette); + + pSalA->ReleaseBuffer(pA, true); + pA = pExtraA; + } + + if(pRGB + && pA + && pRGB->mnWidth > 0 + && pRGB->mnHeight > 0 + && pRGB->mnWidth == pA->mnWidth + && pRGB->mnHeight == pA->mnHeight + && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN) + && BMP_FORMAT_8BIT_PAL == (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // we have alpha and bitmap in known formats, create GdiPlus Bitmap as 32bit ARGB + const sal_uInt32 nW(pRGB->mnWidth); + const sal_uInt32 nH(pRGB->mnHeight); + + pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat32bppARGB); + + if(pRetval) + { + sal_uInt8* pSrcRGB(pRGB->mpBits); + sal_uInt8* pSrcA(pA->mpBits); + const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); + const sal_uInt32 nExtraA(pA->mnScanlineSize - nW); + const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN); + + for(sal_uInt32 y(0); y < nH; y++) + { + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + + for(sal_uInt32 x(0); x < nW; x++) + { + const sal_uInt8 nB(*pSrcRGB++); + const sal_uInt8 nG(*pSrcRGB++); + const sal_uInt8 nR(*pSrcRGB++); + const sal_uInt8 nA(0xff - *pSrcA++); + + pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nA, nR, nG, nB)); + } + + pSrcRGB += nExtraRGB; + pSrcA += nExtraA; + } + } + } + + if(pExtraA) + { + delete pExtraA; + } + else + { + pSalA->ReleaseBuffer(pA, true); + } + + if(pExtraWinSalA) + { + delete pExtraWinSalA; + } + + if(pExtraRGB) + { + delete pExtraRGB; + } + else + { + pSalRGB->ReleaseBuffer(pRGB, true); + } + + if(pExtraWinSalRGB) + { + delete pExtraWinSalRGB; + } + + return pRetval; +} + +// ------------------------------------------------------------------ + bool WinSalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle ) { bool bRet = TRUE; @@ -172,7 +584,7 @@ bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) { PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB ); PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI; - HDC hDC = pGraphics->mhDC; + HDC hDC = pGraphics->getHDC(); HBITMAP hNewDDB; BITMAP aDDBInfo; PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI + @@ -278,21 +690,6 @@ bool WinSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::s return false; } -// ------------------------------------------------------------------ - -void WinSalBitmap::Destroy() -{ - if( mhDIB ) - GlobalFree( mhDIB ); - else if( mhDDB ) - DeleteObject( mhDDB ); - - maSize = Size(); - mnBitCount = 0; -} - -// ------------------------------------------------------------------ - sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB ) { sal_uInt16 nColors = 0; diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 4287f0b6d84e..86b99be0ea8d 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -513,16 +513,16 @@ void ImplSalInitGraphics( WinSalGraphics* pData ) // calculate the minimal line width for the printer if ( pData->mbPrinter ) { - int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX ); + int nDPIX = GetDeviceCaps( pData->getHDC(), LOGPIXELSX ); if ( nDPIX <= 300 ) pData->mnPenWidth = 0; else pData->mnPenWidth = nDPIX/300; } - ::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP ); - ::SetBkMode( pData->mhDC, TRANSPARENT ); - ::SetROP2( pData->mhDC, R2_COPYPEN ); + ::SetTextAlign( pData->getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP ); + ::SetBkMode( pData->getHDC(), TRANSPARENT ); + ::SetROP2( pData->getHDC(), R2_COPYPEN ); } // ----------------------------------------------------------------------- @@ -530,14 +530,14 @@ void ImplSalInitGraphics( WinSalGraphics* pData ) void ImplSalDeInitGraphics( WinSalGraphics* pData ) { // clear clip region - SelectClipRgn( pData->mhDC, 0 ); + SelectClipRgn( pData->getHDC(), 0 ); // select default objects if ( pData->mhDefPen ) - SelectPen( pData->mhDC, pData->mhDefPen ); + SelectPen( pData->getHDC(), pData->mhDefPen ); if ( pData->mhDefBrush ) - SelectBrush( pData->mhDC, pData->mhDefBrush ); + SelectBrush( pData->getHDC(), pData->mhDefBrush ); if ( pData->mhDefFont ) - SelectFont( pData->mhDC, pData->mhDefFont ); + SelectFont( pData->getHDC(), pData->mhDefFont ); } // ======================================================================= @@ -723,7 +723,7 @@ WinSalGraphics::WinSalGraphics() mfCurrentFontScale = 1.0; - mhDC = 0; + mhLocalDC = 0; mhPen = 0; mhBrush = 0; mhRegion = 0; @@ -782,8 +782,8 @@ WinSalGraphics::~WinSalGraphics() void WinSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) { - rDPIX = GetDeviceCaps( mhDC, LOGPIXELSX ); - rDPIY = GetDeviceCaps( mhDC, LOGPIXELSY ); + rDPIX = GetDeviceCaps( getHDC(), LOGPIXELSX ); + rDPIY = GetDeviceCaps( getHDC(), LOGPIXELSY ); // #111139# this fixes the symptom of div by zero on startup // however, printing will fail most likely as communication with @@ -796,7 +796,7 @@ void WinSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) sal_uInt16 WinSalGraphics::GetBitCount() const { - return (sal_uInt16)GetDeviceCaps( mhDC, BITSPIXEL ); + return (sal_uInt16)GetDeviceCaps( getHDC(), BITSPIXEL ); } // ----------------------------------------------------------------------- @@ -833,7 +833,7 @@ void WinSalGraphics::ResetClipRegion() mhRegion = 0; } - SelectClipRgn( mhDC, 0 ); + SelectClipRgn( getHDC(), 0 ); } // ----------------------------------------------------------------------- @@ -1041,7 +1041,7 @@ bool WinSalGraphics::setClipRegion( const Region& i_rClip ) } if( mhRegion ) - SelectClipRgn( mhDC, mhRegion ); + SelectClipRgn( getHDC(), mhRegion ); return mhRegion != 0; } @@ -1051,7 +1051,7 @@ void WinSalGraphics::SetLineColor() { // create and select new pen HPEN hNewPen = GetStockPen( NULL_PEN ); - HPEN hOldPen = SelectPen( mhDC, hNewPen ); + HPEN hOldPen = SelectPen( getHDC(), hNewPen ); // destroy or save old pen if ( mhPen ) @@ -1109,7 +1109,7 @@ void WinSalGraphics::SetLineColor( SalColor nSalColor ) } // select new pen - HPEN hOldPen = SelectPen( mhDC, hNewPen ); + HPEN hOldPen = SelectPen( getHDC(), hNewPen ); // destroy or save old pen if ( mhPen ) @@ -1133,7 +1133,7 @@ void WinSalGraphics::SetFillColor() { // create and select new brush HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH ); - HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush ); // destroy or save old brush if ( mhBrush ) @@ -1237,7 +1237,7 @@ void WinSalGraphics::SetFillColor( SalColor nSalColor ) } // select new brush - HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush ); // destroy or save old brush if ( mhBrush ) @@ -1260,7 +1260,7 @@ void WinSalGraphics::SetFillColor( SalColor nSalColor ) void WinSalGraphics::SetXORMode( bool bSet, bool ) { mbXORMode = bSet; - ::SetROP2( mhDC, bSet ? R2_XORPEN : R2_COPYPEN ); + ::SetROP2( getHDC(), bSet ? R2_XORPEN : R2_COPYPEN ); } // ----------------------------------------------------------------------- @@ -1284,13 +1284,13 @@ void WinSalGraphics::drawPixel( long nX, long nY ) if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( mnPenColor ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - SetPixel( mhDC, (int)nX, (int)nY, mnPenColor ); + SetPixel( getHDC(), (int)nX, (int)nY, mnPenColor ); } // ----------------------------------------------------------------------- @@ -1309,20 +1309,20 @@ void WinSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( nCol ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - ::SetPixel( mhDC, (int)nX, (int)nY, nCol ); + ::SetPixel( getHDC(), (int)nX, (int)nY, nCol ); } // ----------------------------------------------------------------------- void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) { - MoveToEx( mhDC, (int)nX1, (int)nY1, NULL ); + MoveToEx( getHDC(), (int)nX1, (int)nY1, NULL ); // we must paint the endpoint int bPaintEnd = TRUE; @@ -1343,20 +1343,20 @@ void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) nX2--; } - LineTo( mhDC, (int)nX2, (int)nY2 ); + LineTo( getHDC(), (int)nX2, (int)nY2 ); if ( bPaintEnd && !mbPrinter ) { if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( mnPenColor ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - SetPixel( mhDC, (int)nX2, (int)nY2, mnPenColor ); + SetPixel( getHDC(), (int)nX2, (int)nY2, mnPenColor ); } } @@ -1368,7 +1368,7 @@ void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) { if ( !mbPrinter ) { - PatBlt( mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight, + PatBlt( getHDC(), (int)nX, (int)nY, (int)nWidth, (int)nHeight, mbXORMode ? PATINVERT : PATCOPY ); } else @@ -1378,11 +1378,11 @@ void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) aWinRect.top = nY; aWinRect.right = nX+nWidth; aWinRect.bottom = nY+nHeight; - ::FillRect( mhDC, &aWinRect, mhBrush ); + ::FillRect( getHDC(), &aWinRect, mhBrush ); } } else - WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); + WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); } // ----------------------------------------------------------------------- @@ -1416,21 +1416,21 @@ void WinSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry ) } // for Windows 95 and its maximum number of points - if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); if ( bPaintEnd && !mbPrinter ) { if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( mnPenColor ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - SetPixel( mhDC, (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), mnPenColor ); + SetPixel( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), mnPenColor ); } } @@ -1444,8 +1444,8 @@ void WinSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry ) POINT* pWinPtAry = (POINT*)pPtAry; // for Windows 95 and its maximum number of points - if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } // ----------------------------------------------------------------------- @@ -1491,7 +1491,7 @@ void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoint n += nPoints; } - if ( !WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) && + if ( !WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) && (nPolyPolyPoints > MAX_64KSALPOINTS) ) { nPolyPolyPoints = 0; @@ -1506,9 +1506,9 @@ void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoint if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS ) pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS; if ( nPoly == 1 ) - WIN_Polygon( mhDC, pWinPointAryAry, *pWinPointAry ); + WIN_Polygon( getHDC(), pWinPointAryAry, *pWinPointAry ); else - WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly ); + WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, nPoly ); } if ( pWinPointAry != aWinPointAry ) @@ -1530,7 +1530,7 @@ sal_Bool WinSalGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ), "WinSalGraphics::DrawPolyLineBezier(): POINT != SalPoint" ); - ImplRenderPath( mhDC, nPoints, pPtAry, pFlgAry ); + ImplRenderPath( getHDC(), nPoints, pPtAry, pFlgAry ); return sal_True; #else @@ -1567,13 +1567,13 @@ sal_Bool WinSalGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* p sal_Bool bRet( sal_False ); - if( BeginPath( mhDC ) ) + if( BeginPath( getHDC() ) ) { - PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nPoints); + PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nPoints); - if( EndPath( mhDC ) ) + if( EndPath( getHDC() ) ) { - if( StrokeAndFillPath( mhDC ) ) + if( StrokeAndFillPath( getHDC() ) ) bRet = sal_True; } } @@ -1624,13 +1624,13 @@ sal_Bool WinSalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt sal_Bool bRet( sal_False ); - if( BeginPath( mhDC ) ) + if( BeginPath( getHDC() ) ) { - PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nTotalPoints); + PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nTotalPoints); - if( EndPath( mhDC ) ) + if( EndPath( getHDC() ) ) { - if( StrokeAndFillPath( mhDC ) ) + if( StrokeAndFillPath( getHDC() ) ) bRet = sal_True; } } @@ -1738,7 +1738,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v { int nEscape = POSTSCRIPT_PASSTHROUGH; - if ( Escape( mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) ) + if ( Escape( getHDC(), QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) ) { double nBoundingBox[4]; @@ -1825,7 +1825,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v // #107797# Write out buffer // ---------------------------------------------------------------------------------- *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); // #107797# Write out EPS transformation code @@ -1845,7 +1845,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v aBuf.append( "] concat\n" "%%BeginDocument:\n" ); *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); // #107797# Write out actual EPS content @@ -1861,7 +1861,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v // of size POSTSCRIPT_BUFSIZE at construction time of aBuf *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)nDoNow; memcpy( (void*)(aBuf.getStr() + 2), (BYTE*)pPtr + nSize - nToDo, nDoNow ); - sal_uLong nResult = Escape ( mhDC, nEscape, nDoNow + 2, (LPTSTR)aBuf.getStr(), 0 ); + sal_uLong nResult = Escape ( getHDC(), nEscape, nDoNow + 2, (LPTSTR)aBuf.getStr(), 0 ); if (!nResult ) break; nToDo -= nResult; @@ -1877,7 +1877,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v "countdictstack dict_count_salWin sub {end} repeat\n" "b4_Inc_state_salWin restore\n\n" ); *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); bRetValue = TRUE; } } @@ -1892,7 +1892,7 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const { SystemGraphicsData aRes; aRes.nSize = sizeof(aRes); - aRes.hDC = mhDC; + aRes.hDC = const_cast< WinSalGraphics* >(this)->getHDC(); return aRes; } diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx index 3455c9c5e506..2585d136a790 100644 --- a/vcl/win/source/gdi/salgdi2.cxx +++ b/vcl/win/source/gdi/salgdi2.cxx @@ -57,42 +57,42 @@ bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const // ======================================================================= -void WinSalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) +void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { HDC hSrcDC; DWORD nRop; if ( pSrcGraphics ) - hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->mhDC; + hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC(); else - hSrcDC = mhDC; + hSrcDC = getHDC(); if ( mbXORMode ) nRop = SRCINVERT; else nRop = SRCCOPY; - if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && - (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) + if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) { - BitBlt( mhDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + BitBlt( getHDC(), + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hSrcDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, nRop ); } else { - int nOldStretchMode = SetStretchBltMode( mhDC, STRETCH_DELETESCANS ); - StretchBlt( mhDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS ); + StretchBlt( getHDC(), + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hSrcDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, nRop ); - SetStretchBltMode( mhDC, nOldStretchMode ); + SetStretchBltMode( getHDC(), nOldStretchMode ); } } @@ -282,19 +282,19 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // 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( mhDC, hOldClipRgn ); + nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn ); bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate - ExtSelectClipRgn( mhDC, hInvalidateRgn, RGN_DIFF ); + ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF ); } } } } - BitBlt( mhDC, + BitBlt( getHDC(), (int)nDestX, (int)nDestY, (int)nSrcWidth, (int)nSrcHeight, - mhDC, + getHDC(), (int)nSrcX, (int)nSrcY, SRCCOPY ); @@ -302,7 +302,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, { // restore old clip region if( nOldClipRgnType != ERROR ) - SelectClipRgn( mhDC, hOldClipRgn); + SelectClipRgn( getHDC(), hOldClipRgn); DeleteRegion( hOldClipRgn ); // invalidate regions that were not copied @@ -310,7 +310,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // Combine Invalidate Region with existing ClipRegion HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 ); - if ( GetClipRgn( mhDC, hTempRgn ) == 1 ) + if ( GetClipRgn( getHDC(), hTempRgn ) == 1 ) { int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND ); if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) ) @@ -338,7 +338,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // ----------------------------------------------------------------------- void ImplDrawBitmap( HDC hDC, - const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap, + const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap, sal_Bool bPrinter, int nDrawMode ) { if( hDC ) @@ -366,10 +366,10 @@ void ImplDrawBitmap( HDC hDC, const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); StretchDIBits( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, - (int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY), - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (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 ); @@ -404,14 +404,14 @@ void ImplDrawBitmap( HDC hDC, nOldTextColor = ::SetTextColor( hDC, nTextColor ); } - if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && - (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) + if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) { BitBlt( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hBmpDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, nDrawMode ); } else @@ -419,11 +419,11 @@ void ImplDrawBitmap( HDC hDC, const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); StretchBlt( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hBmpDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, nDrawMode ); SetStretchBltMode( hDC, nOldStretchMode ); @@ -445,17 +445,36 @@ void ImplDrawBitmap( HDC hDC, // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap ) +void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) { - ImplDrawBitmap( mhDC, pPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), - mbPrinter, - mbXORMode ? SRCINVERT : SRCCOPY ); + 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 ); } // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nTransparentColor ) { @@ -504,28 +523,46 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE ) if( pMask->Create( hMaskBitmap, FALSE, FALSE ) ) - drawBitmap( pPosAry, rSalBitmap, *pMask ); + drawBitmap( rPosAry, rSalBitmap, *pMask ); delete pMask; } // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +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 = *pPosAry; + 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 = mhDC; + HDC hDC = getHDC(); HBITMAP hMemBitmap = 0; HBITMAP hMaskBitmap = 0; @@ -548,17 +585,17 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, WinSalBitmap aTmp; if( aTmp.Create( rTransparentBitmap, this ) ) - ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY ); + ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY ); } else - ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); + 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 ); + 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 @@ -567,7 +604,7 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, { 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 ); + 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 @@ -588,19 +625,6 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, // ----------------------------------------------------------------------- -bool WinSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, - const SalBitmap& rSrcBitmap, - const SalBitmap& rAlphaBmp ) -{ - (void)rTR; (void)rSrcBitmap; (void)rAlphaBmp; - - // TODO(P3): implement alpha bmp blits. Catch: Windows only - // handles 32bpp, premultiplied bitmaps - return false; -} - -// ----------------------------------------------------------------------- - bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -619,7 +643,7 @@ bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, // hMemDC contains a 1x1 bitmap of the right color - stretch-blit // that to dest hdc - bool bRet = AlphaBlend( mhDC, nX, nY, nWidth, nHeight, + bool bRet = AlphaBlend( getHDC(), nX, nY, nWidth, nHeight, hMemDC, 0,0,1,1, aFunc ) == TRUE; @@ -630,7 +654,7 @@ bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, // ----------------------------------------------------------------------- -void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, +void WinSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nMaskColor ) { @@ -638,11 +662,11 @@ void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - SalTwoRect aPosAry = *pPosAry; + SalTwoRect aPosAry = rPosAry; const BYTE cRed = SALCOLOR_RED( nMaskColor ); const BYTE cGreen = SALCOLOR_GREEN( nMaskColor ); const BYTE cBlue = SALCOLOR_BLUE( nMaskColor ); - HDC hDC = mhDC; + HDC hDC = getHDC(); HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) ); HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush ); @@ -653,10 +677,10 @@ void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, WinSalBitmap aTmp; if( aTmp.Create( rSalBitmap, this ) ) - ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL ); } else - ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); SelectBrush( hDC, hOldBrush ); DeleteBrush( hMaskBrush ); @@ -673,7 +697,7 @@ SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) nDX = labs( nDX ); nDY = labs( nDY ); - HDC hDC = mhDC; + HDC hDC = getHDC(); HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); sal_Bool bRet; @@ -704,7 +728,7 @@ SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) SalColor WinSalGraphics::getPixel( long nX, long nY ) { - COLORREF aWinCol = ::GetPixel( mhDC, (int) nX, (int) nY ); + COLORREF aWinCol = ::GetPixel( getHDC(), (int) nX, (int) nY ); if ( CLR_INVALID == aWinCol ) return MAKE_SALCOLOR( 0, 0, 0 ); @@ -721,15 +745,15 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv if ( nFlags & SAL_INVERT_TRACKFRAME ) { HPEN hDotPen = CreatePen( PS_DOT, 0, 0 ); - HPEN hOldPen = SelectPen( mhDC, hDotPen ); - HBRUSH hOldBrush = SelectBrush( mhDC, GetStockBrush( NULL_BRUSH ) ); - int nOldROP = SetROP2( mhDC, R2_NOT ); + HPEN hOldPen = SelectPen( getHDC(), hDotPen ); + HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) ); + int nOldROP = SetROP2( getHDC(), R2_NOT ); - WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); + WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); - SetROP2( mhDC, nOldROP ); - SelectPen( mhDC, hOldPen ); - SelectBrush( mhDC, hOldBrush ); + SetROP2( getHDC(), nOldROP ); + SelectPen( getHDC(), hOldPen ); + SelectBrush( getHDC(), hOldBrush ); DeletePen( hDotPen ); } else if ( nFlags & SAL_INVERT_50 ) @@ -742,11 +766,11 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); } - COLORREF nOldTextColor = ::SetTextColor( mhDC, 0 ); - HBRUSH hOldBrush = SelectBrush( mhDC, pSalData->mh50Brush ); - PatBlt( mhDC, nX, nY, nWidth, nHeight, PATINVERT ); - ::SetTextColor( mhDC, nOldTextColor ); - SelectBrush( mhDC, hOldBrush ); + 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 { @@ -755,7 +779,7 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv aRect.top = (int)nY; aRect.right = (int)nX+nWidth; aRect.bottom = (int)nY+nHeight; - ::InvertRect( mhDC, &aRect ); + ::InvertRect( getHDC(), &aRect ); } } @@ -768,7 +792,7 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver HBRUSH hBrush; HBRUSH hOldBrush = 0; COLORREF nOldTextColor RGB(0,0,0); - int nOldROP = SetROP2( mhDC, R2_NOT ); + int nOldROP = SetROP2( getHDC(), R2_NOT ); if ( nSalFlags & SAL_INVERT_TRACKFRAME ) hPen = CreatePen( PS_DOT, 0, 0 ); @@ -791,10 +815,10 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver hBrush = GetStockBrush( BLACK_BRUSH ); hPen = GetStockPen( NULL_PEN ); - nOldTextColor = ::SetTextColor( mhDC, 0 ); - hOldBrush = SelectBrush( mhDC, hBrush ); + nOldTextColor = ::SetTextColor( getHDC(), 0 ); + hOldBrush = SelectBrush( getHDC(), hBrush ); } - hOldPen = SelectPen( mhDC, hPen ); + hOldPen = SelectPen( getHDC(), hPen ); POINT* pWinPtAry; // for NT, we can handover the array directly @@ -805,24 +829,24 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver // for Windows 95 and its maximum number of points if ( nSalFlags & SAL_INVERT_TRACKFRAME ) { - if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } else { - if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } - SetROP2( mhDC, nOldROP ); - SelectPen( mhDC, hOldPen ); + SetROP2( getHDC(), nOldROP ); + SelectPen( getHDC(), hOldPen ); if ( nSalFlags & SAL_INVERT_TRACKFRAME ) DeletePen( hPen ); else { - ::SetTextColor( mhDC, nOldTextColor ); - SelectBrush( mhDC, hOldBrush ); + ::SetTextColor( getHDC(), nOldTextColor ); + SelectBrush( getHDC(), hOldBrush ); } } diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 625ee1a0ea1a..2442a1e92db6 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -1422,7 +1422,7 @@ void WinSalGraphics::SetTextColor( SalColor nSalColor ) aCol = PALRGB_TO_RGB( aCol ); } - ::SetTextColor( mhDC, aCol ); + ::SetTextColor( getHDC(), aCol ); } // ----------------------------------------------------------------------- @@ -1520,7 +1520,7 @@ HFONT WinSalGraphics::ImplDoSetFont( FontSelectPattern* i_pFont, float& o_rFontS hdcScreen = GetDC(0); LOGFONTW aLogFont; - ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true ); + ImplGetLogFontFromFontSelect( getHDC(), i_pFont, aLogFont, true ); // on the display we prefer Courier New when Courier is a // bitmap only font and we need to stretch or rotate it @@ -1562,17 +1562,17 @@ HFONT WinSalGraphics::ImplDoSetFont( FontSelectPattern* i_pFont, float& o_rFontS // "PRB: Fonts Not Drawn Antialiased on Device Context for DirectDraw Surface" SelectFont( hdcScreen, SelectFont( hdcScreen , hNewFont ) ); } - o_rOldFont = ::SelectFont( mhDC, hNewFont ); + o_rOldFont = ::SelectFont( getHDC(), hNewFont ); TEXTMETRICW aTextMetricW; - if( !::GetTextMetricsW( mhDC, &aTextMetricW ) ) + if( !::GetTextMetricsW( getHDC(), &aTextMetricW ) ) { // the selected font doesn't work => try a replacement // TODO: use its font fallback instead lstrcpynW( aLogFont.lfFaceName, L"Courier New", 11 ); aLogFont.lfPitchAndFamily = FIXED_PITCH; HFONT hNewFont2 = CreateFontIndirectW( &aLogFont ); - SelectFont( mhDC, hNewFont2 ); + SelectFont( getHDC(), hNewFont2 ); DeleteFont( hNewFont ); hNewFont = hNewFont2; } @@ -1590,7 +1590,7 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* pFont, int nFallbackLevel { // deselect still active font if( mhDefFont ) - ::SelectFont( mhDC, mhDefFont ); + ::SelectFont( getHDC(), mhDefFont ); mfCurrentFontScale = mfFontScale[nFallbackLevel]; // release no longer referenced font handles for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) @@ -1633,7 +1633,7 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* pFont, int nFallbackLevel mhFonts[ nFallbackLevel ] = hNewFont; // now the font is live => update font face if( mpWinFontData[ nFallbackLevel ] ) - mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( mhDC ); + mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() ); if( !nFallbackLevel ) { @@ -1662,17 +1662,17 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* pFont, int nFallbackLevel void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { // temporarily change the HDC to the font in the fallback level - HFONT hOldFont = SelectFont( mhDC, mhFonts[nFallbackLevel] ); + HFONT hOldFont = SelectFont( getHDC(), mhFonts[nFallbackLevel] ); wchar_t aFaceName[LF_FACESIZE+60]; - if( ::GetTextFaceW( mhDC, sizeof(aFaceName)/sizeof(wchar_t), aFaceName ) ) + if( ::GetTextFaceW( getHDC(), sizeof(aFaceName)/sizeof(wchar_t), aFaceName ) ) pMetric->SetFamilyName( String().Assign( reinterpret_cast<const sal_Unicode*>(aFaceName))); // get the font metric TEXTMETRICA aWinMetric; - const bool bOK = GetTextMetricsA( mhDC, &aWinMetric ); + const bool bOK = GetTextMetricsA( getHDC(), &aWinMetric ); // restore the HDC to the font in the base level - SelectFont( mhDC, hOldFont ); + SelectFont( getHDC(), hOldFont ); if( !bOK ) return; @@ -1691,7 +1691,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe { // check if there are kern pairs // TODO: does this work with GPOS kerning? - DWORD nKernPairs = ::GetKerningPairsA( mhDC, 0, NULL ); + DWORD nKernPairs = ::GetKerningPairsA( getHDC(), 0, NULL ); pMetric->mbKernableFont = (nKernPairs > 0); } else @@ -1752,13 +1752,13 @@ sal_uLong WinSalGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData* pKer mnFontKernPairCount = 0; KERNINGPAIR* pPairs = NULL; - int nCount = ::GetKerningPairsW( mhDC, 0, NULL ); + int nCount = ::GetKerningPairsW( getHDC(), 0, NULL ); if( nCount ) { pPairs = new KERNINGPAIR[ nCount+1 ]; mpFontKernPairs = pPairs; mnFontKernPairCount = nCount; - ::GetKerningPairsW( mhDC, nCount, pPairs ); + ::GetKerningPairsW( getHDC(), nCount, pPairs ); } mbFontKernInit = FALSE; @@ -2217,7 +2217,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) } ImplEnumInfo aInfo; - aInfo.mhDC = mhDC; + aInfo.mhDC = getHDC(); aInfo.mpList = pFontList; aInfo.mpName = NULL; aInfo.mpLogFontA = NULL; @@ -2246,7 +2246,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) memset( &aLogFont, 0, sizeof( aLogFont ) ); aLogFont.lfCharSet = DEFAULT_CHARSET; aInfo.mpLogFontW = &aLogFont; - EnumFontFamiliesExW( mhDC, &aLogFont, + EnumFontFamiliesExW( getHDC(), &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW, (LPARAM)(void*)&aInfo, 0 ); // check what Courier fonts are used on the screen, so to perhaps @@ -2258,7 +2258,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) } // set glyph fallback hook - static WinGlyphFallbackSubstititution aSubstFallback( mhDC ); + static WinGlyphFallbackSubstititution aSubstFallback( getHDC() ); pFontList->SetFallbackHook( &aSubstFallback ); } @@ -2276,7 +2276,7 @@ void WinSalGraphics::GetDevFontSubstList( OutputDevice* ) sal_Bool WinSalGraphics::GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& rRect ) { - HDC hDC = mhDC; + HDC hDC = getHDC(); // use unity matrix MAT2 aMat; @@ -2311,7 +2311,7 @@ sal_Bool WinSalGraphics::GetGlyphOutline( sal_GlyphId nIndex, { rB2DPolyPoly.clear(); - HDC hDC = mhDC; + HDC hDC = getHDC(); // use unity matrix MAT2 aMat; @@ -2515,7 +2515,7 @@ ScopedFont::~ScopedFont() // restore original font, destroy temporary font HFONT hTempFont = m_rData.mhFonts[0]; m_rData.mhFonts[0] = m_hOrigFont; - SelectObject( m_rData.mhDC, m_hOrigFont ); + SelectObject( m_rData.getHDC(), m_hOrigFont ); DeleteObject( hTempFont ); } } @@ -2570,7 +2570,7 @@ sal_Bool WinSalGraphics::CreateFontSubset( const OUString& rToFile, #if OSL_DEBUG_LEVEL > 1 // get font metrics TEXTMETRICA aWinMetric; - if( !::GetTextMetricsA( mhDC, &aWinMetric ) ) + if( !::GetTextMetricsA( getHDC(), &aWinMetric ) ) return FALSE; DBG_ASSERT( !(aWinMetric.tmPitchAndFamily & TMPF_DEVICE), "cannot subset device font" ); @@ -2585,10 +2585,10 @@ sal_Bool WinSalGraphics::CreateFontSubset( const OUString& rToFile, // check if the font has a CFF-table const DWORD nCffTag = CalcTag( "CFF " ); - const RawFontData aRawCffData( mhDC, nCffTag ); + const RawFontData aRawCffData( getHDC(), nCffTag ); if( aRawCffData.get() ) { - pWinFontData->UpdateFromHDC( mhDC ); + pWinFontData->UpdateFromHDC( getHDC() ); const ImplFontCharMap* pCharMap = pWinFontData->GetImplFontCharMap(); pCharMap->AddReference(); @@ -2618,7 +2618,7 @@ sal_Bool WinSalGraphics::CreateFontSubset( const OUString& rToFile, } // get raw font file data - const RawFontData xRawFontData( mhDC, 0 ); + const RawFontData xRawFontData( getHDC(), 0 ); if( !xRawFontData.get() ) return FALSE; @@ -2718,19 +2718,19 @@ const void* WinSalGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, SetFont( &aIFSD, 0 ); // get the raw font file data - RawFontData aRawFontData( mhDC ); + RawFontData aRawFontData( getHDC() ); *pDataLen = aRawFontData.size(); if( !aRawFontData.get() ) return NULL; // get important font properties TEXTMETRICA aTm; - if( !::GetTextMetricsA( mhDC, &aTm ) ) + if( !::GetTextMetricsA( getHDC(), &aTm ) ) *pDataLen = 0; const bool bPFA = (*aRawFontData.get() < 0x80); rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB; WCHAR aFaceName[64]; - sal_Int32 nFNLen = ::GetTextFaceW( mhDC, 64, aFaceName ); + sal_Int32 nFNLen = ::GetTextFaceW( getHDC(), 64, aFaceName ); // #i59854# strip eventual null byte while( nFNLen > 0 && aFaceName[nFNLen-1] == 0 ) nFNLen--; @@ -2748,7 +2748,7 @@ const void* WinSalGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, { int nCharWidth = 0; const sal_Unicode cChar = pUnicodes[i]; - if( !::GetCharWidth32W( mhDC, cChar, cChar, &nCharWidth ) ) + if( !::GetCharWidth32W( getHDC(), cChar, cChar, &nCharWidth ) ) *pDataLen = 0; pCharWidths[i] = nCharWidth; } @@ -2815,7 +2815,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, if( pFont->IsSubsettable() ) { // get raw font file data - const RawFontData xRawFontData( mhDC ); + const RawFontData xRawFontData( getHDC() ); if( !xRawFontData.get() ) return; @@ -2879,7 +2879,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, for( sal_Unicode i = 32; i < 256; ++i ) { int nCharWidth = 0; - if( ::GetCharWidth32W( mhDC, i, i, &nCharWidth ) ) + if( ::GetCharWidth32W( getHDC(), i, i, &nCharWidth ) ) { rUnicodeEnc[ i ] = rWidths.size(); rWidths.push_back( nCharWidth ); diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index 58659469deca..ba28f5743027 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -19,12 +19,11 @@ #include <stdio.h> #include <string.h> - #include <svsys.h> - #include <win/wincomp.hxx> #include <win/saldata.hxx> #include <win/salgdi.h> +#include <win/salbmp.h> #if defined _MSC_VER #ifndef min @@ -160,7 +159,7 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0)) { Gdiplus::GpGraphics *pGraphics = NULL; - Gdiplus::DllExports::GdipCreateFromHDC(mhDC, &pGraphics); + Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics); const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0)); Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor)); Gdiplus::GpSolidFill *pTestBrush; @@ -209,7 +208,7 @@ bool WinSalGraphics::drawPolyLine( if(mbPen && nCount) { Gdiplus::GpGraphics *pGraphics = NULL; - Gdiplus::DllExports::GdipCreateFromHDC(mhDC, &pGraphics); + Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics); const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) ); Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); Gdiplus::GpPen *pTestPen = NULL; @@ -305,4 +304,199 @@ bool WinSalGraphics::drawPolyLine( // ----------------------------------------------------------------------- +void paintToGdiPlus( + Gdiplus::Graphics& rGraphics, + const SalTwoRect& rTR, + Gdiplus::Bitmap& rBitmap) +{ + // only parts of source are used + Gdiplus::PointF aDestPoints[3]; + Gdiplus::ImageAttributes aAttributes; + + // define target region as paralellogram + aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX); + aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY); + aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth); + aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY); + aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX); + aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight); + + aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); + + rGraphics.DrawImage( + &rBitmap, + aDestPoints, + 3, + Gdiplus::REAL(rTR.mnSrcX), + Gdiplus::REAL(rTR.mnSrcY), + Gdiplus::REAL(rTR.mnSrcWidth), + Gdiplus::REAL(rTR.mnSrcHeight), + Gdiplus::UnitPixel, + &aAttributes, + 0, + 0); +} + +// ----------------------------------------------------------------------- + +void setInterpolationMode( + Gdiplus::Graphics& rGraphics, + const long& rSrcWidth, + const long& rDestWidth, + const long& rSrcHeight, + const long& rDestHeight) +{ + const bool bSameWidth(rSrcWidth == rDestWidth); + const bool bSameHeight(rSrcHeight == rDestHeight); + + if(bSameWidth && bSameHeight) + { + rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid); + } + else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight) + { + rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault); + } + else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight) + { + rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic); + } + else + { + rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault); + } +} + + +bool WinSalGraphics::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap) +{ + if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) + { + const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); + GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap()); + + if(aARGB.get()) + { + Gdiplus::Graphics aGraphics(getHDC()); + + setInterpolationMode( + aGraphics, + rTR.mnSrcWidth, + rTR.mnDestWidth, + rTR.mnSrcHeight, + rTR.mnDestHeight); + + paintToGdiPlus( + aGraphics, + rTR, + *aARGB.get()); + + return true; + } + } + + return false; +} + +bool WinSalGraphics::drawAlphaBitmap( + const SalTwoRect& rTR, + const SalBitmap& rSrcBitmap, + const SalBitmap& rAlphaBmp) +{ + if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) + { + const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); + const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp); + GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha)); + + if(aARGB.get()) + { + Gdiplus::Graphics aGraphics(getHDC()); + + setInterpolationMode( + aGraphics, + rTR.mnSrcWidth, + rTR.mnDestWidth, + rTR.mnSrcHeight, + rTR.mnDestHeight); + + paintToGdiPlus( + aGraphics, + rTR, + *aARGB.get()); + + return true; + } + } + + return false; +} + +// ----------------------------------------------------------------------- + +bool WinSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap); + const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap); + GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha)); + + if(aARGB.get()) + { + const long nSrcWidth(aARGB->GetWidth()); + const long nSrcHeight(aARGB->GetHeight()); + + if(nSrcWidth && nSrcHeight) + { + const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength())); + const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength())); + + if(nDestWidth && nDestHeight) + { + Gdiplus::Graphics aGraphics(getHDC()); + Gdiplus::PointF aDestPoints[3]; + Gdiplus::ImageAttributes aAttributes; + + setInterpolationMode( + aGraphics, + nSrcWidth, + nDestWidth, + nSrcHeight, + nDestHeight); + + // this mode is only capable of drawing the whole bitmap to a paralellogram + aDestPoints[0].X = Gdiplus::REAL(rNull.getX()); + aDestPoints[0].Y = Gdiplus::REAL(rNull.getY()); + aDestPoints[1].X = Gdiplus::REAL(rX.getX()); + aDestPoints[1].Y = Gdiplus::REAL(rX.getY()); + aDestPoints[2].X = Gdiplus::REAL(rY.getX()); + aDestPoints[2].Y = Gdiplus::REAL(rY.getY()); + + aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); + + aGraphics.DrawImage( + aARGB.get(), + aDestPoints, + 3, + Gdiplus::REAL(0.0), + Gdiplus::REAL(0.0), + Gdiplus::REAL(nSrcWidth), + Gdiplus::REAL(nSrcHeight), + Gdiplus::UnitPixel, + &aAttributes, + 0, + 0); + } + } + + return true; + } + + return false; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index 796cbb33bb57..674f03c60fbb 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -1268,15 +1268,15 @@ sal_Bool WinSalGraphics::drawNativeControl( ControlType nType, rc.bottom = buttonRect.Bottom()+1; // set default text alignment - int ta = SetTextAlign( mhDC, TA_LEFT|TA_TOP|TA_NOUPDATECP ); + int ta = SetTextAlign( getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP ); OUString aCaptionStr( aCaption.replace('~', '&') ); // translate mnemonics - bOk = ImplDrawNativeControl(mhDC, hTheme, rc, + bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr ); // restore alignment - SetTextAlign( mhDC, ta ); + SetTextAlign( getHDC(), ta ); //GdiFlush(); diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index d87b3a94892f..385a15ee59b9 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -1074,7 +1074,7 @@ static WinSalGraphics* ImplCreateSalPrnGraphics( HDC hDC ) { WinSalGraphics* pGraphics = new WinSalGraphics; pGraphics->SetLayout( 0 ); - pGraphics->mhDC = hDC; + pGraphics->setHDC(hDC); pGraphics->mhWnd = 0; pGraphics->mbPrinter = TRUE; pGraphics->mbVirDev = FALSE; @@ -1095,7 +1095,7 @@ static sal_Bool ImplUpdateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* p if ( pPrinter->mpGraphics ) { ImplSalDeInitGraphics( pPrinter->mpGraphics ); - DeleteDC( pPrinter->mpGraphics->mhDC ); + DeleteDC( pPrinter->mpGraphics->getHDC() ); delete pPrinter->mpGraphics; } @@ -1163,7 +1163,7 @@ WinSalInfoPrinter::~WinSalInfoPrinter() if ( mpGraphics ) { ImplSalDeInitGraphics( mpGraphics ); - DeleteDC( mpGraphics->mhDC ); + DeleteDC( mpGraphics->getHDC() ); delete mpGraphics; } } diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index 28d0f36f78bd..54ef0637dcef 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -88,11 +88,11 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } else { - hDC = CreateCompatibleDC( pGraphics->mhDC ); + hDC = CreateCompatibleDC( pGraphics->getHDC() ); if( !hDC ) ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" ); - hBmp = ImplCreateVirDevBitmap( pGraphics->mhDC, + hBmp = ImplCreateVirDevBitmap( pGraphics->getHDC(), nDX, nDY, nBitCount ); if( !hBmp ) ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" ); @@ -111,7 +111,7 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, SalData* pSalData = GetSalData(); WinSalGraphics* pVirGraphics = new WinSalGraphics; pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() - pVirGraphics->mhDC = hDC; + pVirGraphics->setHDC(hDC); pVirGraphics->mhWnd = 0; pVirGraphics->mbPrinter = FALSE; pVirGraphics->mbVirDev = TRUE; @@ -124,7 +124,7 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } ImplSalInitGraphics( pVirGraphics ); - pVDev->mhDC = hDC; + pVDev->setHDC(hDC); pVDev->mhBmp = hBmp; if( hBmp ) pVDev->mhDefBmp = SelectBitmap( hDC, hBmp ); @@ -162,7 +162,7 @@ void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice ) WinSalVirtualDevice::WinSalVirtualDevice() { - mhDC = (HDC) NULL; // HDC or 0 for Cache Device + setHDC((HDC)NULL); // HDC or 0 for Cache Device mhBmp = (HBITMAP) NULL; // Memory Bitmap mhDefBmp = (HBITMAP) NULL; // Default Bitmap mpGraphics = NULL; // current VirDev graphics @@ -185,12 +185,12 @@ WinSalVirtualDevice::~WinSalVirtualDevice() // destroy saved DC if( mpGraphics->mhDefPal ) - SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE ); + SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics ); if( mhDefBmp ) - SelectBitmap( mpGraphics->mhDC, mhDefBmp ); + SelectBitmap( mpGraphics->getHDC(), mhDefBmp ); if( !mbForeignDC ) - DeleteDC( mpGraphics->mhDC ); + DeleteDC( mpGraphics->getHDC() ); if( mhBmp ) DeleteBitmap( mhBmp ); delete mpGraphics; @@ -225,11 +225,11 @@ sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) return TRUE; // ??? else { - HBITMAP hNewBmp = ImplCreateVirDevBitmap( mhDC, nDX, nDY, + HBITMAP hNewBmp = ImplCreateVirDevBitmap( getHDC(), nDX, nDY, mnBitCount ); if ( hNewBmp ) { - SelectBitmap( mhDC, hNewBmp ); + SelectBitmap( getHDC(), hNewBmp ); DeleteBitmap( mhBmp ); mhBmp = hNewBmp; return TRUE; @@ -244,8 +244,8 @@ sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) { - rWidth = GetDeviceCaps( mhDC, HORZRES ); - rHeight= GetDeviceCaps( mhDC, VERTRES ); + rWidth = GetDeviceCaps( getHDC(), HORZRES ); + rHeight= GetDeviceCaps( getHDC(), VERTRES ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 41271b02c954..fac3d032bc85 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -605,7 +605,7 @@ void SimpleWinLayout::DrawText( SalGraphics& rGraphics ) const return; WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics); - HDC aHDC = rWinGraphics.mhDC; + HDC aHDC = rWinGraphics.getHDC(); HFONT hOrigFont = DisableFontScaling(); @@ -2819,7 +2819,7 @@ void GraphiteWinLayout::AdjustLayout(ImplLayoutArgs& rArgs) void GraphiteWinLayout::DrawText(SalGraphics &sal_graphics) const { HFONT hOrigFont = DisableFontScaling(); - HDC aHDC = static_cast<WinSalGraphics&>(sal_graphics).mhDC; + const HDC aHDC = static_cast<WinSalGraphics&>(sal_graphics).getHDC(); maImpl.DrawBase() = WinLayout::maDrawBase; maImpl.DrawOffset() = WinLayout::maDrawOffset; const int MAX_GLYPHS = 2; @@ -2838,7 +2838,7 @@ void GraphiteWinLayout::DrawText(SalGraphics &sal_graphics) const NULL, (LPCWSTR)&(glyphWStr), nGlyphs, NULL); } while (nGlyphs); if( hOrigFont ) - DeleteFont( SelectFont( mhDC, hOrigFont ) ); + DeleteFont( SelectFont( aHDC, hOrigFont ) ); } int GraphiteWinLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const @@ -2897,12 +2897,12 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe #if ENABLE_GRAPHITE if (rFontFace.SupportsGraphite()) { - pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); + pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance); } else #endif // ENABLE_GRAPHITE // script complexity is determined in upper layers - pWinLayout = new UniscribeLayout( mhDC, rFontFace, rFontInstance ); + pWinLayout = new UniscribeLayout( getHDC(), rFontFace, rFontInstance ); // NOTE: it must be guaranteed that the WinSalGraphics lives longer than // the created UniscribeLayout, otherwise the data passed into the // constructor might become invalid too early @@ -2922,10 +2922,10 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe eCharSet = mpLogFont->lfCharSet; #if ENABLE_GRAPHITE if (rFontFace.SupportsGraphite()) - pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); + pWinLayout = new GraphiteWinLayout( getHDC(), rFontFace, rFontInstance); else #endif // ENABLE_GRAPHITE - pWinLayout = new SimpleWinLayout( mhDC, eCharSet, rFontFace, rFontInstance ); + pWinLayout = new SimpleWinLayout( getHDC(), eCharSet, rFontFace, rFontInstance ); } if( mfFontScale[nFallbackLevel] != 1.0 ) @@ -2940,7 +2940,7 @@ int WinSalGraphics::GetMinKashidaWidth() { if( !mpWinFontEntry[0] ) return 0; - mpWinFontEntry[0]->InitKashidaHandling( mhDC ); + mpWinFontEntry[0]->InitKashidaHandling( getHDC() ); int nMinKashida = static_cast<int>(mfFontScale[0] * mpWinFontEntry[0]->GetMinKashidaWidth()); return nMinKashida; } diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index 072dd3ca33a0..05f1f35415fb 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -948,16 +948,16 @@ WinSalFrame::~WinSalFrame() // Release Cache DC if ( mpGraphics2 && - mpGraphics2->mhDC ) + mpGraphics2->getHDC() ) ReleaseGraphics( mpGraphics2 ); // destroy saved DC if ( mpGraphics ) { if ( mpGraphics->mhDefPal ) - SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE ); + SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics ); - ReleaseDC( mhWnd, mpGraphics->mhDC ); + ReleaseDC( mhWnd, mpGraphics->getHDC() ); delete mpGraphics; mpGraphics = NULL; } @@ -1004,7 +1004,7 @@ SalGraphics* WinSalFrame::GetGraphics() if ( !mpGraphics2 ) { mpGraphics2 = new WinSalGraphics; - mpGraphics2->mhDC = 0; + mpGraphics2->setHDC(0); mpGraphics2->mhWnd = mhWnd; mpGraphics2->mbPrinter = FALSE; mpGraphics2->mbVirDev = FALSE; @@ -1017,7 +1017,7 @@ SalGraphics* WinSalFrame::GetGraphics() (WPARAM)mhWnd, 0 ); if ( hDC ) { - mpGraphics2->mhDC = hDC; + mpGraphics2->setHDC(hDC); if ( pSalData->mhDitherPal ) { mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); @@ -1040,7 +1040,7 @@ SalGraphics* WinSalFrame::GetGraphics() if ( hDC ) { mpGraphics = new WinSalGraphics; - mpGraphics->mhDC = hDC; + mpGraphics->setHDC(hDC); mpGraphics->mhWnd = mhWnd; mpGraphics->mbPrinter = FALSE; mpGraphics->mbVirDev = FALSE; @@ -1068,17 +1068,17 @@ void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) { if ( mpGraphics2 == pGraphics ) { - if ( mpGraphics2->mhDC ) + if ( mpGraphics2->getHDC() ) { SalData* pSalData = GetSalData(); if ( mpGraphics2->mhDefPal ) - SelectPalette( mpGraphics2->mhDC, mpGraphics2->mhDefPal, TRUE ); + SelectPalette( mpGraphics2->getHDC(), mpGraphics2->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics2 ); ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_RELEASEDC, (WPARAM)mhWnd, - (LPARAM)mpGraphics2->mhDC ); - mpGraphics2->mhDC = 0; + (LPARAM)mpGraphics2->getHDC() ); + mpGraphics2->setHDC(0); pSalData->mnCacheDCInUse--; } } @@ -1540,12 +1540,12 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool // Release Cache DC if ( pThis->mpGraphics2 && - pThis->mpGraphics2->mhDC ) + pThis->mpGraphics2->getHDC() ) { // save current gdi objects before hdc is gone - hFont = (HFONT) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_FONT); - hPen = (HPEN) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_PEN); - hBrush = (HBRUSH) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_BRUSH); + hFont = (HFONT) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_FONT); + hPen = (HPEN) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_PEN); + hBrush = (HBRUSH) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_BRUSH); pThis->ReleaseGraphics( pThis->mpGraphics2 ); // recreate cache dc only if it was destroyed @@ -1556,9 +1556,9 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool if ( pThis->mpGraphics ) { if ( pThis->mpGraphics->mhDefPal ) - SelectPalette( pThis->mpGraphics->mhDC, pThis->mpGraphics->mhDefPal, TRUE ); + SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( pThis->mpGraphics ); - ReleaseDC( pThis->mhWnd, pThis->mpGraphics->mhDC ); + ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() ); } // create a new hwnd with the same styles @@ -1586,7 +1586,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool (WPARAM) hWnd, 0 ); if ( hDC ) { - pThis->mpGraphics2->mhDC = hDC; + pThis->mpGraphics2->setHDC(hDC); if ( pSalData->mhDitherPal ) { pThis->mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); @@ -1615,11 +1615,11 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool { // re-create DC pThis->mpGraphics->mhWnd = hWnd; - pThis->mpGraphics->mhDC = GetDC( hWnd ); + pThis->mpGraphics->setHDC( GetDC( hWnd ) ); if ( GetSalData()->mhDitherPal ) { - pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->mhDC, GetSalData()->mhDitherPal, TRUE ); - RealizePalette( pThis->mpGraphics->mhDC ); + pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE ); + RealizePalette( pThis->mpGraphics->getHDC() ); } ImplSalInitGraphics( pThis->mpGraphics ); pThis->mbGraphics = TRUE; @@ -3501,8 +3501,8 @@ static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg, // reset the background mode for each text input, // as some tools such as RichWin may have changed it if ( pFrame->mpGraphics && - pFrame->mpGraphics->mhDC ) - SetBkMode( pFrame->mpGraphics->mhDC, TRANSPARENT ); + pFrame->mpGraphics->getHDC() ) + SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); // determine modifiers if ( GetKeyState( VK_SHIFT ) & 0x8000 ) @@ -3863,7 +3863,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // clip-region must be reset, as we do not get a proper // bounding-rectangle otherwise if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) - SelectClipRgn( pFrame->mpGraphics->mhDC, 0 ); + SelectClipRgn( pFrame->mpGraphics->getHDC(), 0 ); // according to Window-Documentation one shall check first if // there really is a paint-region @@ -3880,7 +3880,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // reset ClipRegion if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) { - SelectClipRgn( pFrame->mpGraphics->mhDC, + SelectClipRgn( pFrame->mpGraphics->getHDC(), pFrame->mpGraphics->mhRegion ); } @@ -3902,7 +3902,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // reset ClipRegion if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) { - SelectClipRgn( pFrame->mpGraphics->mhDC, + SelectClipRgn( pFrame->mpGraphics->getHDC(), pFrame->mpGraphics->mhRegion ); } } @@ -4284,8 +4284,8 @@ static void ImplHandleForcePalette( HWND hWnd ) WinSalGraphics* pGraphics = pFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, FALSE ); - if ( RealizePalette( pGraphics->mhDC ) ) + SelectPalette( pGraphics->getHDC(), hPal, FALSE ); + if ( RealizePalette( pGraphics->getHDC() ) ) { InvalidateRect( hWnd, NULL, FALSE ); UpdateWindow( hWnd ); @@ -4349,7 +4349,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempVD->mpGraphics; if ( pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, + SelectPalette( pGraphics->getHDC(), pGraphics->mhDefPal, TRUE ); } @@ -4361,7 +4361,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, + SelectPalette( pGraphics->getHDC(), pGraphics->mhDefPal, TRUE ); } @@ -4374,7 +4374,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pFrame = GetWindowPtr( hWnd ); if ( pFrame && pFrame->mpGraphics ) { - hDC = pFrame->mpGraphics->mhDC; + hDC = pFrame->mpGraphics->getHDC(); bStdDC = TRUE; } else @@ -4399,8 +4399,8 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempVD->mpGraphics; if ( pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, TRUE ); - RealizePalette( pGraphics->mhDC ); + SelectPalette( pGraphics->getHDC(), hPal, TRUE ); + RealizePalette( pGraphics->getHDC() ); } pTempVD = pTempVD->mpNext; } @@ -4412,8 +4412,8 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, TRUE ); - if ( RealizePalette( pGraphics->mhDC ) ) + SelectPalette( pGraphics->getHDC(), hPal, TRUE ); + if ( RealizePalette( pGraphics->getHDC() ) ) bUpdate = TRUE; } } @@ -5287,8 +5287,8 @@ static sal_Bool ImplHandleIMEComposition( HWND hWnd, LPARAM lParam ) // reset the background mode for each text input, // as some tools such as RichWin may have changed it if ( pFrame->mpGraphics && - pFrame->mpGraphics->mhDC ) - SetBkMode( pFrame->mpGraphics->mhDC, TRANSPARENT ); + pFrame->mpGraphics->getHDC() ) + SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); } if ( pFrame && pFrame->mbHandleIME ) |