diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-01-19 09:33:56 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-01-19 13:24:27 +0000 |
commit | 1c217968b609de4484388719427366e7ddbc48d0 (patch) | |
tree | 6a42e2b4ca57d7ceb0799ec16f963d60ff3cb09a | |
parent | 1e2bcb3177d58e6f446296ae28fcff7f5da9b620 (diff) |
always copying the full bitmap, not just a portion of it
Change-Id: Ib3e10d188c3f0d1bde40653d783f98ebfaed423c
-rw-r--r-- | basebmp/source/bitmapdevice.cxx | 179 | ||||
-rw-r--r-- | include/basebmp/bitmapdevice.hxx | 23 | ||||
-rw-r--r-- | vcl/headless/svpbmp.cxx | 3 | ||||
-rw-r--r-- | vcl/headless/svpgdi.cxx | 3 |
4 files changed, 28 insertions, 180 deletions
diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx index f40d931e79d7..1e582e7812d4 100644 --- a/basebmp/source/bitmapdevice.cxx +++ b/basebmp/source/bitmapdevice.cxx @@ -233,83 +233,59 @@ namespace template< typename Iterator, typename RawAcc > void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect, const Iterator& begin, const RawAcc& acc) { + const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); + const basegfx::B2IBox aRect(0, 0, rSrcSize.getX(),rSrcSize.getY()); + std::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) ); OSL_ASSERT( pSrcBmp ); scaleImage( srcIterRange(pSrcBmp->maBegin, pSrcBmp->maRawAccessor, - rSrcRect), + aRect), destIterRange(begin, acc, - rDstRect), + aRect), isSharedBuffer(rSrcBitmap) ); } template< typename Iterator, typename Acc > static void implDrawBitmapGeneric(const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect, const Iterator& begin, const Acc& acc) { + const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); + const basegfx::B2IBox aRect(0, 0, rSrcSize.getX(),rSrcSize.getY()); + GenericColorImageAccessor aSrcAcc( rSrcBitmap ); scaleImage( srcIterRange(vigra::Diff2D(), aSrcAcc, - rSrcRect), + aRect), destIterRange(begin, acc, - rDstRect)); + aRect)); } - void implDrawBitmapDirect(const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect) + void implDrawBitmapDirect(const BitmapDeviceSharedPtr& rSrcBitmap) { - sal_Int32 nSrcX = rSrcRect.getMinX(); - sal_Int32 nSrcY = rSrcRect.getMinY(); - sal_Int32 nSrcWidth = rSrcRect.getWidth(); - sal_Int32 nSrcHeight = rSrcRect.getHeight(); - sal_Int32 nDestX = rDstRect.getMinX(); - sal_Int32 nDestY = rDstRect.getMinY(); + const basegfx::B2IVector& rSrcSize(rSrcBitmap->getSize()); + + sal_Int32 nSrcWidth = rSrcSize.getX(); + sal_Int32 nSrcHeight = rSrcSize.getY(); char* dstBuf = reinterpret_cast<char*>(getBuffer().get()); char* srcBuf = reinterpret_cast<char*>(rSrcBitmap->getBuffer().get()); sal_Int32 dstStride = getScanlineStride(); sal_Int32 srcStride = rSrcBitmap->getScanlineStride(); sal_Int32 bytesPerPixel = (bitsPerPixel[getScanlineFormat()] + 7) >> 3; // round up to bytes - bool dstTopDown = true; - bool srcTopDown = true; - - if (dstBuf == srcBuf && nSrcY < nDestY) // reverse copy order to avoid overlapping - { - nSrcY = getBufferSize().getY() - nSrcY - nSrcHeight; - nDestY = getBufferSize().getY() - nDestY - nSrcHeight; - srcTopDown = !srcTopDown; - dstTopDown = !dstTopDown; - } - if (!dstTopDown) - { - dstBuf += dstStride * (getBufferSize().getY() - 1); - dstStride = -dstStride; - } - - if (!srcTopDown) - { - srcBuf += srcStride * (rSrcBitmap->getBufferSize().getY() - 1); - srcStride = -srcStride; - } - - char* dstline = dstBuf + dstStride * nDestY + nDestX * bytesPerPixel; - char* srcline = srcBuf + srcStride * nSrcY + nSrcX * bytesPerPixel; + char* dstline = dstBuf; + char* srcline = srcBuf; sal_Int32 lineBytes = nSrcWidth * bytesPerPixel; for(; 0 < nSrcHeight; nSrcHeight--) @@ -320,24 +296,21 @@ namespace } } - virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect ) override + virtual void copyBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap) override { if( isCompatibleBitmap( rSrcBitmap ) ) { if (bitsPerPixel[getScanlineFormat()] >= 8 - && rSrcRect.getWidth() == rDstRect.getWidth() && rSrcRect.getHeight() == rDstRect.getHeight() && rSrcBitmap->getScanlineFormat() == getScanlineFormat()) - implDrawBitmapDirect(rSrcBitmap, rSrcRect, rDstRect); + implDrawBitmapDirect(rSrcBitmap); else - implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect, + implDrawBitmap(rSrcBitmap, maBegin, maRawAccessor); } else { - implDrawBitmapGeneric(rSrcBitmap, rSrcRect, rDstRect, + implDrawBitmapGeneric(rSrcBitmap, maBegin, maAccessor); } @@ -473,115 +446,9 @@ sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt ) return 0; } -namespace -{ - void assertImageRange( const basegfx::B2IBox& rRange, - const basegfx::B2IBox& rPermittedRange ) - { -#if OSL_DEBUG_LEVEL > 0 - basegfx::B2IBox aRange( rRange ); - aRange.intersect( rPermittedRange ); - - OSL_ASSERT( aRange == rRange ); -#else - (void)rRange; (void)rPermittedRange; -#endif - } - - // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down - // to basegfx, and use here! - bool clipAreaImpl( ::basegfx::B2IBox& io_rDestArea, - ::basegfx::B2IBox& io_rSourceArea, - const ::basegfx::B2IBox& rDestBounds, - const ::basegfx::B2IBox& rSourceBounds ) - { - // extract inherent scale - double fWidth = io_rSourceArea.getWidth(); - if (fWidth == 0.0) - return false; - - double fHeight = io_rSourceArea.getHeight(); - if (fHeight == 0.0) - return false; - - const double nScaleX( io_rDestArea.getWidth() / fWidth ); - const double nScaleY( io_rDestArea.getHeight() / fHeight ); - - // extract range origins - const basegfx::B2IPoint aDestTopLeft( - io_rDestArea.getMinimum() ); - const ::basegfx::B2IPoint aSourceTopLeft( - io_rSourceArea.getMinimum() ); - - ::basegfx::B2IBox aLocalSourceArea( io_rSourceArea ); - - // clip source area (which must be inside rSourceBounds) - aLocalSourceArea.intersect( rSourceBounds ); - - if( aLocalSourceArea.isEmpty() ) - return false; - - // calc relative new source area points (relative to orig - // source area) - const ::basegfx::B2IVector aUpperLeftOffset( - aLocalSourceArea.getMinimum()-aSourceTopLeft ); - const ::basegfx::B2IVector aLowerRightOffset( - aLocalSourceArea.getMaximum()-aSourceTopLeft ); - - ::basegfx::B2IBox aLocalDestArea( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()), - basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()), - basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()), - basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) ); - - // clip dest area (which must be inside rDestBounds) - aLocalDestArea.intersect( rDestBounds ); - - if( aLocalDestArea.isEmpty() ) - return false; - - // calc relative new dest area points (relative to orig - // source area) - const ::basegfx::B2IVector aDestUpperLeftOffset( - aLocalDestArea.getMinimum()-aDestTopLeft ); - const ::basegfx::B2IVector aDestLowerRightOffset( - aLocalDestArea.getMaximum()-aDestTopLeft ); - - io_rSourceArea = ::basegfx::B2IBox( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX), - basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY), - basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX), - basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) ); - io_rDestArea = aLocalDestArea; - - // final source area clip (chopping round-offs) - io_rSourceArea.intersect( rSourceBounds ); - - if( io_rSourceArea.isEmpty() ) - return false; - - - return true; - } -} - -void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect ) +void BitmapDevice::copyBitmap( const BitmapDeviceSharedPtr& rSrcBitmap ) { - const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); - const basegfx::B2IBox aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); - basegfx::B2IBox aSrcRange( rSrcRect ); - basegfx::B2IBox aDestRange( rDstRect ); - - if( clipAreaImpl( aDestRange, - aSrcRange, - mpImpl->maBounds, - aSrcBounds )) - { - assertImageRange(aDestRange,mpImpl->maBounds); - assertImageRange(aSrcRange,aSrcBounds); - - drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange ); - } + copyBitmap_i( rSrcBitmap ); } /** Standard clip and alpha masks diff --git a/include/basebmp/bitmapdevice.hxx b/include/basebmp/bitmapdevice.hxx index 16c89aa6b8b2..5f2756c9d17d 100644 --- a/include/basebmp/bitmapdevice.hxx +++ b/include/basebmp/bitmapdevice.hxx @@ -118,23 +118,9 @@ public: /** Draw another bitmap into this device @param rSrcBitmap - Bitmap to render into this one. It is permitted that source - and destination bitmap are the same. - - @param rSrcRect - Rectangle within the source bitmap to take the pixel from. - - @param rDstRect - Rectangle in the destination bitmap to put the pixel - into. Source and destination rectangle are permitted to have - differing sizes; this method will scale the source pixel - accordingly. Please note that both source and destination - rectangle are interpreted excluding the rightmost pixel column - and the bottommost pixel row + Bitmap to render into this one. */ - void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect ); + void copyBitmap( const BitmapDeviceSharedPtr& rSrcBitmap ); protected: BASEBMP_DLLPRIVATE BitmapDevice( const basegfx::B2IBox& rBounds, @@ -155,10 +141,7 @@ private: BASEBMP_DLLPRIVATE virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) = 0; - // must work with *this == rSrcBitmap! - BASEBMP_DLLPRIVATE virtual void drawBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap, - const basegfx::B2IBox& rSrcRect, - const basegfx::B2IBox& rDstRect ) = 0; + BASEBMP_DLLPRIVATE virtual void copyBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap ) = 0; BitmapDeviceSharedPtr getGenericRenderer() const; diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx index 6ef56848dee4..e0b1afbbf5ed 100644 --- a/vcl/headless/svpbmp.cxx +++ b/vcl/headless/svpbmp.cxx @@ -79,8 +79,7 @@ bool SvpSalBitmap::Create( const SalBitmap& rSalBmp ) { B2IVector aSize = rSrcBmp->getSize(); m_aBitmap = cloneBitmapDevice( aSize, rSrcBmp ); - B2IBox aRect( 0, 0, aSize.getX(), aSize.getY() ); - m_aBitmap->drawBitmap(rSrcBmp, aRect, aRect); + m_aBitmap->copyBitmap(rSrcBmp); } else m_aBitmap.reset(); diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 390ed8fc03fe..eb96693a0b18 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -130,9 +130,8 @@ namespace Size aSize = rSourceBitmap.GetSize(); aTmpBmp.Create(aSize, 0, BitmapPalette()); assert(aTmpBmp.GetBitCount() == 32); - basegfx::B2IBox aRect(0, 0, aSize.Width(), aSize.Height()); const basebmp::BitmapDeviceSharedPtr& rTmpSrc = aTmpBmp.getBitmap(); - rTmpSrc->drawBitmap(rSrcBmp, aRect, aRect); + rTmpSrc->copyBitmap(rSrcBmp); source = SvpSalGraphics::createCairoSurface(rTmpSrc); } else |