summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <quikee@gmail.com>2012-09-02 17:23:03 +0200
committerTomaž Vajngerl <quikee@gmail.com>2012-09-02 17:30:51 +0200
commit4b161067d46ddd48b4602ccdcc4d1b2545e2ac83 (patch)
tree15c301a51f935c216eb64946f447d1504cad9c6f
parent35e13d1f5403076c752879ecbe17b2f451b188d9 (diff)
Stepwise rebuild bitmap rendering from scratch to avoid rendering bugs.
Bitmap rendering was rebuild from the original state and checked for rendering bugs at every change. Currently the implementation supports scaling by averagin for RGB channels an for alpha channel in some cases. For scaling factor > 0.6, the original bilinear scaling is used. Implementation is currently still in "outdev2" but is decoupled and will be moved to its proper place into "bitmap" and "bitmapex". Change-Id: I6feb744712956a92d6140d079dc3a85ee8511930
-rw-r--r--svtools/source/graphic/grfmgr2.cxx726
-rw-r--r--vcl/inc/vcl/bitmap.hxx18
-rw-r--r--vcl/inc/vcl/bitmapex.hxx5
-rw-r--r--vcl/source/gdi/bitmap3.cxx233
-rw-r--r--vcl/source/gdi/bitmapex.cxx56
5 files changed, 613 insertions, 425 deletions
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 2cc7ae3762e5..299f883f8c5c 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -46,6 +46,7 @@
#define WATERMARK_LUM_OFFSET 50
#define WATERMARK_CON_OFFSET -70
+#define MAP( cVal0, cVal1, nFrac ) ((sal_uInt8)((((long)(cVal0)<<20L)+nFrac*((long)(cVal1)-(cVal0)))>>20L))
// ------------------
// - GraphicManager -
@@ -264,172 +265,659 @@ sal_Bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
return bRet;
}
-sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
- const Point& rPoint, const Size& rSize,
- const BitmapEx& rBitmapEx, const GraphicAttr& rAttributes,
- const sal_uLong nFlags, BitmapEx* pResultBitmapEx )
+sal_Bool ImplCreateRotatedScaled( const BitmapEx& rBmpEx, const GraphicAttr& rAttributes,
+ sal_uInt16 nRot10, const Size& rUnrotatedSzPix,
+ long nStartX, long nEndX, long nStartY, long nEndY,
+ BitmapEx& rOutBmpEx )
{
- bool bRet = false;
+ const long aUnrotatedWidth = rUnrotatedSzPix.Width();
+ const long aUnrotatedHeight = rUnrotatedSzPix.Height();
+ const long aBitmapWidth = rBmpEx.GetSizePixel().Width();
+ const long aBitmapHeight = rBmpEx.GetSizePixel().Height();
- Point aUnrotatedPointInPixels( pOutputDevice->LogicToPixel( rPoint ) );
- Size aUnrotatedSizeInPixels( pOutputDevice->LogicToPixel( rSize ) );
+ long nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY, nTmp;
+ double fTmp;
- if( aUnrotatedSizeInPixels.Width() <= 0 || aUnrotatedSizeInPixels.Height() <= 0)
- return false;
+ bool bHMirr = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+ bool bVMirr = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+
+ long* pMapIX = new long[ aUnrotatedWidth ];
+ long* pMapFX = new long[ aUnrotatedWidth ];
+ long* pMapIY = new long[ aUnrotatedHeight ];
+ long* pMapFY = new long[ aUnrotatedHeight ];
+
+ const double fScaleX = ( aUnrotatedWidth - 1 ) / (double) ( aBitmapWidth - 1 );
+ const double fScaleY = ( aUnrotatedHeight - 1 ) / (double) ( aBitmapHeight - 1 );
- Point aOutPointInPixels;
- Size aOutSizeInPixels;
- BitmapEx aBitmapEx( rBitmapEx );
- int nRotation = rAttributes.GetRotation() % 3600;
+ const double fRevScaleX = 1.0 / fScaleX;
+ const double fRevScaleY = 1.0 / fScaleY;
- if( nRotation != 0 )
+ int x,y;
+
+ // create horizontal mapping table
+ for( x = 0, nTmpX = aBitmapWidth - 1L, nTmp = aBitmapWidth - 2L; x < aUnrotatedWidth; x++ )
{
- Polygon aPoly( Rectangle( rPoint, rSize ) );
- aPoly.Rotate( rPoint, nRotation );
- const Rectangle aRotationBoundRect( aPoly.GetBoundRect() );
- aOutPointInPixels = pOutputDevice->LogicToPixel( aRotationBoundRect.TopLeft() );
- aOutSizeInPixels = pOutputDevice->LogicToPixel( aRotationBoundRect.GetSize() );
+ fTmp = x * fRevScaleX;
+
+ if( bHMirr )
+ fTmp = nTmpX - fTmp;
+
+ pMapIX[ x ] = MinMax( fTmp, 0, nTmp );
+ pMapFX[ x ] = (long) ( ( fTmp - pMapIX[ x ] ) * 1048576.0 );
}
- else
+
+ // create vertical mapping table
+ for( y = 0, nTmpY = aBitmapHeight - 1L, nTmp = aBitmapHeight - 2L; y < aUnrotatedHeight; y++ )
{
- aOutPointInPixels = aUnrotatedPointInPixels;
- aOutSizeInPixels = aUnrotatedSizeInPixels;
+ fTmp = y * fRevScaleY;
+
+ if( bVMirr )
+ fTmp = nTmpY - fTmp;
+
+ pMapIY[ y ] = MinMax( fTmp, 0, nTmp );
+ pMapFY[ y ] = (long) ( ( fTmp - pMapIY[ y ] ) * 1048576.0 );
}
- Point aOutPoint;
- Size aOutSize;
- const Size& rBitmapSizePixels = rBitmapEx.GetSizePixel();
- Rectangle aCropRectangle(0, 0, 0, 0);
+ Bitmap aBmp( rBmpEx.GetBitmap() );
+ Bitmap aOutBmp;
+ BitmapReadAccess* pReadAccess = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pWriteAccess;
+
+ const double fCosAngle = cos( nRot10 * F_PI1800 );
+ const double fSinAngle = sin( nRot10 * F_PI1800 );
+ const long aTargetWidth = nEndX - nStartX + 1L;
+ const long aTargetHeight = nEndY - nStartY + 1L;
+ long* pCosX = new long[ aTargetWidth ];
+ long* pSinX = new long[ aTargetWidth ];
+ long* pCosY = new long[ aTargetHeight ];
+ long* pSinY = new long[ aTargetHeight ];
+ long nUnRotX, nUnRotY, nSinY, nCosY;
+ sal_uInt8 cR0, cG0, cB0, cR1, cG1, cB1;
+ bool bRet = false;
- bool isHorizontalMirrored = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
- bool isVerticalMirrored = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+ Polygon aPoly( Rectangle( Point(), rUnrotatedSzPix ) );
+ aPoly.Rotate( Point(), nRot10 );
+ Rectangle aNewBound( aPoly.GetBoundRect() );
- // calculate output sizes
- if( true || !pResultBitmapEx )
+ bool scaleByAveraging = fScaleX < 0.6 || fScaleY < 0.6;
+
+ // create horizontal mapping table
+ for( x = 0, nTmpX = aNewBound.Left() + nStartX; x < aTargetWidth; x++ )
{
- Rectangle aBitmapRectangle( aOutPointInPixels, aOutSizeInPixels );
- Rectangle aOutRect( Point(), pOutputDevice->GetOutputSizePixel() );
+ pCosX[ x ] = FRound( fCosAngle * ( fTmp = nTmpX++ << 8 ) );
+ pSinX[ x ] = FRound( fSinAngle * fTmp );
+ }
- if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
+ // create vertical mapping table
+ for( y = 0, nTmpY = aNewBound.Top() + nStartY; y < aTargetHeight; y++ )
+ {
+ pCosY[ y ] = FRound( fCosAngle * ( fTmp = nTmpY++ << 8 ) );
+ pSinY[ y ] = FRound( fSinAngle * fTmp );
+ }
+
+ if( pReadAccess )
+ {
+ aOutBmp = Bitmap( Size( aTargetWidth, aTargetHeight ), 24 );
+ pWriteAccess = aOutBmp.AcquireWriteAccess();
+
+ if( pWriteAccess )
{
- const Region aPaintRegion( ( (Window*) pOutputDevice )->GetPaintRegion() );
+ BitmapColor aColRes;
+
+ if ( !scaleByAveraging )
+ {
+ if( pReadAccess->HasPalette() )
+ {
+ for( y = 0; y < aTargetHeight; y++ )
+ {
+ nSinY = pSinY[ y ];
+ nCosY = pCosY[ y ];
+
+ for( x = 0; x < aTargetWidth; x++ )
+ {
+ nUnRotX = ( pCosX[ x ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ x ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < aUnrotatedWidth ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < aUnrotatedHeight ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const BitmapColor& rCol0 = pReadAccess->GetPaletteColor( pReadAccess->GetPixel( nTmpY, nTmpX ) );
+ const BitmapColor& rCol1 = pReadAccess->GetPaletteColor( pReadAccess->GetPixel( nTmpY, ++nTmpX ) );
+ cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
+ cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
+
+ const BitmapColor& rCol3 = pReadAccess->GetPaletteColor( pReadAccess->GetPixel( ++nTmpY, nTmpX ) );
+ const BitmapColor& rCol2 = pReadAccess->GetPaletteColor( pReadAccess->GetPixel( nTmpY, --nTmpX ) );
+ cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
+ cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
+ cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWriteAccess->SetPixel( y, x, aColRes );
+ }
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol0, aCol1;
+
+ for( y = 0; y < aTargetHeight; y++ )
+ {
+ nSinY = pSinY[ y ];
+ nCosY = pCosY[ y ];
+
+ for( x = 0; x < aTargetWidth; x++ )
+ {
+ nUnRotX = ( pCosX[ x ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ x ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < aUnrotatedWidth ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < aUnrotatedHeight ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ aCol0 = pReadAccess->GetPixel( nTmpY, nTmpX );
+ aCol1 = pReadAccess->GetPixel( nTmpY, ++nTmpX );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pReadAccess->GetPixel( ++nTmpY, nTmpX );
+ aCol0 = pReadAccess->GetPixel( nTmpY, --nTmpX );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWriteAccess->SetPixel( y, x, aColRes );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ double aSumRed, aSumGreen, aSumBlue, aCount;
+ BitmapColor aColor;
+ BitmapColor aResultColor;
+
+ for( y = 0; y < aTargetHeight; y++ )
+ {
+ nSinY = pSinY[ y ];
+ nCosY = pCosY[ y ];
- if( !aPaintRegion.IsNull() )
- aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRegion.GetBoundRect() ) );
+ for( x = 0; x < aTargetWidth; x++ )
+ {
+ double aUnrotatedX = ( pCosX[ x ] - nSinY ) / 256.0;
+ double aUnrotatedY = ( pSinX[ x ] + nCosY ) / 256.0;
+
+ if( ( aUnrotatedX >= 0 ) && ( aUnrotatedX < aUnrotatedWidth ) &&
+ ( aUnrotatedY >= 0 ) && ( aUnrotatedY < aUnrotatedHeight ) )
+ {
+ double dYStart = ((aUnrotatedY + 0.5) * fRevScaleY) - 0.5;
+ double dYEnd = ((aUnrotatedY + 1.5) * fRevScaleY) - 0.5;
+
+ int yStart = MinMax( dYStart, 0, aBitmapHeight - 1);
+ int yEnd = MinMax( dYEnd, 0, aBitmapHeight - 1);
+
+ double dXStart = ((aUnrotatedX + 0.5) * fRevScaleX) - 0.5;
+ double dXEnd = ((aUnrotatedX + 1.5) * fRevScaleX) - 0.5;
+
+ int xStart = MinMax( dXStart, 0, aBitmapWidth - 1);
+ int xEnd = MinMax( dXEnd, 0, aBitmapWidth - 1);
+
+ aSumRed = aSumGreen = aSumBlue = 0.0;
+ aCount = 0;
+
+ for (int yIn = yStart; yIn <= yEnd; yIn++)
+ {
+ for (int xIn = xStart; xIn <= xEnd; xIn++)
+ {
+ aColor = pReadAccess->GetPixel( yIn, xIn );
+
+ if( pReadAccess->HasPalette() )
+ aColor = pReadAccess->GetPaletteColor( aColor );
+
+ aSumRed += aColor.GetRed();
+ aSumGreen += aColor.GetGreen();
+ aSumBlue += aColor.GetBlue();
+
+ aCount++;
+ }
+ }
+
+ aResultColor.SetRed( MinMax( aSumRed / aCount, 0, 255) );
+ aResultColor.SetGreen( MinMax( aSumGreen / aCount, 0, 255) );
+ aResultColor.SetBlue( MinMax( aSumBlue / aCount, 0, 255) );
+
+ pWriteAccess->SetPixel( y, x, aResultColor );
+ }
+ }
+ }
+ }
+
+ aOutBmp.ReleaseAccess( pWriteAccess );
+ bRet = true;
}
- aOutRect.Intersection( aBitmapRectangle );
- if( !aOutRect.IsEmpty() )
+ aBmp.ReleaseAccess( pReadAccess );
+ }
+
+ // mask processing
+ if( bRet && ( rBmpEx.IsTransparent() || ( nRot10 != 0 && nRot10 != 900 && nRot10 != 1800 && nRot10 != 2700 ) ) )
+ {
+ bRet = false;
+
+ if( rBmpEx.IsAlpha() )
+ {
+ AlphaMask aAlpha( rBmpEx.GetAlpha() );
+ AlphaMask aOutAlpha;
+
+ pReadAccess = aAlpha.AcquireReadAccess();
+
+ if( pReadAccess )
+ {
+ aOutAlpha = AlphaMask( Size( aTargetWidth, aTargetHeight ) );
+ pWriteAccess = aOutAlpha.AcquireWriteAccess();
+
+ if( pWriteAccess )
+ {
+ if( pReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pWriteAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ if ( !scaleByAveraging )
+ {
+ Scanline pLine0, pLine1, pLineW;
+
+ for( nY = 0; nY < aTargetHeight; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+ pLineW = pWriteAccess->GetScanline( nY );
+
+ for( nX = 0; nX < aTargetWidth; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < aUnrotatedWidth ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < aUnrotatedHeight ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ], nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ pLine0 = pReadAccess->GetScanline( nTmpY++ );
+ pLine1 = pReadAccess->GetScanline( nTmpY );
+
+ const long nAlpha0 = pLine0[ nTmpX ];
+ const long nAlpha2 = pLine1[ nTmpX++ ];
+ const long nAlpha1 = pLine0[ nTmpX ];
+ const long nAlpha3 = pLine1[ nTmpX ];
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ *pLineW++ = MAP( n0, n1, nTmpFY );
+ }
+ else
+ *pLineW++ = 255;
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aTrans( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapColor aResultColor( 0 );
+ double aSum, aCount;
+
+ for( y = 0; y < aTargetHeight; y++ )
+ {
+ nSinY = pSinY[ y ];
+ nCosY = pCosY[ y ];
+
+ for( x = 0; x < aTargetWidth; x++ )
+ {
+
+ double aUnrotatedX = ( pCosX[ x ] - nSinY ) / 256.0;
+ double aUnrotatedY = ( pSinX[ x ] + nCosY ) / 256.0;
+
+ if( ( aUnrotatedX >= 0 ) && ( aUnrotatedX < aUnrotatedWidth ) &&
+ ( aUnrotatedY >= 0 ) && ( aUnrotatedY < aUnrotatedHeight ) )
+ {
+ double dYStart = ((aUnrotatedY + 0.5) * fRevScaleY) - 0.5;
+ double dYEnd = ((aUnrotatedY + 1.5) * fRevScaleY) - 0.5;
+
+ int yStart = MinMax( dYStart, 0, aBitmapHeight - 1);
+ int yEnd = MinMax( dYEnd, 0, aBitmapHeight - 1);
+
+ double dXStart = ((aUnrotatedX + 0.5) * fRevScaleX) - 0.5;
+ double dXEnd = ((aUnrotatedX + 1.5) * fRevScaleX) - 0.5;
+
+ int xStart = MinMax( dXStart, 0, aBitmapWidth - 1);
+ int xEnd = MinMax( dXEnd, 0, aBitmapWidth - 1);
+
+ aSum = 0.0;
+ aCount = 0;
+
+ for (int yIn = yStart; yIn <= yEnd; yIn++)
+ {
+ for (int xIn = xStart; xIn <= xEnd; xIn++)
+ {
+ aSum += pReadAccess->GetPixel( yIn, xIn ).GetIndex();
+ aCount++;
+ }
+ }
+ aResultColor.SetIndex( MinMax( aSum / aCount, 0, 255) );
+ pWriteAccess->SetPixel( y, x, aResultColor );
+ }
+ else
+ {
+ pWriteAccess->SetPixel( y, x, aTrans );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aTrans( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapColor aAlphaVal( 0 );
+
+ for( nY = 0; nY < aTargetHeight; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < aTargetWidth; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < aUnrotatedWidth ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < aUnrotatedHeight ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const long nAlpha0 = pReadAccess->GetPixel( nTmpY, nTmpX ).GetIndex();
+ const long nAlpha1 = pReadAccess->GetPixel( nTmpY, ++nTmpX ).GetIndex();
+ const long nAlpha3 = pReadAccess->GetPixel( ++nTmpY, nTmpX ).GetIndex();
+ const long nAlpha2 = pReadAccess->GetPixel( nTmpY, --nTmpX ).GetIndex();
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ aAlphaVal.SetIndex( MAP( n0, n1, nTmpFY ) );
+ pWriteAccess->SetPixel( nY, nX, aAlphaVal );
+ }
+ else
+ pWriteAccess->SetPixel( nY, nX, aTrans );
+ }
+ }
+ }
+
+ aOutAlpha.ReleaseAccess( pWriteAccess );
+ bRet = sal_True;
+ }
+
+ aAlpha.ReleaseAccess( pReadAccess );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
+ }
+ else
{
- aOutPoint = pOutputDevice->PixelToLogic( aOutRect.TopLeft() );
- aOutSize = pOutputDevice->PixelToLogic( aOutRect.GetSize() );
-
- aCropRectangle = Rectangle(
- aOutRect.Left() - aBitmapRectangle.Left(),
- aOutRect.Top() - aBitmapRectangle.Top(),
- aOutRect.Right() - aBitmapRectangle.Left(),
- aOutRect.Bottom() - aBitmapRectangle.Top() );
+ Bitmap aOutMsk( Size( aTargetWidth, aTargetHeight ), 1 );
+ pWriteAccess = aOutMsk.AcquireWriteAccess();
+
+ if( pWriteAccess )
+ {
+ Bitmap aMsk( rBmpEx.GetMask() );
+ const BitmapColor aB( pWriteAccess->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aW( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapReadAccess* pMAcc = NULL;
+
+ if( !aMsk || ( ( pMAcc = aMsk.AcquireReadAccess() ) != NULL ) )
+ {
+ long* pMapLX = new long[ aUnrotatedWidth ];
+ long* pMapLY = new long[ aUnrotatedHeight ];
+ BitmapColor aTestB;
+
+ if( pMAcc )
+ aTestB = pMAcc->GetBestMatchingColor( Color( COL_BLACK ) );
+
+ // create new horizontal mapping table
+ for( nX = 0UL; nX < aUnrotatedWidth; nX++ )
+ pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576. );
+
+ // create new vertical mapping table
+ for( nY = 0UL; nY < aUnrotatedHeight; nY++ )
+ pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576. );
+
+ // do mask rotation
+ for( nY = 0; nY < aTargetHeight; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < aTargetWidth; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < aUnrotatedWidth ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < aUnrotatedHeight ) )
+ {
+ if( pMAcc )
+ {
+ if( pMAcc->GetPixel( pMapLY[ nUnRotY ], pMapLX[ nUnRotX ] ) == aTestB )
+ pWriteAccess->SetPixel( nY, nX, aB );
+ else
+ pWriteAccess->SetPixel( nY, nX, aW );
+ }
+ else
+ pWriteAccess->SetPixel( nY, nX, aB );
+ }
+ else
+ pWriteAccess->SetPixel( nY, nX, aW );
+ }
+ }
+
+ delete[] pMapLX;
+ delete[] pMapLY;
+
+ if( pMAcc )
+ aMsk.ReleaseAccess( pMAcc );
+
+ bRet = sal_True;
+ }
+
+ aOutMsk.ReleaseAccess( pWriteAccess );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
}
+
+ if( !bRet )
+ rOutBmpEx = aOutBmp;
}
else
- {
- aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
- aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
+ rOutBmpEx = aOutBmp;
- aCropRectangle = Rectangle(
- 0, 0,
- aOutSizeInPixels.Width() - 1,
- aOutSizeInPixels.Height() - 1 );
- }
+ delete[] pSinX;
+ delete[] pCosX;
+ delete[] pSinY;
+ delete[] pCosY;
+ delete[] pMapIX;
+ delete[] pMapFX;
+ delete[] pMapIY;
+ delete[] pMapFY;
- if( aCropRectangle.GetWidth() <= 0 && aCropRectangle.GetHeight() <= 0 )
- return false;
+ return bRet;
+}
+
+sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
+ const Point& rPoint, const Size& rSize,
+ const BitmapEx& rBitmapEx, const GraphicAttr& rAttributes,
+ const sal_uLong /*nFlags*/, BitmapEx* pBmpEx )
+{
+ sal_uInt16 nRot10 = rAttributes.GetRotation() % 3600;
+
+ Point aOutputPointPix;
+ Size aOutputSizePix;
+ Point aUnrotatedPointPix( pOutputDevice->LogicToPixel( rPoint ) );
+ Size aUnrotatedSizePix( pOutputDevice->LogicToPixel( rSize ) );
+
+ bool bRet = false;
- // do transformation
- if( !isHorizontalMirrored &&
- !isVerticalMirrored &&
- !nRotation &&
- aOutSizeInPixels == rBitmapSizePixels)
+ if( nRot10 )
{
- // simple copy thorugh
- aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
- aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
- bRet = true;
+ Polygon aPoly( Rectangle( rPoint, rSize ) );
+ aPoly.Rotate( rPoint, nRot10 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ aOutputPointPix = pOutputDevice->LogicToPixel( aRotBoundRect.TopLeft() );
+ aOutputSizePix = pOutputDevice->LogicToPixel( aRotBoundRect.GetSize() );
}
else
{
- // mirror the image - this should not impact the picture dimenstions
- if( isHorizontalMirrored || isVerticalMirrored )
- bRet = aBitmapEx.Mirror( rAttributes.GetMirrorFlags() );
+ aOutputPointPix = aUnrotatedPointPix;
+ aOutputSizePix = aUnrotatedSizePix;
+ }
- // prepare rotation if needed
- if (nRotation != 0)
+ if( aUnrotatedSizePix.Width() && aUnrotatedSizePix.Height() )
+ {
+ BitmapEx aBmpEx( rBitmapEx );
+ BitmapEx aOutBmpEx;
+ Point aOutPoint;
+ Size aOutSize;
+ const Size& rBmpSzPix = rBitmapEx.GetSizePixel();
+ const long nW = rBmpSzPix.Width();
+ const long nH = rBmpSzPix.Height();
+ long nStartX = -1, nStartY = -1, nEndX = -1, nEndY = -1;
+ bool bHMirr = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+ bool bVMirr = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+
+ // calculate output sizes
+ if( !pBmpEx )
{
- Polygon aPoly( Rectangle( Point(), aUnrotatedSizeInPixels) );
- aPoly.Rotate( Point(), nRotation );
- Rectangle aNewBound( aPoly.GetBoundRect() );
-
- aCropRectangle = Rectangle (
- aCropRectangle.Left() + aNewBound.Left(),
- aCropRectangle.Top() + aNewBound.Top(),
- aCropRectangle.Right() + aNewBound.Left(),
- aCropRectangle.Bottom() + aNewBound.Top() );
- }
+ Point aPt;
+ Rectangle aOutRect( aPt, pOutputDevice->GetOutputSizePixel() );
+ Rectangle aBmpRect( aOutputPointPix, aOutputSizePix );
+
+ if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
+ {
+ const Region aPaintRgn( ( (Window*) pOutputDevice )->GetPaintRegion() );
+ if( !aPaintRgn.IsNull() )
+ aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ }
- // calculate scaling factors
- double fScaleX = aUnrotatedSizeInPixels.Width() / (double) rBitmapSizePixels.Width();
- double fScaleY = aUnrotatedSizeInPixels.Height() / (double) rBitmapSizePixels.Height();
+ aOutRect.Intersection( aBmpRect );
- if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
- {
- bRet = aBitmapEx.ScaleCropRotate( fScaleX, fScaleY, aCropRectangle, nRotation, COL_TRANSPARENT );
+ if( !aOutRect.IsEmpty() )
+ {
+ aOutPoint = pOutputDevice->PixelToLogic( aOutRect.TopLeft() );
+ aOutSize = pOutputDevice->PixelToLogic( aOutRect.GetSize() );
+ nStartX = aOutRect.Left() - aBmpRect.Left();
+ nStartY = aOutRect.Top() - aBmpRect.Top();
+ nEndX = aOutRect.Right() - aBmpRect.Left();
+ nEndY = aOutRect.Bottom() - aBmpRect.Top();
+ }
+ else
+ {
+ nStartX = -1L; // invalid
+ }
}
else
{
- aCropRectangle = Rectangle (
- aCropRectangle.Left() / fScaleX,
- aCropRectangle.Top() / fScaleY,
- aCropRectangle.Right() / fScaleX,
- aCropRectangle.Bottom() / fScaleY );
-
- bRet = aBitmapEx.Crop( aCropRectangle );
- if ( bRet )
- bRet = aBitmapEx.Scale( fScaleX, fScaleY );
+ aOutPoint = pOutputDevice->PixelToLogic( aOutputPointPix );
+ aOutSize = pOutputDevice->PixelToLogic( aOutputSizePix );
+ nStartX = nStartY = 0;
+ nEndX = aOutputSizePix.Width() - 1L;
+ nEndY = aOutputSizePix.Height() - 1L;
}
- }
- if( bRet )
- {
- // attribute adjustment if neccessary
- if( rAttributes.IsSpecialDrawMode()
- || rAttributes.IsAdjusted()
- || rAttributes.IsTransparent() )
+ // do transformation
+ if( nStartX >= 0L )
{
- ImplAdjust( aBitmapEx, rAttributes, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
- }
+ const bool bSimple = ( 1 == nW || 1 == nH );
- // OutDev adjustment if neccessary
- if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER
- && pOutputDevice->GetBitCount() <= 8
- && aBitmapEx.GetBitCount() >= 8 )
- {
- aBitmapEx.Dither( BMP_DITHER_MATRIX );
+ if( nRot10 )
+ {
+ if( bSimple )
+ {
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( aUnrotatedSizePix );
+
+ if( bRet )
+ aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ }
+ else
+ {
+ bRet = ImplCreateRotatedScaled( aBmpEx, rAttributes,
+ nRot10, aUnrotatedSizePix,
+ nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+ else
+ {
+ if( !bHMirr && !bVMirr && aOutputSizePix == rBmpSzPix )
+ {
+ aOutPoint = pOutputDevice->PixelToLogic( aOutputPointPix );
+ aOutSize = pOutputDevice->PixelToLogic( aOutputSizePix );
+ aOutBmpEx = aBmpEx;
+ bRet = true;
+ }
+ else
+ {
+ if( bSimple )
+ {
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
+ }
+ else
+ {
+ bRet = ImplCreateRotatedScaled( aBmpEx, rAttributes,
+ nRot10, aUnrotatedSizePix,
+ nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+ }
+
+ if( bRet )
+ {
+ // Attribute adjustment if neccessary
+ if( rAttributes.IsSpecialDrawMode() || rAttributes.IsAdjusted() || rAttributes.IsTransparent() )
+ ImplAdjust( aOutBmpEx, rAttributes, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+
+ // OutDev adjustment if neccessary
+ if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER && pOutputDevice->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
+ aOutBmpEx.Dither( BMP_DITHER_MATRIX );
+ }
}
- }
- // create output
- if( bRet )
- {
- if( pResultBitmapEx )
+ // Create output
+ if( bRet )
{
- if( !rAttributes.IsTransparent() && !aBitmapEx.IsAlpha() )
- aBitmapEx = BitmapEx( aBitmapEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aBitmapEx.GetMask() );
+ if( !pBmpEx )
+ pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aOutBmpEx );
+ else
+ {
+ if( !rAttributes.IsTransparent() && !aOutBmpEx.IsAlpha() )
+ aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aOutBmpEx.GetMask() );
- *pResultBitmapEx = aBitmapEx;
+ pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, *pBmpEx = aOutBmpEx );
+ }
}
- pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aBitmapEx);
}
return bRet;
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index e1e489f06faf..b73f2075a959 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -415,12 +415,12 @@ public:
double* pBlurVector, double*& pWeights, int*& pPixels, int*& pCount );
public:
- Bitmap();
- Bitmap( const Bitmap& rBitmap );
- Bitmap( const Size& rSizePixel, sal_uInt16 nBitCount, const BitmapPalette* pPal = NULL );
- Bitmap( const ResId& rResId );
- Bitmap( SalBitmap* pSalBitmap );
- ~Bitmap();
+ Bitmap();
+ Bitmap( const Bitmap& rBitmap );
+ Bitmap( const Size& rSizePixel, sal_uInt16 nBitCount, const BitmapPalette* pPal = NULL );
+ Bitmap( const ResId& rResId );
+ Bitmap( SalBitmap* pSalBitmap );
+ ~Bitmap();
Bitmap& operator=( const Bitmap& rBitmap );
inline sal_Bool operator!() const;
@@ -448,7 +448,6 @@ public:
*/
void SetSourceSizePixel( const Size& );
-
sal_uInt16 GetBitCount() const;
inline sal_uLong GetColorCount() const;
inline sal_uLong GetSizeBytes() const;
@@ -650,11 +649,6 @@ public:
*/
sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
- /** Scale, crop and rotate the bitmap */
- sal_Bool ScaleCropRotate(
- const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
- const Color& rFillColor, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
-
/** Rotate bitmap by the specified angle
@param nAngle10
diff --git a/vcl/inc/vcl/bitmapex.hxx b/vcl/inc/vcl/bitmapex.hxx
index 437c70a794a8..2c29d68eeb07 100644
--- a/vcl/inc/vcl/bitmapex.hxx
+++ b/vcl/inc/vcl/bitmapex.hxx
@@ -268,11 +268,6 @@ public:
*/
sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
- /** Scale, crop and rotate the bitmap */
- sal_Bool ScaleCropRotate(
- const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
- const Color& rFillColor, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
-
/** Rotate bitmap by the specified angle
@param nAngle10
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index a4900c6df6f2..13b6d13ff55c 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -2313,237 +2313,4 @@ bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapR
return true;
}
-sal_Bool Bitmap::ScaleCropRotate(
- const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
- const Color& rFillColor, sal_uLong /* nScaleFlag */ )
-{
- bool bRet;
-
- if ( rScaleX < 0.6 || rScaleY < 0.6 )
- {
- bRet = ImplTransformAveraging( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
- }
- else
- {
- bRet = ImplTransformBilinearFiltering( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
- }
-
- return bRet;
-}
-
-// Scaling algorithm best for shrinking below factor 0.5 where algorithms with limited sampling range show bad results (bilinear, bicubic).
-// The algoritm determines the sampling range for one pixel and calculates the average of samples which is the resulting pixel.
-bool Bitmap::ImplTransformAveraging( const double& rScaleX, const double& rScaleY, const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor )
-{
- const Size aSizePix( GetSizePixel() );
-
- const int nStartX = rRotatedRectangle.Left();
- const int nStartY = rRotatedRectangle.Top();
- const int nEndX = rRotatedRectangle.Right();
- const int nEndY = rRotatedRectangle.Bottom();
-
- const int nTargetWidth = rRotatedRectangle.GetWidth();
- const int nTargetHeight = rRotatedRectangle.GetHeight();
-
- const int nOriginWidth = aSizePix.Width();
- const int nOriginHeight = aSizePix.Height();
-
- const int nScaledWidth = FRound( nOriginWidth * rScaleX );
- const int nScaledHeight = FRound( nOriginHeight * rScaleY );
-
- const double aReverseScaleX = 1.0 / rScaleX;
- const double aReverseScaleY = 1.0 / rScaleY;
-
- const double fCosAngle = cos( nAngle10 * F_PI1800 );
- const double fSinAngle = sin( nAngle10 * F_PI1800 );
-
- if( nTargetWidth <= 1L || nTargetHeight <= 1L )
- return false;
-
- BitmapColor aColor, aResultColor;
-
- Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
-
- BitmapReadAccess* pReadAccess = AcquireReadAccess();
- BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
-
- if( !pReadAccess || !pWriteAccess )
- return false;
-
- const BitmapColor aFillColor( pWriteAccess->GetBestMatchingColor( rFillColor ) );
-
- int x, y, xOut, yOut;
- int aCount;
- double aSumRed, aSumGreen, aSumBlue;
-
- for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
- {
- for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
- {
- double unrotatedX = fCosAngle * x - fSinAngle * y;
- double unrotatedY = fSinAngle * x + fCosAngle * y;
-
- if ( unrotatedX < 0
- || unrotatedX > nScaledWidth
- || unrotatedY < 0
- || unrotatedY > nScaledHeight)
- {
- pWriteAccess->SetPixel( yOut, xOut, aFillColor );
- }
- else
- {
- double dYStart = ((unrotatedY + 0.5) * aReverseScaleY) - 0.5;
- double dYEnd = ((unrotatedY + 1.5) * aReverseScaleY) - 0.5;
-
- int yStart = MinMax( dYStart, 0, nOriginHeight - 1);
- int yEnd = MinMax( dYEnd, 0, nOriginHeight - 1);
-
- double dXStart = ((unrotatedX + 0.5) * aReverseScaleX) - 0.5;
- double dXEnd = ((unrotatedX + 1.5) * aReverseScaleX) - 0.5;
-
- int xStart = MinMax( dXStart, 0, nOriginWidth - 1);
- int xEnd = MinMax( dXEnd, 0, nOriginWidth - 1);
-
- aSumRed = aSumGreen = aSumBlue = 0.0;
- aCount = 0;
-
- for (int yIn = yStart; yIn <= yEnd; yIn++)
- {
- for (int xIn = xStart; xIn <= xEnd; xIn++)
- {
- aColor = pReadAccess->GetPixel( yIn, xIn );
-
- if( pReadAccess->HasPalette() )
- aColor = pReadAccess->GetPaletteColor( aColor );
-
- aSumRed += aColor.GetRed();
- aSumGreen += aColor.GetGreen();
- aSumBlue += aColor.GetBlue();
-
- aCount++;
- }
- }
-
- aResultColor.SetRed( MinMax( aSumRed / aCount, 0, 255) );
- aResultColor.SetGreen( MinMax( aSumGreen / aCount, 0, 255) );
- aResultColor.SetBlue( MinMax( aSumBlue / aCount, 0, 255) );
-
- pWriteAccess->SetPixel( yOut, xOut, aResultColor );
- }
- }
- }
-
- ReleaseAccess( pReadAccess );
- aOutBmp.ReleaseAccess( pWriteAccess );
- ImplAssignWithSize( aOutBmp );
-
- return true;
-}
-
-// Bilinear filtering used for shrinking and enlarging the source bitmap. Filtering is also used for rotation.
-// Filtering shows bad results at shrinking for a factor less than 0.5 because of limited sampling.
-bool Bitmap::ImplTransformBilinearFiltering( const double& rScaleX, const double& rScaleY, const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor )
-{
- const int nOriginWidth = GetSizePixel().Width();
- const int nOriginHeight = GetSizePixel().Height();
-
- const int nScaledWidth = FRound( nOriginWidth * rScaleX );
- const int nScaledHeight = FRound( nOriginHeight * rScaleY );
-
- const int nTargetWidth = rRotatedRectangle.GetWidth();
- const int nTargetHeight = rRotatedRectangle.GetHeight();
-
- const int nStartX = rRotatedRectangle.Left();
- const int nEndX = rRotatedRectangle.Right();
- const int nStartY = rRotatedRectangle.Top();
- const int nEndY = rRotatedRectangle.Bottom();
-
- const double fCosAngle = cos( nAngle10 * F_PI1800 );
- const double fSinAngle = sin( nAngle10 * F_PI1800 );
-
- Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
-
- BitmapReadAccess* pReadAccess = AcquireReadAccess();
- BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
-
- if( !pReadAccess || !pWriteAccess )
- return false;
-
- const BitmapColor aFillColor( pWriteAccess->GetBestMatchingColor( rFillColor ) );
-
- double aReverseScaleX = 1.0 / rScaleX;
- double aReverseScaleY = 1.0 / rScaleY;
-
- BitmapColor aColor00, aColor01, aColor10, aColor11, aResultColor;
-
- int x, y, xOut, yOut;
-
- for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
- {
- for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
- {
- double unrotatedX = fCosAngle * x - fSinAngle * y;
- double unrotatedY = fSinAngle * x + fCosAngle * y;
-
- if ( unrotatedX < 0
- || unrotatedX >= nScaledWidth
- || unrotatedY < 0
- || unrotatedY >= nScaledHeight)
- {
- pWriteAccess->SetPixel( yOut, xOut, aFillColor );
- }
- else
- {
- double sy0 = ((unrotatedY + 0.5) * aReverseScaleY) - 0.5;
-
- int y0 = MinMax( floor( sy0 ), 0, nOriginHeight - 1);
- int y1 = MinMax( y0 + 1, 0, nOriginHeight - 1);
-
- double sx0 = ((unrotatedX + 0.5) * aReverseScaleX) - 0.5;
- int x0 = MinMax( floor( sx0 ), 0, nOriginWidth - 1);
- int x1 = MinMax( x0 + 1, 0, nOriginWidth - 1);
-
- aColor00 = pReadAccess->GetPixel( y0, x0 );
- aColor01 = pReadAccess->GetPixel( y1, x0 );
- aColor10 = pReadAccess->GetPixel( y0, x1 );
- aColor11 = pReadAccess->GetPixel( y1, x1 );
-
- if( pReadAccess->HasPalette() )
- {
- aColor00 = pReadAccess->GetPaletteColor( aColor00 );
- aColor01 = pReadAccess->GetPaletteColor( aColor01 );
- aColor10 = pReadAccess->GetPaletteColor( aColor10 );
- aColor11 = pReadAccess->GetPaletteColor( aColor11 );
- }
-
- double fx0 = sx0 - x0;
- double fy0 = sy0 - y0;
- double fx1 = 1.0 - fx0;
- double fy1 = 1.0 - fy0;
-
- double w00 = fx1 * fy1;
- double w01 = fx1 * fy0;
- double w10 = fx0 * fy1;
- double w11 = fx0 * fy0;
-
- double red = aColor00.GetRed() * w00 + aColor10.GetRed() * w10 + aColor01.GetRed() * w01 + aColor11.GetRed() * w11;
- double green = aColor00.GetGreen() * w00 + aColor10.GetGreen() * w10 + aColor01.GetGreen() * w01 + aColor11.GetGreen() * w11;
- double blue = aColor00.GetBlue() * w00 + aColor10.GetBlue() * w10 + aColor01.GetBlue() * w01 + aColor11.GetBlue() * w11;
-
- aResultColor.SetRed( MinMax(red, 0, 255) );
- aResultColor.SetGreen( MinMax(green, 0, 255) );
- aResultColor.SetBlue( MinMax(blue, 0, 255) );
-
- pWriteAccess->SetPixel( yOut, xOut, aResultColor );
- }
- }
- }
-
- ReleaseAccess( pReadAccess );
- aOutBmp.ReleaseAccess( pWriteAccess );
- ImplAssignWithSize( aOutBmp );
-
- return true;
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index 5851b743dcfa..06eec646a000 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -389,62 +389,6 @@ sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
return bRet;
}
-sal_Bool BitmapEx::ScaleCropRotate(
- const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel,
- long nAngle10, const Color& rFillColor, sal_uLong nScaleFlag )
-{
- bool bReturn = false;
-
- if( !!aBitmap )
- {
- // If fill color is transpatent
- const bool bTransparentRotation = Color( COL_TRANSPARENT ) == rFillColor;
-
- // If angle is 0, 90, 180 or 270 degreees, then we don't need to create an alpha bitmap.
- const bool bRightAngleRotation = (nAngle10 == 0 || nAngle10 == 900 || nAngle10 == 1800 || nAngle10 == 2700);
-
- if( !bRightAngleRotation && bTransparentRotation )
- {
- if( eTransparent == TRANSPARENT_COLOR )
- {
- bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, aTransparentColor, nScaleFlag );
- }
- else if( eTransparent == TRANSPARENT_NONE )
- {
- bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
- if ( bReturn )
- {
- aMask = Bitmap( aBitmapSize, 1 );
- aMask.Erase( COL_BLACK );
- aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
- eTransparent = TRANSPARENT_BITMAP;
- }
- } else {
- bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
- if( bReturn && !!aMask )
- {
- aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
- aMask.Convert( BMP_CONVERSION_8BIT_GREYS );
- }
- }
- }
- else
- {
- bReturn = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor, nScaleFlag );
- if( eTransparent == TRANSPARENT_BITMAP && !!aMask )
- {
- bReturn = aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
- aMask.Convert( BMP_CONVERSION_8BIT_GREYS );
- }
- }
- }
-
- if ( bReturn )
- aBitmapSize = aBitmap.GetSizePixel();
-
- return bReturn;
-}
-
sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
{
sal_Bool bRet = sal_False;