svtools/source/graphic/grfmgr2.cxx |  726 ++++++++++++++++++++++++++++++-------
 vcl/inc/vcl/bitmap.hxx             |   18 
 vcl/inc/vcl/bitmapex.hxx           |    5 
 vcl/source/gdi/bitmap3.cxx         |  233 -----------
 vcl/source/gdi/bitmapex.cxx        |   56 --
 5 files changed, 613 insertions(+), 425 deletions(-)

New commits:
commit 4b161067d46ddd48b4602ccdcc4d1b2545e2ac83
Author: Tomaž Vajngerl <qui...@gmail.com>
Date:   Sun Sep 2 17:23:03 2012 +0200

    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

diff --git a/svtools/source/graphic/grfmgr2.cxx 
b/svtools/source/graphic/grfmgr2.cxx
index 2cc7ae3..299f883 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 e1e489f..b73f207 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 437c70a..2c29d68 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 a4900c6..13b6d13 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 5851b74..06eec64 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;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to