[Libreoffice-commits] .: Branch 'distro/suse/suse-3.6' - svtools/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Jan 16 05:20:57 PST 2013


 svtools/source/graphic/grfmgr2.cxx |  317 ++++++++++++++-----------------------
 1 file changed, 123 insertions(+), 194 deletions(-)

New commits:
commit 4a34560c92c6bf9c9e3ab8c5740d3dc720d3be1a
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Mon Jun 25 21:07:06 2012 +0200

    n#797967 use only Bitmap scaling and fixes to scaling
    
    "grfmgr" uses its own scaling functions instead of the scaling
    functions available on Bitmap object. The step to use the Bitmap::Scale
    for most scenarios was already made, now the "grfmgr" functions are
    not used anymore.
    
    In addition this commit fixes croping the bitmap with large zoom
    levels.
    
    (cherry picked from commit 764525b39c78bfad1f6fc44a8517a565547f67cf)
    
    Conflicts:
    	svtools/source/graphic/grfmgr2.cxx
    
    Change-Id: Ib27029d2cdf4684146befc131e3c72656dfa407c

diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 6bf2bc5..681fab6 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -295,230 +295,159 @@ sal_Bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
     return bRet;
 }
 
-// -----------------------------------------------------------------------------
-
-sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
-                                       const Point& rPt, const Size& rSz,
-                                       const BitmapEx& rBmpEx, const GraphicAttr& rAttr,
+sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
+                                       const Point& rPoint, const Size& rSize,
+                                       const BitmapEx& rBitmapEx, const GraphicAttr& rAttr,
                                        const sal_uLong nFlags, BitmapEx* pBmpEx )
 {
-    sal_uInt16  nRot10 = rAttr.GetRotation() % 3600;
-    Point   aOutPtPix;
-    Size    aOutSzPix;
-    Size    aUnrotatedSzPix( pOut->LogicToPixel( rSz ) );
-    sal_Bool    bRet = sal_False;
+    bool        bRet = false;
+    Point       aOutPointInPixels;
+    Size        aOutSizeInPixels;
+    int         nRotation = rAttr.GetRotation() % 3600;
+    Size        aUnrotatedSizeInPixels( pOutputDevice->LogicToPixel( rSize ) );
 
-    if( nRot10 )
-    {
-        Polygon aPoly( Rectangle( rPt, rSz ) );
+    BitmapEx    aBitmapEx( rBitmapEx );
 
-        aPoly.Rotate( rPt, nRot10 );
-        const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
-        aOutPtPix = pOut->LogicToPixel( aRotBoundRect.TopLeft() );
-        aOutSzPix = pOut->LogicToPixel( aRotBoundRect.GetSize() );
+    if( !aUnrotatedSizeInPixels.Width() || !aUnrotatedSizeInPixels.Height() )
+        return false;
+
+    if( nRotation )
+    {
+        Polygon aRotationPolygon( Rectangle( rPoint, rSize ) );
+        aRotationPolygon.Rotate( rPoint, nRotation );
+        const Rectangle aRotationBoundRectangle( aRotationPolygon.GetBoundRect() );
+        aOutPointInPixels = pOutputDevice->LogicToPixel( aRotationBoundRectangle.TopLeft() );
+        aOutSizeInPixels = pOutputDevice->LogicToPixel( aRotationBoundRectangle.GetSize() );
+
+        // rotate the image before further processing
+        aBitmapEx.Rotate( nRotation, COL_TRANSPARENT );
     }
     else
     {
-        aOutPtPix = pOut->LogicToPixel( rPt );
-        aOutSzPix = aUnrotatedSzPix;
+        aOutPointInPixels = pOutputDevice->LogicToPixel( rPoint );
+        aOutSizeInPixels = aUnrotatedSizeInPixels;
     }
 
-    if( aUnrotatedSzPix.Width() && aUnrotatedSzPix.Height() )
+    Point           aOutPoint;
+    Size            aOutSize;
+    const Size&     rBitmapSizePixels = rBitmapEx.GetSizePixel();
+    long            nStartX, nStartY, nEndX, nEndY;
+    bool            isHorizontalMirrored = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+    bool            isVerticalMirrored   = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+
+    Rectangle   aBmpRect( aOutPointInPixels, aOutSizeInPixels );
+
+    // calculate output sizes
+    if( !pBmpEx )
     {
-        BitmapEx        aBmpEx( rBmpEx );
-        BitmapEx        aOutBmpEx;
-        Point           aOutPt;
-        Size            aOutSz;
-        const Size&     rBmpSzPix = rBmpEx.GetSizePixel();
-        const long      nW = rBmpSzPix.Width();
-        const long      nH = rBmpSzPix.Height();
-        const long      nNewW = aUnrotatedSzPix.Width();
-        const long      nNewH = aUnrotatedSzPix.Height();
-        double          fTmp;
-        long*           pMapIX = new long[ nNewW ];
-        long*           pMapFX = new long[ nNewW ];
-        long*           pMapIY = new long[ nNewH ];
-        long*           pMapFY = new long[ nNewH ];
-        long            nStartX = -1, nStartY = -1, nEndX = -1, nEndY = -1;
-        long            nX, nY, nTmp, nTmpX, nTmpY;
-        sal_Bool            bHMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
-        sal_Bool            bVMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+        Point       aPoint;
+        Rectangle   aOutRect( aPoint, pOutputDevice->GetOutputSizePixel() );
 
-        if( !( nFlags & GRFMGR_DRAW_SMOOTHSCALE ))
+        if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
         {
-            // #98290# Use a different mapping for non-interpolating mode, to avoid missing rows/columns
-            const double    fRevScaleX = ( nNewW > 1L ) ? ( (double) nW / nNewW ) : 0.0;
-            const double    fRevScaleY = ( nNewH > 1L ) ? ( (double) nH / nNewH ) : 0.0;
-
-            // create horizontal mapping table
-            for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
+            const Region aPaintRgn( ( (Window*) pOutputDevice )->GetPaintRegion() );
+            if( !aPaintRgn.IsNull() )
             {
-                fTmp = nX * fRevScaleX;
-
-                if( bHMirr )
-                    fTmp = nTmpX - fTmp;
-
-                // #98290# Do not use round to zero, otherwise last column will be missing
-                pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp );
-                pMapFX[ nX ] = fTmp >= nTmp+1 ? 1048576 : 0;
-            }
-
-            // create vertical mapping table
-            for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
-            {
-                fTmp = nY * fRevScaleY;
-
-                if( bVMirr )
-                    fTmp = nTmpY - fTmp;
-
-                // #98290# Do not use round to zero, otherwise last row will be missing
-                pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp );
-                pMapFY[ nY ] = fTmp >= nTmp+1 ? 1048576 : 0;
+                aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRgn.GetBoundRect() ) );
             }
         }
+        aOutRect.Intersection( aBmpRect );
 
-        // calculate output sizes
-        if( !pBmpEx )
+        if( !aOutRect.IsEmpty() )
         {
-            Point       aPt;
-            Rectangle   aOutRect( aPt, pOut->GetOutputSizePixel() );
-            Rectangle   aBmpRect( aOutPtPix, aOutSzPix );
+            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
+    {
+        aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
+        aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
+        nStartX = nStartY = 0;
+        nEndX = aOutSizeInPixels.Width() - 1L;
+        nEndY = aOutSizeInPixels.Height() - 1L;
+    }
 
-            if( pOut->GetOutDevType() == OUTDEV_WINDOW )
-            {
-                const Region aPaintRgn( ( (Window*) pOut )->GetPaintRegion() );
-                if( !aPaintRgn.IsNull() )
-                    aOutRect.Intersection( pOut->LogicToPixel( aPaintRgn.GetBoundRect() ) );
-            }
 
-            aOutRect.Intersection( aBmpRect );
+    if( nStartX < 0L )
+        return false;
 
-            if( !aOutRect.IsEmpty() )
-            {
-                aOutPt = pOut->PixelToLogic( aOutRect.TopLeft() );
-                aOutSz = pOut->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
-        {
-            aOutPt = pOut->PixelToLogic( aOutPtPix );
-            aOutSz = pOut->PixelToLogic( aOutSzPix );
-            nStartX = nStartY = 0;
-            nEndX = aOutSzPix.Width() - 1L;
-            nEndY = aOutSzPix.Height() - 1L;
-        }
+    // do transformation
 
-        // do transformation
-        if( nStartX >= 0L )
-        {
-            const sal_Bool bSimple = ( 1 == nW || 1 == nH );
+    // #105229# Don't scale if output size equals bitmap size
+    // #107226# Copy through only if we're not mirroring
+    if( !isHorizontalMirrored &&
+        !isVerticalMirrored &&
+        aOutSizeInPixels == rBitmapSizePixels &&
+        !nRotation)
+    {
+        // #107226# Use original dimensions when just copying through
+        aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
+        aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
+        bRet = true;
+    }
+    else
+    {
+        // calculate scaling factors
+        double fScaleX = aBmpRect.GetWidth()  / (double) aBitmapEx.GetSizePixel().Width();
+        double fScaleY = aBmpRect.GetHeight() / (double) aBitmapEx.GetSizePixel().Height();
 
-            if( nRot10 )
-            {
-                if( bSimple )
-                {
-                    bRet = ( aOutBmpEx = aBmpEx ).Scale( aUnrotatedSzPix );
+        // calculate crop regions on original non-scaled bitmap
+        long nOriginalStartX = nStartX / fScaleX;
+        long nOriginalEndX = nEndX / fScaleX;
+        long nOriginalStartY = nStartY / fScaleY;
+        long nOriginalEndY = nEndY / fScaleY;
 
-                    if( bRet )
-                        bRet = aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
-                }
-                else if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
-                {
-                    // Scale using the Box filter, rather than this algorithm, as that one provides
-                    // better quality, while being somewhat slower (the result should be cached though).
-                    aOutBmpEx = aBmpEx;
-                    bRet = true;
-                    if( bHMirr || bVMirr )
-                        bRet = aOutBmpEx.Mirror(( bHMirr ? BMP_MIRROR_HORZ : BMP_MIRROR_NONE )
-                                    | ( bVMirr ? BMP_MIRROR_VERT : BMP_MIRROR_NONE ));
-                    if( bRet )
-                        bRet = aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
-                    if( bRet ) // scale as last (rotating would destroy the smooth scaling)
-                        bRet = aOutBmpEx.Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ),
-                            BMP_SCALE_BOX );
-                }
-                else
-                {
-                    bRet = ImplCreateRotatedScaled( aBmpEx,
-                                                    nRot10, aOutSzPix, aUnrotatedSzPix,
-                                                    pMapIX, pMapFX, pMapIY, pMapFY, nStartX, nEndX, nStartY, nEndY,
-                                                    aOutBmpEx );
-                }
-            }
-            else
-            {
-                // #105229# Don't scale if output size equals bitmap size
-                // #107226# Copy through only if we're not mirroring
-                if( !bHMirr && !bVMirr && aOutSzPix == rBmpSzPix )
-                {
-                    // #107226# Use original dimensions when just copying through
-                    aOutPt = pOut->PixelToLogic( aOutPtPix );
-                    aOutSz = pOut->PixelToLogic( aOutSzPix );
-                    aOutBmpEx = aBmpEx;
-                    bRet = sal_True;
-                }
-                else
-                {
-                    if( bSimple )
-                        bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
-                    else if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
-                    {
-                    // Scale using the Box filter, rather than this algorithm, as that one provides
-                    // better quality, while being somewhat slower (the result should be cached though).
-                        aOutBmpEx = aBmpEx;
-                        bRet = aOutBmpEx.Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ),
-                            BMP_SCALE_BOX );
-                        if( bRet && ( bHMirr || bVMirr ))
-                            bRet = aOutBmpEx.Mirror(( bHMirr ? BMP_MIRROR_HORZ : BMP_MIRROR_NONE )
-                                    | ( bVMirr ? BMP_MIRROR_VERT : BMP_MIRROR_NONE ));
-                    }
-                    else
-                    {
-                        bRet = ImplCreateScaled( aBmpEx,
-                                                 pMapIX, pMapFX, pMapIY, pMapFY,
-                                                 nStartX, nEndX, nStartY, nEndY,
-                                                 aOutBmpEx );
-                    }
-                }
-            }
+        Size aScaleSize( nEndX - nStartX + 1, nEndY - nStartY + 1 );
 
