diff options
-rw-r--r-- | include/vcl/outdev.hxx | 189 | ||||
-rw-r--r-- | include/vcl/print.hxx | 2 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/gdi/print.cxx | 2 | ||||
-rw-r--r-- | vcl/source/outdev/bitmap.cxx | 358 | ||||
-rw-r--r-- | vcl/source/outdev/blend.cxx | 350 |
6 files changed, 451 insertions, 451 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index cd7e5a553f11..e8d03da789cd 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -785,29 +785,6 @@ public: const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, const Size& rSrcSizePixel ); virtual void ClipToPaintRegion ( Rectangle& rDstRect ); - SAL_DLLPRIVATE Bitmap ImplBlend ( Bitmap aBmp, - BitmapReadAccess* pP, - BitmapReadAccess* pA, - const sal_Int32 nOffY, - const sal_Int32 nDstHeight, - const sal_Int32 nOffX, - const sal_Int32 nDstWidth, - const Rectangle& aBmpRect, - const Size& aOutSz, - const bool bHMirr, - const bool bVMirr, - const long* pMapX, - const long* pMapY ); - SAL_DLLPRIVATE Bitmap ImplBlendWithAlpha ( Bitmap aBmp, - BitmapReadAccess* pP, - BitmapReadAccess* pA, - const Rectangle& aDstRect, - const sal_Int32 nOffY, - const sal_Int32 nDstHeight, - const sal_Int32 nOffX, - const sal_Int32 nDstWidth, - const long* pMapX, - const long* pMapY ); SAL_DLLPRIVATE void ImplPrintTransparent ( const Bitmap& rBmp, const Bitmap& rMask, const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, const Size& rSrcSizePixel ); @@ -854,40 +831,6 @@ protected: virtual bool UsePolyPolygonForComplexGradient() = 0; - /** Transform and draw a bitmap directly - - @param aFullTransform The B2DHomMatrix used for the transformation - @param rBitmapEx Reference to the bitmap to be transformed and drawn - - @return true if it was able to draw the bitmap, false if not - */ - virtual bool DrawTransformBitmapExDirect( - const basegfx::B2DHomMatrix& aFullTransform, - const BitmapEx& rBitmapEx); - - /** Reduce the area that needs to be drawn of the bitmap and return the new - visible range and the maximum area. - - - @param aFullTransform B2DHomMatrix used for transformation - @param aVisibleRange The new visible area of the bitmap - @param fMaximumArea The maximum area of the bitmap - - @returns true if there is an area to be drawn, otherwise nothing is left to be drawn - so return false - */ - virtual bool TransformReduceBitmapExTargetRange( - const basegfx::B2DHomMatrix& aFullTransform, - basegfx::B2DRange &aVisibleRange, - double &fMaximumArea); - - virtual void ScaleBitmap ( Bitmap &rBmp, SalTwoRect &rPosAry ); - - virtual void DrawDeviceBitmap( - const Point& rDestPt, const Size& rDestSize, - const Point& rSrcPtPixel, const Size& rSrcSizePixel, - BitmapEx& rBitmapEx ); - virtual void EmulateDrawTransparent( const PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent ); void DrawInvisiblePolygon( const PolyPolygon& rPolyPoly ); @@ -1105,25 +1048,60 @@ public: protected: virtual void CopyAreaFinal( SalTwoRect& aPosAry, sal_uInt32 nFlags); -public: - void DrawBitmap( const Point& rDestPt, - const Bitmap& rBitmap ); - void DrawBitmap( const Point& rDestPt, const Size& rDestSize, - const Bitmap& rBitmap ); - void DrawBitmap( const Point& rDestPt, const Size& rDestSize, - const Point& rSrcPtPixel, const Size& rSrcSizePixel, - const Bitmap& rBitmap, sal_uLong nAction = META_BMPSCALEPART_ACTION ); +public: + /** @name Bitmap functions + */ + ///@{ - void DrawBitmapEx( const Point& rDestPt, - const BitmapEx& rBitmapEx ); - void DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, - const BitmapEx& rBitmapEx ); - void DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, - const Point& rSrcPtPixel, const Size& rSrcSizePixel, - const BitmapEx& rBitmapExi, sal_uLong nAction = META_BMPEXSCALEPART_ACTION ); + /** @overload void DrawBitmap(const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, + const Size& rSecSizePixel, const Bitmap& rBitmap, + sal_uLong nAction = META_BMPSCALEPART_ACTION) */ + void DrawBitmap( + const Point& rDestPt, + const Bitmap& rBitmap ); + + /** @overload void DrawBitmap(const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, + const Size& rSecSizePixel, const Bitmap& rBitmap, + sal_uLong nAction = META_BMPSCALEPART_ACTION) */ + void DrawBitmap( + const Point& rDestPt, + const Size& rDestSize, + const Bitmap& rBitmap ); + + void DrawBitmap( + const Point& rDestPt, + const Size& rDestSize, + const Point& rSrcPtPixel, + const Size& rSrcSizePixel, + const Bitmap& rBitmap, + sal_uLong nAction = META_BMPSCALEPART_ACTION ); + + /** @overload void DrawBitmapEx(const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, + const Size& rSecSizePixel, const BitmapEx& rBitmapEx, + sal_uLong nAction = META_BMPEXSCALEPART_ACTION) */ + void DrawBitmapEx( + const Point& rDestPt, + const BitmapEx& rBitmapEx ); + + /** @overload void DrawBitmapEx(const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, + const Size& rSecSizePixel, const BitmapEx& rBitmapEx, + sal_uLong nAction = META_BMPEXSCALEPART_ACTION) */ + void DrawBitmapEx( + const Point& rDestPt, + const Size& rDestSize, + const BitmapEx& rBitmapEx ); + + void DrawBitmapEx( + const Point& rDestPt, + const Size& rDestSize, + const Point& rSrcPtPixel, + const Size& rSrcSizePixel, + const BitmapEx& rBitmapEx, + sal_uLong nAction = META_BMPEXSCALEPART_ACTION ); - /** Draw BitampEx transformed +protected: + /** Draw BitmapEx transformed @param rTransformation The transformation describing the target positioning of the given bitmap. Transforming @@ -1133,10 +1111,73 @@ public: @param rBitmapEx The BitmapEx to be painted */ - void DrawTransformedBitmapEx( + void DrawTransformBitmapEx( const basegfx::B2DHomMatrix& rTransformation, const BitmapEx& rBitmapEx); + /** Transform and draw a bitmap directly + + @param aFullTransform The B2DHomMatrix used for the transformation + @param rBitmapEx Reference to the bitmap to be transformed and drawn + + @return true if it was able to draw the bitmap, false if not + */ + virtual bool DrawTransformBitmapExDirect( + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx); + + /** Transform and reduce the area that needs to be drawn of the bitmap and return the new + visible range and the maximum area. + + + @param aFullTransform B2DHomMatrix used for transformation + @param aVisibleRange The new visible area of the bitmap + @param fMaximumArea The maximum area of the bitmap + + @returns true if there is an area to be drawn, otherwise nothing is left to be drawn + so return false + */ + virtual bool TransformAndReduceBitmapExToTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea); + + virtual void ScaleBitmap ( Bitmap &rBmp, SalTwoRect &rPosAry ); + + virtual void DrawDeviceBitmap( + const Point& rDestPt, const Size& rDestSize, + const Point& rSrcPtPixel, const Size& rSrcSizePixel, + BitmapEx& rBitmapEx ); +private: + SAL_DLLPRIVATE Bitmap BlendBitmap( + Bitmap aBmp, + BitmapReadAccess* pP, + BitmapReadAccess* pA, + const sal_Int32 nOffY, + const sal_Int32 nDstHeight, + const sal_Int32 nOffX, + const sal_Int32 nDstWidth, + const Rectangle& aBmpRect, + const Size& aOutSz, + const bool bHMirr, + const bool bVMirr, + const long* pMapX, + const long* pMapY ); + + SAL_DLLPRIVATE Bitmap BlendBitmapWithAlpha( + Bitmap aBmp, + BitmapReadAccess* pP, + BitmapReadAccess* pA, + const Rectangle& aDstRect, + const sal_Int32 nOffY, + const sal_Int32 nDstHeight, + const sal_Int32 nOffX, + const sal_Int32 nDstWidth, + const long* pMapX, + const long* pMapY ); + ///@} + +public: void DrawMask( const Point& rDestPt, const Bitmap& rBitmap, const Color& rMaskColor ); void DrawMask( const Point& rDestPt, const Size& rDestSize, diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx index 40659356d490..9780c0d9abdb 100644 --- a/include/vcl/print.hxx +++ b/include/vcl/print.hxx @@ -291,7 +291,7 @@ protected: const basegfx::B2DHomMatrix& aFullTransform, const BitmapEx& rBitmapEx) SAL_OVERRIDE; - bool TransformReduceBitmapExTargetRange( + bool TransformAndReduceBitmapExToTargetRange( const basegfx::B2DHomMatrix& aFullTransform, basegfx::B2DRange &aVisibleRange, double &fMaximumArea) SAL_OVERRIDE; diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 989bf8e1069e..4cfa61af0a9c 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -238,7 +238,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/outdev/tworect \ vcl/source/outdev/polygon \ vcl/source/outdev/transparent \ - vcl/source/outdev/blend \ vcl/source/outdev/mask \ vcl/source/outdev/bitmap \ vcl/source/outdev/font \ diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 12a0638ffb2c..249fe2564fec 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -217,7 +217,7 @@ bool Printer::DrawTransformBitmapExDirect( return false; } -bool Printer::TransformReduceBitmapExTargetRange( +bool Printer::TransformAndReduceBitmapExToTargetRange( const basegfx::B2DHomMatrix& /*aFullTransform*/, basegfx::B2DRange& /*aVisibleRange*/, double& /*fMaximumArea*/) diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 5f88ab725d5c..ce88a2d5e042 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -160,20 +160,6 @@ void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize, } } -void OutputDevice::ScaleBitmap (Bitmap &rBmp, SalTwoRect &rPosAry) -{ - const double nScaleX = rPosAry.mnDestWidth / static_cast<double>( rPosAry.mnSrcWidth ); - const double nScaleY = rPosAry.mnDestHeight / static_cast<double>( rPosAry.mnSrcHeight ); - - // If subsampling, use Bitmap::Scale for subsampling for better quality. - if ( nScaleX < 1.0 || nScaleY < 1.0 ) - { - rBmp.Scale ( nScaleX, nScaleY ); - rPosAry.mnSrcWidth = rPosAry.mnDestWidth; - rPosAry.mnSrcHeight = rPosAry.mnDestHeight; - } -} - void OutputDevice::DrawBitmapEx( const Point& rDestPt, const BitmapEx& rBitmapEx ) { @@ -299,10 +285,23 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, } } +void OutputDevice::ScaleBitmap (Bitmap &rBmp, SalTwoRect &rPosAry) +{ + const double nScaleX = rPosAry.mnDestWidth / static_cast<double>( rPosAry.mnSrcWidth ); + const double nScaleY = rPosAry.mnDestHeight / static_cast<double>( rPosAry.mnSrcHeight ); + + // If subsampling, use Bitmap::Scale for subsampling for better quality. + if ( nScaleX < 1.0 || nScaleY < 1.0 ) + { + rBmp.Scale ( nScaleX, nScaleY ); + rPosAry.mnSrcWidth = rPosAry.mnDestWidth; + rPosAry.mnSrcHeight = rPosAry.mnDestHeight; + } +} bool OutputDevice::DrawTransformBitmapExDirect( - const basegfx::B2DHomMatrix& aFullTransform, - const BitmapEx& rBitmapEx) + const basegfx::B2DHomMatrix& aFullTransform, + const BitmapEx& rBitmapEx) { bool bDone = false; @@ -336,10 +335,10 @@ bool OutputDevice::DrawTransformBitmapExDirect( return bDone; }; -bool OutputDevice::TransformReduceBitmapExTargetRange( - const basegfx::B2DHomMatrix& aFullTransform, - basegfx::B2DRange &aVisibleRange, - double &fMaximumArea) +bool OutputDevice::TransformAndReduceBitmapExToTargetRange( + const basegfx::B2DHomMatrix& aFullTransform, + basegfx::B2DRange &aVisibleRange, + double &fMaximumArea) { // limit TargetRange to existing pixels (if pixel device) // first get discrete range of object @@ -419,7 +418,7 @@ bool OutputDevice::TransformReduceBitmapExTargetRange( return true; } -void OutputDevice::DrawTransformedBitmapEx( +void OutputDevice::DrawTransformBitmapEx( const basegfx::B2DHomMatrix& rTransformation, const BitmapEx& rBitmapEx) { @@ -502,7 +501,7 @@ void OutputDevice::DrawTransformedBitmapEx( if(!bMetafile) { - if ( !TransformReduceBitmapExTargetRange( aFullTransform, aVisibleRange, fMaximumArea ) ) + if ( !TransformAndReduceBitmapExToTargetRange( aFullTransform, aVisibleRange, fMaximumArea ) ) return; } @@ -1075,7 +1074,7 @@ void OutputDevice::DrawAlphaBitmap( const Bitmap& rBmp, const AlphaMask& rAlpha, if( mpAlphaVDev ) { - aTmp = ImplBlendWithAlpha( + aTmp = BlendBitmapWithAlpha( aBmp,pP,pA, aDstRect, nOffY,nDstHeight, @@ -1084,7 +1083,7 @@ void OutputDevice::DrawAlphaBitmap( const Bitmap& rBmp, const AlphaMask& rAlpha, } else { - aTmp = ImplBlend( + aTmp = BlendBitmap( aBmp,pP,pA, nOffY,nDstHeight, nOffX,nDstWidth, @@ -1114,4 +1113,315 @@ void OutputDevice::DrawAlphaBitmap( const Bitmap& rBmp, const AlphaMask& rAlpha, } } + +namespace +{ + // Co = Cs + Cd*(1-As) premultiplied alpha -or- + // Co = (AsCs + AdCd*(1-As)) / Ao + inline sal_uInt8 CalcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha, + const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor ) + { + int c = nResAlpha ? ( (int)nSourceAlpha*nSourceColor + (int)nDstAlpha*nDestColor - + (int)nDstAlpha*nDestColor*nSourceAlpha/255 ) / (int)nResAlpha : 0; + return sal_uInt8( c ); + } + + inline BitmapColor AlphaBlend( int nX, int nY, + const long nMapX, + const long nMapY, + BitmapReadAccess* pP, + BitmapReadAccess* pA, + BitmapReadAccess* pB, + BitmapWriteAccess* pAlphaW, + sal_uInt8& nResAlpha ) + { + BitmapColor aDstCol,aSrcCol; + aSrcCol = pP->GetColor( nMapY, nMapX ); + aDstCol = pB->GetColor( nY, nX ); + + // vcl stores transparency, not alpha - invert it + const sal_uInt8 nSrcAlpha = 255 - pA->GetPixelIndex( nMapY, nMapX ); + const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixelIndex( nY, nX ); + + // Perform porter-duff compositing 'over' operation + + // Co = Cs + Cd*(1-As) + // Ad = As + Ad*(1-As) + nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255; + + aDstCol.SetRed( CalcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) ); + aDstCol.SetBlue( CalcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( CalcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) ); + + return aDstCol; + } +} + +Bitmap OutputDevice::BlendBitmapWithAlpha( + Bitmap aBmp, + BitmapReadAccess* pP, + BitmapReadAccess* pA, + const Rectangle& aDstRect, + const sal_Int32 nOffY, + const sal_Int32 nDstHeight, + const sal_Int32 nOffX, + const sal_Int32 nDstWidth, + const long* pMapX, + const long* pMapY ) + +{ + BitmapColor aDstCol; + Bitmap res; + int nX, nY; + sal_uInt8 nResAlpha; + + OSL_ENSURE(mpAlphaVDev, + "BlendBitmapWithAlpha(): call me only with valid alpha VDev!" ); + + bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() ); + mpAlphaVDev->EnableMapMode(false); + + Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) ); + BitmapWriteAccess* pAlphaW = aAlphaBitmap.AcquireWriteAccess(); + + if( GetBitCount() <= 8 ) + { + Bitmap aDither( aBmp.GetSizePixel(), 8 ); + BitmapColor aIndex( 0 ); + BitmapReadAccess* pB = aBmp.AcquireReadAccess(); + BitmapWriteAccess* pW = aDither.AcquireWriteAccess(); + + if( pB && pP && pA && pW && pAlphaW ) + { + int nOutY; + + for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ ) + { + const long nMapY = pMapY[ nY ]; + const long nModY = ( nOutY & 0x0FL ) << 4L; + int nOutX; + + for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) + { + const long nMapX = pMapX[ nX ]; + const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ]; + + aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha ); + + aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + + nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + + nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); + pW->SetPixel( nY, nX, aIndex ); + + aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] + + nVCLGLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] + + nVCLBLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] ) ); + pAlphaW->SetPixel( nY, nX, aIndex ); + } + } + } + + aBmp.ReleaseAccess( pB ); + aDither.ReleaseAccess( pW ); + res = aDither; + } + else + { + BitmapWriteAccess* pB = aBmp.AcquireWriteAccess(); + if( pP && pA && pB ) + { + for( nY = 0; nY < nDstHeight; nY++ ) + { + const long nMapY = pMapY[ nY ]; + + for( nX = 0; nX < nDstWidth; nX++ ) + { + const long nMapX = pMapX[ nX ]; + aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha ); + + pB->SetPixel( nY, nX, aDstCol ); + pAlphaW->SetPixel( nY, nX, Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha) ); + } + } + } + + aBmp.ReleaseAccess( pB ); + res = aBmp; + } + + aAlphaBitmap.ReleaseAccess( pAlphaW ); + mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap ); + mpAlphaVDev->EnableMapMode( bOldMapMode ); + + return res; +} + +Bitmap OutputDevice::BlendBitmap( + Bitmap aBmp, + BitmapReadAccess* pP, + BitmapReadAccess* pA, + const sal_Int32 nOffY, + const sal_Int32 nDstHeight, + const sal_Int32 nOffX, + const sal_Int32 nDstWidth, + const Rectangle& aBmpRect, + const Size& aOutSz, + const bool bHMirr, + const bool bVMirr, + const long* pMapX, + const long* pMapY ) +{ + BitmapColor aDstCol; + Bitmap res; + int nX, nY; + + if( GetBitCount() <= 8 ) + { + Bitmap aDither( aBmp.GetSizePixel(), 8 ); + BitmapColor aIndex( 0 ); + BitmapReadAccess* pB = aBmp.AcquireReadAccess(); + BitmapWriteAccess* pW = aDither.AcquireWriteAccess(); + + if( pB && pP && pA && pW ) + { + int nOutY; + + for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ ) + { + const long nMapY = pMapY[ nY ]; + const long nModY = ( nOutY & 0x0FL ) << 4L; + int nOutX; + + for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) + { + const long nMapX = pMapX[ nX ]; + const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ]; + + aDstCol = pB->GetColor( nY, nX ); + aDstCol.Merge( pP->GetColor( nMapY, nMapX ), pA->GetPixelIndex( nMapY, nMapX ) ); + aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + + nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + + nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); + pW->SetPixel( nY, nX, aIndex ); + } + } + } + + aBmp.ReleaseAccess( pB ); + aDither.ReleaseAccess( pW ); + res = aDither; + } + else + { + BitmapWriteAccess* pB = aBmp.AcquireWriteAccess(); + + bool bFastBlend = false; + if( pP && pA && pB ) + { + SalTwoRect aTR; + aTR.mnSrcX = aBmpRect.Left(); + aTR.mnSrcY = aBmpRect.Top(); + aTR.mnSrcWidth = aBmpRect.GetWidth(); + aTR.mnSrcHeight = aBmpRect.GetHeight(); + aTR.mnDestX = nOffX; + aTR.mnDestY = nOffY; + aTR.mnDestWidth = aOutSz.Width(); + aTR.mnDestHeight= aOutSz.Height(); + + if( !bHMirr && !bVMirr ) + bFastBlend = ImplFastBitmapBlending( *pB,*pP,*pA, aTR ); + } + + if( pP && pA && pB && !bFastBlend ) + { + switch( pP->GetScanlineFormat() ) + { + case( BMP_FORMAT_8BIT_PAL ): + { + for( nY = 0; nY < nDstHeight; nY++ ) + { + const long nMapY = pMapY[ nY ]; + Scanline pPScan = pP->GetScanline( nMapY ); + Scanline pAScan = pA->GetScanline( nMapY ); + + for( nX = 0; nX < nDstWidth; nX++ ) + { + const long nMapX = pMapX[ nX ]; + aDstCol = pB->GetPixel( nY, nX ); + pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ), + pAScan[ nMapX ] ) ); + } + } + } + break; + + case( BMP_FORMAT_24BIT_TC_BGR ): + { + for( nY = 0; nY < nDstHeight; nY++ ) + { + const long nMapY = pMapY[ nY ]; + Scanline pPScan = pP->GetScanline( nMapY ); + Scanline pAScan = pA->GetScanline( nMapY ); + + for( nX = 0; nX < nDstWidth; nX++ ) + { + const long nMapX = pMapX[ nX ]; + Scanline pTmp = pPScan + nMapX * 3; + + aDstCol = pB->GetPixel( nY, nX ); + pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 2 ], pTmp[ 1 ], pTmp[ 0 ], + pAScan[ nMapX ] ) ); + } + } + } + break; + + case( BMP_FORMAT_24BIT_TC_RGB ): + { + for( nY = 0; nY < nDstHeight; nY++ ) + { + const long nMapY = pMapY[ nY ]; + Scanline pPScan = pP->GetScanline( nMapY ); + Scanline pAScan = pA->GetScanline( nMapY ); + + for( nX = 0; nX < nDstWidth; nX++ ) + { + const long nMapX = pMapX[ nX ]; + Scanline pTmp = pPScan + nMapX * 3; + + aDstCol = pB->GetPixel( nY, nX ); + pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 0 ], pTmp[ 1 ], pTmp[ 2 ], + pAScan[ nMapX ] ) ); + } + } + } + break; + + default: + { + for( nY = 0; nY < nDstHeight; nY++ ) + { + const long nMapY = pMapY[ nY ]; + Scanline pAScan = pA->GetScanline( nMapY ); + + for( nX = 0; nX < nDstWidth; nX++ ) + { + const long nMapX = pMapX[ nX ]; + aDstCol = pB->GetPixel( nY, nX ); + pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ), + pAScan[ nMapX ] ) ); + } + } + } + break; + } + } + + aBmp.ReleaseAccess( pB ); + res = aBmp; + } + + return res; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/blend.cxx b/vcl/source/outdev/blend.cxx deleted file mode 100644 index 0b516790df20..000000000000 --- a/vcl/source/outdev/blend.cxx +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <tools/debug.hxx> -#include <vcl/bitmap.hxx> -#include <vcl/bitmapex.hxx> -#include <vcl/window.hxx> -#include <vcl/metaact.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/virdev.hxx> -#include <vcl/bmpacc.hxx> -#include <vcl/outdev.hxx> -#include <vcl/image.hxx> -#include <bmpfast.hxx> -#include <salbmp.hxx> -#include <salgdi.hxx> -#include <impbmp.hxx> -#include <sallayout.hxx> -#include <image.h> -#include <outdev.h> -#include <window.h> -#include <outdata.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <basegfx/matrix/b2dhommatrixtools.hxx> -#include <boost/scoped_array.hpp> - -namespace -{ - // Co = Cs + Cd*(1-As) premultiplied alpha -or- - // Co = (AsCs + AdCd*(1-As)) / Ao - inline sal_uInt8 lcl_calcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha, - const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor ) - { - int c = nResAlpha ? ( (int)nSourceAlpha*nSourceColor + (int)nDstAlpha*nDestColor - - (int)nDstAlpha*nDestColor*nSourceAlpha/255 ) / (int)nResAlpha : 0; - return sal_uInt8( c ); - } - - inline BitmapColor lcl_AlphaBlend( int nX, int nY, - const long nMapX, - const long nMapY, - BitmapReadAccess* pP, - BitmapReadAccess* pA, - BitmapReadAccess* pB, - BitmapWriteAccess* pAlphaW, - sal_uInt8& nResAlpha ) - { - BitmapColor aDstCol,aSrcCol; - aSrcCol = pP->GetColor( nMapY, nMapX ); - aDstCol = pB->GetColor( nY, nX ); - - // vcl stores transparency, not alpha - invert it - const sal_uInt8 nSrcAlpha = 255 - pA->GetPixelIndex( nMapY, nMapX ); - const sal_uInt8 nDstAlpha = 255 - pAlphaW->GetPixelIndex( nY, nX ); - - // Perform porter-duff compositing 'over' operation - - // Co = Cs + Cd*(1-As) - // Ad = As + Ad*(1-As) - nResAlpha = (int)nSrcAlpha + (int)nDstAlpha - (int)nDstAlpha*nSrcAlpha/255; - - aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) ); - aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) ); - aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) ); - - return aDstCol; - } -} - -Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, - BitmapReadAccess* pP, - BitmapReadAccess* pA, - const Rectangle& aDstRect, - const sal_Int32 nOffY, - const sal_Int32 nDstHeight, - const sal_Int32 nOffX, - const sal_Int32 nDstWidth, - const long* pMapX, - const long* pMapY ) -{ - BitmapColor aDstCol; - Bitmap res; - int nX, nY; - sal_uInt8 nResAlpha; - - OSL_ENSURE(mpAlphaVDev, - "ImplBlendWithAlpha(): call me only with valid alpha VDev!" ); - - bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() ); - mpAlphaVDev->EnableMapMode(false); - - Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) ); - BitmapWriteAccess* pAlphaW = aAlphaBitmap.AcquireWriteAccess(); - - if( GetBitCount() <= 8 ) - { - Bitmap aDither( aBmp.GetSizePixel(), 8 ); - BitmapColor aIndex( 0 ); - BitmapReadAccess* pB = aBmp.AcquireReadAccess(); - BitmapWriteAccess* pW = aDither.AcquireWriteAccess(); - - if( pB && pP && pA && pW && pAlphaW ) - { - int nOutY; - - for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ ) - { - const long nMapY = pMapY[ nY ]; - const long nModY = ( nOutY & 0x0FL ) << 4L; - int nOutX; - - for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) - { - const long nMapX = pMapX[ nX ]; - const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ]; - - aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha ); - - aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); - pW->SetPixel( nY, nX, aIndex ); - - aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ 255-nResAlpha ] + nD ) >> 16UL ] ) ); - pAlphaW->SetPixel( nY, nX, aIndex ); - } - } - } - - aBmp.ReleaseAccess( pB ); - aDither.ReleaseAccess( pW ); - res = aDither; - } - else - { - BitmapWriteAccess* pB = aBmp.AcquireWriteAccess(); - if( pP && pA && pB ) - { - for( nY = 0; nY < nDstHeight; nY++ ) - { - const long nMapY = pMapY[ nY ]; - - for( nX = 0; nX < nDstWidth; nX++ ) - { - const long nMapX = pMapX[ nX ]; - aDstCol = lcl_AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB, pAlphaW, nResAlpha ); - - pB->SetPixel( nY, nX, aDstCol ); - pAlphaW->SetPixel( nY, nX, Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha) ); - } - } - } - - aBmp.ReleaseAccess( pB ); - res = aBmp; - } - - aAlphaBitmap.ReleaseAccess( pAlphaW ); - mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap ); - mpAlphaVDev->EnableMapMode( bOldMapMode ); - - return res; -} - -Bitmap OutputDevice::ImplBlend( Bitmap aBmp, - BitmapReadAccess* pP, - BitmapReadAccess* pA, - const sal_Int32 nOffY, - const sal_Int32 nDstHeight, - const sal_Int32 nOffX, - const sal_Int32 nDstWidth, - const Rectangle& aBmpRect, - const Size& aOutSz, - const bool bHMirr, - const bool bVMirr, - const long* pMapX, - const long* pMapY ) -{ - BitmapColor aDstCol; - Bitmap res; - int nX, nY; - - if( GetBitCount() <= 8 ) - { - Bitmap aDither( aBmp.GetSizePixel(), 8 ); - BitmapColor aIndex( 0 ); - BitmapReadAccess* pB = aBmp.AcquireReadAccess(); - BitmapWriteAccess* pW = aDither.AcquireWriteAccess(); - - if( pB && pP && pA && pW ) - { - int nOutY; - - for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ ) - { - const long nMapY = pMapY[ nY ]; - const long nModY = ( nOutY & 0x0FL ) << 4L; - int nOutX; - - for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) - { - const long nMapX = pMapX[ nX ]; - const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ]; - - aDstCol = pB->GetColor( nY, nX ); - aDstCol.Merge( pP->GetColor( nMapY, nMapX ), pA->GetPixelIndex( nMapY, nMapX ) ); - aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); - pW->SetPixel( nY, nX, aIndex ); - } - } - } - - aBmp.ReleaseAccess( pB ); - aDither.ReleaseAccess( pW ); - res = aDither; - } - else - { - BitmapWriteAccess* pB = aBmp.AcquireWriteAccess(); - - bool bFastBlend = false; - if( pP && pA && pB ) - { - SalTwoRect aTR; - aTR.mnSrcX = aBmpRect.Left(); - aTR.mnSrcY = aBmpRect.Top(); - aTR.mnSrcWidth = aBmpRect.GetWidth(); - aTR.mnSrcHeight = aBmpRect.GetHeight(); - aTR.mnDestX = nOffX; - aTR.mnDestY = nOffY; - aTR.mnDestWidth = aOutSz.Width(); - aTR.mnDestHeight= aOutSz.Height(); - - if( !bHMirr && !bVMirr ) - bFastBlend = ImplFastBitmapBlending( *pB,*pP,*pA, aTR ); - } - - if( pP && pA && pB && !bFastBlend ) - { - switch( pP->GetScanlineFormat() ) - { - case( BMP_FORMAT_8BIT_PAL ): - { - for( nY = 0; nY < nDstHeight; nY++ ) - { - const long nMapY = pMapY[ nY ]; - Scanline pPScan = pP->GetScanline( nMapY ); - Scanline pAScan = pA->GetScanline( nMapY ); - - for( nX = 0; nX < nDstWidth; nX++ ) - { - const long nMapX = pMapX[ nX ]; - aDstCol = pB->GetPixel( nY, nX ); - pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ), - pAScan[ nMapX ] ) ); - } - } - } - break; - - case( BMP_FORMAT_24BIT_TC_BGR ): - { - for( nY = 0; nY < nDstHeight; nY++ ) - { - const long nMapY = pMapY[ nY ]; - Scanline pPScan = pP->GetScanline( nMapY ); - Scanline pAScan = pA->GetScanline( nMapY ); - - for( nX = 0; nX < nDstWidth; nX++ ) - { - const long nMapX = pMapX[ nX ]; - Scanline pTmp = pPScan + nMapX * 3; - - aDstCol = pB->GetPixel( nY, nX ); - pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 2 ], pTmp[ 1 ], pTmp[ 0 ], - pAScan[ nMapX ] ) ); - } - } - } - break; - - case( BMP_FORMAT_24BIT_TC_RGB ): - { - for( nY = 0; nY < nDstHeight; nY++ ) - { - const long nMapY = pMapY[ nY ]; - Scanline pPScan = pP->GetScanline( nMapY ); - Scanline pAScan = pA->GetScanline( nMapY ); - - for( nX = 0; nX < nDstWidth; nX++ ) - { - const long nMapX = pMapX[ nX ]; - Scanline pTmp = pPScan + nMapX * 3; - - aDstCol = pB->GetPixel( nY, nX ); - pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 0 ], pTmp[ 1 ], pTmp[ 2 ], - pAScan[ nMapX ] ) ); - } - } - } - break; - - default: - { - for( nY = 0; nY < nDstHeight; nY++ ) - { - const long nMapY = pMapY[ nY ]; - Scanline pAScan = pA->GetScanline( nMapY ); - - for( nX = 0; nX < nDstWidth; nX++ ) - { - const long nMapX = pMapX[ nX ]; - aDstCol = pB->GetPixel( nY, nX ); - pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ), - pAScan[ nMapX ] ) ); - } - } - } - break; - } - } - - aBmp.ReleaseAccess( pB ); - res = aBmp; - } - - return res; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |