summaryrefslogtreecommitdiff
path: root/vcl/source/outdev/bitmap.cxx
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2015-01-03 13:14:55 +0900
committerTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2015-01-19 00:07:24 +0900
commit009c1752b1eff36827dae4fa9bd394c5089dcc55 (patch)
treede783aaf3a0211acd012a6af5c3f9e6d07fdb78d /vcl/source/outdev/bitmap.cxx
parent15db0307fe6429238be72612cccd4a1df5e1e97c (diff)
Extract slow path of DrawDeviceAlphaBitmap into its own method
Additioanlly cleanup and use ScopedReadAccess Change-Id: Ia3365f4dc968368bdd90d4398188bffe2d56e89b
Diffstat (limited to 'vcl/source/outdev/bitmap.cxx')
-rw-r--r--vcl/source/outdev/bitmap.cxx253
1 files changed, 137 insertions, 116 deletions
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 680f36231c5b..50877bea8011 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -604,36 +604,37 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
const Point& rDestPt, const Size& rDestSize,
const Point& rSrcPtPixel, const Size& rSrcSizePixel )
{
- Point aOutPt( LogicToPixel( rDestPt ) );
- Size aOutSz( LogicToPixel( rDestSize ) );
- Rectangle aDstRect( Point(), GetOutputSizePixel() );
- const bool bHMirr = aOutSz.Width() < 0;
- const bool bVMirr = aOutSz.Height() < 0;
+ Point aOutPt(LogicToPixel(rDestPt));
+ Size aOutSz(LogicToPixel(rDestSize));
+ Rectangle aDstRect(Point(), GetOutputSizePixel());
+
+ const bool bHMirr = aOutSz.Width() < 0;
+ const bool bVMirr = aOutSz.Height() < 0;
ClipToPaintRegion(aDstRect);
- if( bHMirr )
+ if (bHMirr)
{
aOutSz.Width() = -aOutSz.Width();
- aOutPt.X() -= ( aOutSz.Width() - 1L );
+ aOutPt.X() -= aOutSz.Width() - 1L;
}
- if( bVMirr )
+ if (bVMirr)
{
aOutSz.Height() = -aOutSz.Height();
- aOutPt.Y() -= ( aOutSz.Height() - 1L );
+ aOutPt.Y() -= aOutSz.Height() - 1L;
}
- if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
+ if (!aDstRect.Intersection(Rectangle(aOutPt, aOutSz)).IsEmpty())
{
static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
// #i83087# Naturally, system alpha blending cannot work with
// separate alpha VDev
bool bTryDirectPaint(!pDisableNative && !bHMirr && !bVMirr);
- if(bTryDirectPaint)
+ if (bTryDirectPaint)
{
- Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY );
+ Point aRelPt = aOutPt + Point(mnOutOffX, mnOutOffY);
SalTwoRect aTR(
rSrcPtPixel.X(), rSrcPtPixel.Y(),
rSrcSizePixel.Width(), rSrcSizePixel.Height(),
@@ -644,19 +645,19 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
// try the blen the alpha bitmap with the alpha virtual device
- if( mpAlphaVDev )
+ if (mpAlphaVDev)
{
Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) );
SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetImpBitmap()->ImplGetSalBitmap();
- if( mpGraphics->BlendAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this ) )
+ if (mpGraphics->BlendAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this))
{
- mpAlphaVDev->BlendBitmap( aTR, rAlpha );
+ mpAlphaVDev->BlendBitmap(aTR, rAlpha);
return;
}
}
else
{
- if (mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this ))
+ if (mpGraphics->DrawAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, this))
return;
}
}
@@ -664,122 +665,142 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
// we need to make sure OpenGL never reaches this slow code path
assert(!OpenGLHelper::isVCLOpenGLEnabled());
- VirtualDevice* pOldVDev = mpAlphaVDev;
-
- Rectangle aBmpRect( Point(), rBmp.GetSizePixel() );
+ Rectangle aBmpRect(Point(), rBmp.GetSizePixel());
if (!aBmpRect.Intersection(Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty())
{
- // The scaling in this code path produces really ugly results - it
- // does the most trivial scaling with no smoothing.
-
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- const bool bOldMap = mbMap;
- mpMetaFile = NULL; // fdo#55044 reset before GetBitmap!
- mbMap = false;
- Bitmap aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
-
- // #109044# The generated bitmap need not necessarily be
- // of aDstRect dimensions, it's internally clipped to
- // window bounds. Thus, we correct the dest size here,
- // since we later use it (in nDstWidth/Height) for pixel
- // access)
- // #i38887# reading from screen may sometimes fail
- if( aBmp.ImplGetImpBitmap() )
- aDstRect.SetSize( aBmp.GetSizePixel() );
-
- BitmapColor aDstCol;
- const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
- const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
- const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
- // calculate offset in original bitmap
- // in RTL case this is a little more complicated since the contents of the
- // bitmap is not mirrored (it never is), however the paint region and bmp region
- // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
- // is content wise somewhere else and needs to take mirroring into account
- const long nOffX = IsRTLEnabled()
- ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X())
- : aDstRect.Left() - aOutPt.X(),
- nOffY = aDstRect.Top() - aOutPt.Y();
- long nX, nOutX, nY, nOutY;
- long nMirrOffX = 0;
- long nMirrOffY = 0;
- boost::scoped_array<long> pMapX(new long[ nDstWidth ]);
- boost::scoped_array<long> pMapY(new long[ nDstHeight ]);
-
- // create horizontal mapping table
- if( bHMirr )
- nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;
-
- for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
- {
- pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
- if( bHMirr )
- pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
- }
+ DrawDeviceAlphaBitmapSlowPath(rBmp, rAlpha, aDstRect, aBmpRect, aOutSz, aOutPt);
+ }
+ }
+}
- // create vertical mapping table
- if( bVMirr )
- nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;
+void OutputDevice::DrawDeviceAlphaBitmapSlowPath(const Bitmap& rBitmap, const AlphaMask& rAlpha, Rectangle aDstRect, Rectangle aBmpRect, Size& aOutSize, Point& aOutPoint)
+{
+ VirtualDevice* pOldVDev = mpAlphaVDev;
- for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
- {
- pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
+ const bool bHMirr = aOutSize.Width() < 0;
+ const bool bVMirr = aOutSize.Height() < 0;
- if( bVMirr )
- pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
- }
+ // The scaling in this code path produces really ugly results - it
+ // does the most trivial scaling with no smoothing.
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ const bool bOldMap = mbMap;
- BitmapReadAccess* pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
- BitmapReadAccess* pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
+ mpMetaFile = NULL; // fdo#55044 reset before GetBitmap!
+ mbMap = false;
- DBG_ASSERT( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
- pA->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
- "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
+ Bitmap aBmp(GetBitmap(aDstRect.TopLeft(), aDstRect.GetSize()));
- // #i38887# reading from screen may sometimes fail
- if( aBmp.ImplGetImpBitmap() )
- {
- Bitmap aTmp;
+ // #109044# The generated bitmap need not necessarily be
+ // of aDstRect dimensions, it's internally clipped to
+ // window bounds. Thus, we correct the dest size here,
+ // since we later use it (in nDstWidth/Height) for pixel
+ // access)
+ // #i38887# reading from screen may sometimes fail
+ if (aBmp.ImplGetImpBitmap())
+ {
+ aDstRect.SetSize(aBmp.GetSizePixel());
+ }
- if( mpAlphaVDev )
- {
- aTmp = BlendBitmapWithAlpha(
- aBmp,pP,pA,
- aDstRect,
- nOffY,nDstHeight,
- nOffX,nDstWidth,
- pMapX.get(),pMapY.get() );
- }
- else
- {
- aTmp = BlendBitmap(
- aBmp,pP,pA,
- nOffY,nDstHeight,
- nOffX,nDstWidth,
- aBmpRect,aOutSz,
- bHMirr,bVMirr,
- pMapX.get(),pMapY.get() );
- }
+ BitmapColor aDstCol;
+ const long nSrcWidth = aBmpRect.GetWidth();
+ const long nSrcHeight = aBmpRect.GetHeight();
- // #110958# Disable alpha VDev, we're doing the necessary
- // stuff explicitly furher below
- if( mpAlphaVDev )
- mpAlphaVDev = NULL;
+ const long nDstWidth = aDstRect.GetWidth();
+ const long nDstHeight = aDstRect.GetHeight();
- DrawBitmap( aDstRect.TopLeft(),
- aTmp );
+ const long nOutWidth = aOutSize.Width();
+ const long nOutHeight = aOutSize.Height();
- // #110958# Enable alpha VDev again
- mpAlphaVDev = pOldVDev;
- }
+ // calculate offset in original bitmap
+ // in RTL case this is a little more complicated since the contents of the
+ // bitmap is not mirrored (it never is), however the paint region and bmp region
+ // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these
+ // is content wise somewhere else and needs to take mirroring into account
+ const long nOffX = IsRTLEnabled()
+ ? aOutSize.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPoint.X())
+ : aDstRect.Left() - aOutPoint.X();
+
+ const long nOffY = aDstRect.Top() - aOutPoint.Y();
- ( (Bitmap&) rBmp ).ReleaseAccess( pP );
- ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
+ long nX, nOutX, nY, nOutY;
+ long nMirrOffX = 0;
+ long nMirrOffY = 0;
- mbMap = bOldMap;
- mpMetaFile = pOldMetaFile;
+ boost::scoped_array<long> pMapX(new long[nDstWidth]);
+ boost::scoped_array<long> pMapY(new long[nDstHeight]);
+
+ // create horizontal mapping table
+ if (bHMirr)
+ {
+ nMirrOffX = (aBmpRect.Left() << 1) + nSrcWidth - 1;
+ }
+
+ for (nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++)
+ {
+ pMapX[nX] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
+ if(bHMirr)
+ pMapX[nX] = nMirrOffX - pMapX[nX];
+ }
+
+ // create vertical mapping table
+ if (bVMirr)
+ {
+ nMirrOffY = (aBmpRect.Top() << 1) + nSrcHeight - 1;
+ }
+
+ for(nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++)
+ {
+ pMapY[nY] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
+
+ if (bVMirr)
+ pMapY[nY] = nMirrOffY - pMapY[nY];
+ }
+
+ Bitmap::ScopedReadAccess pBitmapReadAccess(const_cast<Bitmap&>(rBitmap));
+ AlphaMask::ScopedReadAccess pAlphaReadAccess(const_cast<AlphaMask&>(rAlpha));
+
+ DBG_ASSERT( pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
+ pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
+ "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
+
+ // #i38887# reading from screen may sometimes fail
+ if (aBmp.ImplGetImpBitmap())
+ {
+ Bitmap aNewBitmap;
+
+ if (mpAlphaVDev)
+ {
+ aNewBitmap = BlendBitmapWithAlpha(
+ aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
+ aDstRect,
+ nOffY, nDstHeight,
+ nOffX, nDstWidth,
+ pMapX.get(), pMapY.get() );
}
+ else
+ {
+ aNewBitmap = BlendBitmap(
+ aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
+ nOffY, nDstHeight,
+ nOffX, nDstWidth,
+ aBmpRect, aOutSize,
+ bHMirr, bVMirr,
+ pMapX.get(), pMapY.get() );
+ }
+
+ // #110958# Disable alpha VDev, we're doing the necessary
+ // stuff explicitly furher below
+ if (mpAlphaVDev)
+ mpAlphaVDev = NULL;
+
+ DrawBitmap(aDstRect.TopLeft(), aNewBitmap);
+
+ // #110958# Enable alpha VDev again
+ mpAlphaVDev = pOldVDev;
}
+
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
}
void OutputDevice::ScaleBitmap (Bitmap &rBmp, SalTwoRect &rPosAry)