-            if( bRet )
-            {
-                // attribute adjustment if neccessary
-                if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
-                    ImplAdjust( aOutBmpEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+        // crop the bitmap, so we deal with a smaller bitmap
+        // todo: join crop and scale step into one step on Bitmap to decrease processing
+        bRet = aBitmapEx.Crop( Rectangle( nOriginalStartX, nOriginalStartY, nOriginalEndX, nOriginalEndY ) );
 
-                // OutDev adjustment if neccessary
-                if( pOut->GetOutDevType() != OUTDEV_PRINTER && pOut->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
-                    aOutBmpEx.Dither( BMP_DITHER_MATRIX );
-            }
-        }
+        // mirror the image - this should not impact the picture dimenstions
+        if( isHorizontalMirrored || isVerticalMirrored )
+            bRet = aBitmapEx.Mirror( rAttr.GetMirrorFlags() );
+
+        // depending on the flags, scale the image to the desired proportions
+        // use FAST scale if no smooth scale is desired
+        if( !( nFlags & GRFMGR_DRAW_SMOOTHSCALE ))
+            bRet = aBitmapEx.Scale( aScaleSize, BMP_SCALE_FAST );
+        else
+            bRet = aBitmapEx.Scale( aScaleSize );
+    }
 
-        // delete lookup tables
-        delete[] pMapIX;
-        delete[] pMapFX;
-        delete[] pMapIY;
-        delete[] pMapFY;
+    if( bRet )
+    {
+        // attribute adjustment if neccessary
+        if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
+            ImplAdjust( aBitmapEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+
+        // OutDev adjustment if neccessary
+        if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER &&
+                pOutputDevice->GetBitCount() <= 8 &&
+                aBitmapEx.GetBitCount() >= 8 )
+        {
+            aBitmapEx.Dither( BMP_DITHER_MATRIX );
+        }
+    }
 
-        // create output
-        if( bRet )
+    // create output
+    if( bRet )
+    {
+        if( pBmpEx )
         {
-            if( !pBmpEx )
-                pOut->DrawBitmapEx( aOutPt, aOutSz, aOutBmpEx );
-            else
-            {
-                if( !rAttr.IsTransparent() && !aOutBmpEx.IsAlpha() )
-                    aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOut ), aOutBmpEx.GetMask() );
+            if( !rAttr.IsTransparent() && !aBitmapEx.IsAlpha() )
+                aBitmapEx = BitmapEx( aBitmapEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aBitmapEx.GetMask() );
 
-                pOut->DrawBitmapEx( aOutPt, aOutSz, *pBmpEx = aOutBmpEx );
-            }
+            *pBmpEx = aBitmapEx;
         }
+        pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aBitmapEx);
     }
 
     return bRet;


More information about the Libreoffice-commits mailing list