LCOV - code coverage report
Current view: top level - svtools/source/graphic - grfmgr2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 128 580 22.1 %
Date: 2012-08-25 Functions: 14 28 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 118 1174 10.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <vcl/bmpacc.hxx>
      31                 :            : #include <tools/poly.hxx>
      32                 :            : #include <vcl/outdev.hxx>
      33                 :            : #include <vcl/window.hxx>
      34                 :            : #include <vcl/gdimtf.hxx>
      35                 :            : #include <vcl/metaact.hxx>
      36                 :            : #include <vcl/metric.hxx>
      37                 :            : #include <vcl/animate.hxx>
      38                 :            : #include <vcl/alpha.hxx>
      39                 :            : #include <vcl/virdev.hxx>
      40                 :            : #include "grfcache.hxx"
      41                 :            : #include <svtools/grfmgr.hxx>
      42                 :            : 
      43                 :            : // -----------
      44                 :            : // - defines -
      45                 :            : // -----------
      46                 :            : 
      47                 :            : #define WATERMARK_LUM_OFFSET        50
      48                 :            : #define WATERMARK_CON_OFFSET        -70
      49                 :            : 
      50                 :            : // ------------------
      51                 :            : // - GraphicManager -
      52                 :            : // ------------------
      53                 :            : 
      54                 :        138 : GraphicManager::GraphicManager( sal_uLong nCacheSize, sal_uLong nMaxObjCacheSize ) :
      55 [ +  - ][ +  - ]:        138 :         mpCache( new GraphicCache( nCacheSize, nMaxObjCacheSize ) )
      56                 :            : {
      57                 :        138 : }
      58                 :            : 
      59                 :         51 : GraphicManager::~GraphicManager()
      60                 :            : {
      61         [ -  + ]:         51 :     for( size_t i = 0, n = maObjList.size(); i < n; ++i )
      62 [ #  # ][ #  # ]:          0 :         maObjList[ i ]->GraphicManagerDestroyed();
      63                 :            : 
      64 [ +  - ][ +  - ]:         51 :     delete mpCache;
      65                 :         51 : }
      66                 :            : 
      67                 :          0 : void GraphicManager::SetMaxCacheSize( sal_uLong nNewCacheSize )
      68                 :            : {
      69                 :          0 :     mpCache->SetMaxDisplayCacheSize( nNewCacheSize );
      70                 :          0 : }
      71                 :            : 
      72                 :          0 : void GraphicManager::SetMaxObjCacheSize( sal_uLong nNewMaxObjSize, sal_Bool bDestroyGreaterCached )
      73                 :            : {
      74                 :          0 :     mpCache->SetMaxObjDisplayCacheSize( nNewMaxObjSize, bDestroyGreaterCached );
      75                 :          0 : }
      76                 :            : 
      77                 :        138 : void GraphicManager::SetCacheTimeout( sal_uLong nTimeoutSeconds )
      78                 :            : {
      79                 :        138 :     mpCache->SetCacheTimeout( nTimeoutSeconds );
      80                 :        138 : }
      81                 :            : 
      82                 :         48 : void GraphicManager::ReleaseFromCache( const GraphicObject& /*rObj*/ )
      83                 :            : {
      84                 :            :     // !!!
      85                 :         48 : }
      86                 :            : 
      87                 :         30 : sal_Bool GraphicManager::IsInCache( OutputDevice* pOut, const Point& rPt,
      88                 :            :                                     const Size& rSz, const GraphicObject& rObj,
      89                 :            :                                     const GraphicAttr& rAttr ) const
      90                 :            : {
      91                 :         30 :     return mpCache->IsInDisplayCache( pOut, rPt, rSz, rObj, rAttr );
      92                 :            : }
      93                 :            : 
      94                 :      17560 : sal_Bool GraphicManager::DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
      95                 :            :                               GraphicObject& rObj, const GraphicAttr& rAttr,
      96                 :            :                               const sal_uLong nFlags, sal_Bool& rCached )
      97                 :            : {
      98                 :      17560 :     Point   aPt( rPt );
      99                 :      17560 :     Size    aSz( rSz );
     100                 :      17560 :     sal_Bool    bRet = sal_False;
     101                 :            : 
     102                 :      17560 :     rCached = sal_False;
     103                 :            : 
     104 [ -  + ][ #  # ]:      17560 :     if( ( rObj.GetType() == GRAPHIC_BITMAP ) || ( rObj.GetType() == GRAPHIC_GDIMETAFILE ) )
                 [ +  - ]
     105                 :            :     {
     106                 :            :         // create output and fill cache
     107                 :            : 
     108 [ +  - ][ +  - ]:      35145 :         if( rObj.IsAnimated() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ||
         [ +  - ][ +  - ]
           [ +  -  +  +  
           +  - ][ +  + ]
     109                 :      17560 :             ( !( nFlags & GRFMGR_DRAW_NO_SUBSTITUTE ) &&
     110                 :            :               ( ( nFlags & GRFMGR_DRAW_SUBSTITUTE ) ||
     111                 :      17560 :                 !( nFlags & GRFMGR_DRAW_CACHED ) ||
     112                 :      17585 :                 ( pOut->GetConnectMetaFile() && !pOut->IsOutputEnabled() ) ) ) )
     113                 :            :         {
     114                 :            :             // simple output of transformed graphic
     115         [ +  - ]:         25 :             const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
     116                 :            : 
     117 [ +  - ][ +  - ]:         25 :             if( aGraphic.IsSupportedGraphic() )
     118                 :            :             {
     119                 :         25 :                 const sal_uInt16 nRot10 = rAttr.GetRotation() % 3600;
     120                 :            : 
     121         [ -  + ]:         25 :                 if( nRot10 )
     122                 :            :                 {
     123 [ #  # ][ #  # ]:          0 :                     Polygon aPoly( Rectangle( aPt, aSz ) );
     124                 :            : 
     125         [ #  # ]:          0 :                     aPoly.Rotate( aPt, nRot10 );
     126         [ #  # ]:          0 :                     const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
     127                 :          0 :                     aPt = aRotBoundRect.TopLeft();
     128 [ #  # ][ #  # ]:          0 :                     aSz = aRotBoundRect.GetSize();
     129                 :            :                 }
     130                 :            : 
     131         [ +  - ]:         25 :                 aGraphic.Draw( pOut, aPt, aSz );
     132                 :            :             }
     133                 :            : 
     134         [ +  - ]:         25 :             bRet = sal_True;
     135                 :            :         }
     136                 :            : 
     137         [ +  + ]:      17560 :         if( !bRet )
     138                 :            :         {
     139                 :            :             // cached/direct drawing
     140 [ +  - ][ +  + ]:      17535 :             if( !mpCache->DrawDisplayCacheObj( pOut, aPt, aSz, rObj, rAttr ) )
     141         [ +  - ]:      17534 :                 bRet = ImplDraw( pOut, aPt, aSz, rObj, rAttr, nFlags, rCached );
     142                 :            :             else
     143                 :          1 :                 bRet = rCached = sal_True;
     144                 :            :         }
     145                 :            :     }
     146                 :            : 
     147                 :      17560 :     return bRet;
     148                 :            : }
     149                 :            : 
     150                 :      34781 : void GraphicManager::ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute,
     151                 :            :                                       const rtl::OString* pID, const GraphicObject* pCopyObj )
     152                 :            : {
     153         [ +  - ]:      34781 :     maObjList.push_back( (GraphicObject*)&rObj );
     154                 :      34781 :     mpCache->AddGraphicObject( rObj, rSubstitute, pID, pCopyObj );
     155                 :      34781 : }
     156                 :            : 
     157                 :      34530 : void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
     158                 :            : {
     159                 :      34530 :     mpCache->ReleaseGraphicObject( rObj );
     160 [ +  - ][ +  - ]:     232820 :     for( GraphicObjectList_impl::iterator it = maObjList.begin(); it != maObjList.end(); ++it )
                 [ +  - ]
     161                 :            :     {
     162 [ +  - ][ +  + ]:     232820 :         if ( *it == &rObj ) {
     163         [ +  - ]:      34530 :             maObjList.erase( it );
     164                 :      34530 :             break;
     165                 :            :         }
     166                 :            :     }
     167                 :      34530 : }
     168                 :            : 
     169                 :         27 : void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
     170                 :            : {
     171                 :         27 :     mpCache->GraphicObjectWasSwappedOut( rObj );
     172                 :         27 : }
     173                 :            : 
     174                 :       5521 : rtl::OString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
     175                 :            : {
     176                 :       5521 :     return mpCache->GetUniqueID( rObj );
     177                 :            : }
     178                 :            : 
     179                 :          8 : sal_Bool GraphicManager::ImplFillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
     180                 :            : {
     181                 :          8 :     return( mpCache->FillSwappedGraphicObject( rObj, rSubstitute ) );
     182                 :            : }
     183                 :            : 
     184                 :          6 : void GraphicManager::ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj )
     185                 :            : {
     186                 :          6 :     mpCache->GraphicObjectWasSwappedIn( rObj );
     187                 :          6 : }
     188                 :            : 
     189                 :      17534 : sal_Bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
     190                 :            :                                const Size& rSz, GraphicObject& rObj,
     191                 :            :                                const GraphicAttr& rAttr,
     192                 :            :                                const sal_uLong nFlags, sal_Bool& rCached )
     193                 :            : {
     194                 :      17534 :     const Graphic&  rGraphic = rObj.GetGraphic();
     195                 :      17534 :     sal_Bool            bRet = sal_False;
     196                 :            : 
     197 [ +  - ][ +  - ]:      17534 :     if( rGraphic.IsSupportedGraphic() && !rGraphic.IsSwapOut() )
                 [ +  - ]
     198                 :            :     {
     199         [ +  - ]:      17534 :         if( GRAPHIC_BITMAP == rGraphic.GetType() )
     200                 :            :         {
     201         [ +  - ]:      17534 :             const BitmapEx aSrcBmpEx( rGraphic.GetBitmapEx() );
     202                 :            : 
     203                 :            :             // #i46805# No point in caching a bitmap that is rendered
     204                 :            :             // via RectFill on the OutDev
     205 [ +  - ][ +  - ]:      35068 :             if( !(pOut->GetDrawMode() & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP )) &&
                 [ +  - ]
     206         [ +  - ]:      17534 :                 mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
     207                 :            :             {
     208         [ +  - ]:      17534 :                 BitmapEx aDstBmpEx;
     209                 :            : 
     210 [ +  - ][ +  - ]:      17534 :                 if( ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags, &aDstBmpEx ) )
     211                 :            :                 {
     212         [ +  - ]:      17534 :                     rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
     213                 :      17534 :                     bRet = sal_True;
     214         [ +  - ]:      17534 :                 }
     215                 :            :             }
     216                 :            : 
     217         [ -  + ]:      17534 :             if( !bRet )
     218 [ #  # ][ +  - ]:      17534 :                 bRet = ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags );
     219                 :            :         }
     220                 :            :         else
     221                 :            :         {
     222                 :          0 :             const GDIMetaFile& rSrcMtf = rGraphic.GetGDIMetaFile();
     223                 :            : 
     224         [ #  # ]:          0 :             if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
     225                 :            :             {
     226         [ #  # ]:          0 :                 GDIMetaFile aDstMtf;
     227         [ #  # ]:          0 :                 BitmapEx    aContainedBmpEx;
     228                 :            : 
     229 [ #  # ][ #  # ]:          0 :                 if( ImplCreateOutput( pOut, rPt, rSz, rSrcMtf, rAttr, nFlags, aDstMtf, aContainedBmpEx ) )
     230                 :            :                 {
     231         [ #  # ]:          0 :                     if( !!aContainedBmpEx )
     232                 :            :                     {
     233                 :            :                         // Use bitmap output method, if metafile basically contains only a single
     234                 :            :                         // bitmap (allows caching the resulting pixmap).
     235         [ #  # ]:          0 :                         BitmapEx aDstBmpEx;
     236                 :            : 
     237 [ #  # ][ #  # ]:          0 :                         if( ImplCreateOutput( pOut, rPt, rSz, aContainedBmpEx, rAttr, nFlags, &aDstBmpEx ) )
     238                 :            :                         {
     239         [ #  # ]:          0 :                             rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
     240                 :          0 :                             bRet = sal_True;
     241         [ #  # ]:          0 :                         }
     242                 :            :                     }
     243                 :            :                     else
     244                 :            :                     {
     245         [ #  # ]:          0 :                         rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstMtf );
     246                 :          0 :                         bRet = sal_True;
     247                 :            :                     }
     248 [ #  # ][ #  # ]:          0 :                 }
     249                 :            :             }
     250                 :            : 
     251         [ #  # ]:          0 :             if( !bRet )
     252                 :            :             {
     253         [ #  # ]:          0 :                 const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
     254                 :            : 
     255 [ #  # ][ #  # ]:          0 :                 if( aGraphic.IsSupportedGraphic() )
     256                 :            :                 {
     257         [ #  # ]:          0 :                     aGraphic.Draw( pOut, rPt, rSz );
     258                 :          0 :                     bRet = sal_True;
     259         [ #  # ]:          0 :                 }
     260                 :            :             }
     261                 :            :         }
     262                 :            :     }
     263                 :            : 
     264                 :      17534 :     return bRet;
     265                 :            : }
     266                 :            : 
     267                 :      17534 : sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
     268                 :            :                                        const Point& rPoint, const Size& rSize,
     269                 :            :                                        const BitmapEx& rBitmapEx, const GraphicAttr& rAttributes,
     270                 :            :                                        const sal_uLong nFlags, BitmapEx* pResultBitmapEx )
     271                 :            : {
     272                 :      17534 :     bool        bRet = false;
     273                 :            : 
     274         [ +  - ]:      17534 :     Point       aUnrotatedPointInPixels( pOutputDevice->LogicToPixel( rPoint ) );
     275         [ +  - ]:      17534 :     Size        aUnrotatedSizeInPixels(  pOutputDevice->LogicToPixel( rSize ) );
     276                 :            : 
     277 [ +  - ][ -  + ]:      17534 :     if( aUnrotatedSizeInPixels.Width() <= 0  || aUnrotatedSizeInPixels.Height() <= 0)
                 [ -  + ]
     278                 :          0 :         return false;
     279                 :            : 
     280                 :      17534 :     Point       aOutPointInPixels;
     281                 :      17534 :     Size        aOutSizeInPixels;
     282         [ +  - ]:      17534 :     BitmapEx    aBitmapEx( rBitmapEx );
     283                 :      17534 :     int         nRotation = rAttributes.GetRotation() % 3600;
     284                 :            : 
     285         [ -  + ]:      17534 :     if( nRotation != 0 )
     286                 :            :     {
     287 [ #  # ][ #  # ]:          0 :         Polygon aPoly( Rectangle( rPoint, rSize ) );
     288         [ #  # ]:          0 :         aPoly.Rotate( rPoint, nRotation );
     289         [ #  # ]:          0 :         const Rectangle aRotationBoundRect( aPoly.GetBoundRect() );
     290         [ #  # ]:          0 :         aOutPointInPixels = pOutputDevice->LogicToPixel( aRotationBoundRect.TopLeft() );
     291 [ #  # ][ #  # ]:          0 :         aOutSizeInPixels  = pOutputDevice->LogicToPixel( aRotationBoundRect.GetSize() );
                 [ #  # ]
     292                 :            :     }
     293                 :            :     else
     294                 :            :     {
     295                 :      17534 :         aOutPointInPixels = aUnrotatedPointInPixels;
     296                 :      17534 :         aOutSizeInPixels  = aUnrotatedSizeInPixels;
     297                 :            :     }
     298                 :            : 
     299                 :      17534 :     Point       aOutPoint;
     300                 :      17534 :     Size        aOutSize;
     301                 :            : 
     302                 :      17534 :     const Size& rBitmapSizePixels = rBitmapEx.GetSizePixel();
     303         [ +  - ]:      17534 :     Rectangle   aCropRectangle(0, 0, 0, 0);
     304                 :            : 
     305                 :      17534 :     bool        isHorizontalMirrored = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
     306                 :      17534 :     bool        isVerticalMirrored   = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
     307                 :            : 
     308                 :            :     // calculate output sizes
     309                 :            :     if( true || !pResultBitmapEx )
     310                 :            :     {
     311         [ +  - ]:      17534 :         Rectangle aBitmapRectangle( aOutPointInPixels, aOutSizeInPixels );
     312         [ +  - ]:      17534 :         Rectangle aOutRect( Point(), pOutputDevice->GetOutputSizePixel() );
     313                 :            : 
     314         [ -  + ]:      17534 :         if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
     315                 :            :         {
     316         [ #  # ]:          0 :             const Region aPaintRegion( ( (Window*) pOutputDevice )->GetPaintRegion() );
     317                 :            : 
     318 [ #  # ][ #  # ]:          0 :             if( !aPaintRegion.IsNull() )
     319 [ #  # ][ #  # ]:          0 :                 aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRegion.GetBoundRect() ) );
         [ #  # ][ #  # ]
     320                 :            :         }
     321         [ +  - ]:      17534 :         aOutRect.Intersection( aBitmapRectangle );
     322                 :            : 
     323 [ +  - ][ +  + ]:      17534 :         if( !aOutRect.IsEmpty() )
     324                 :            :         {
     325         [ +  - ]:      16562 :             aOutPoint = pOutputDevice->PixelToLogic( aOutRect.TopLeft() );
     326 [ +  - ][ +  - ]:      16562 :             aOutSize =  pOutputDevice->PixelToLogic( aOutRect.GetSize() );
     327                 :            : 
     328                 :            :             aCropRectangle = Rectangle(
     329                 :      16562 :                 aOutRect.Left()   - aBitmapRectangle.Left(),
     330                 :      16562 :                 aOutRect.Top()    - aBitmapRectangle.Top(),
     331                 :      16562 :                 aOutRect.Right()  - aBitmapRectangle.Left(),
     332         [ +  - ]:      33124 :                 aOutRect.Bottom() - aBitmapRectangle.Top() );
     333                 :            :         }
     334                 :            :     }
     335                 :            :     else
     336                 :            :     {
     337                 :            :         aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
     338                 :            :         aOutSize =  pOutputDevice->PixelToLogic( aOutSizeInPixels );
     339                 :            : 
     340                 :            :         aCropRectangle = Rectangle(
     341                 :            :             0, 0,
     342                 :            :             aOutSizeInPixels.Width()  - 1,
     343                 :            :             aOutSizeInPixels.Height() - 1 );
     344                 :            :     }
     345                 :            : 
     346                 :            : 
     347 [ +  - ][ -  + ]:      17534 :     if( aCropRectangle.GetWidth() <= 0 && aCropRectangle.GetHeight() <= 0 )
         [ #  # ][ #  # ]
                 [ -  + ]
     348                 :          0 :         return false;
     349                 :            : 
     350                 :            :     // do transformation
     351 [ +  - ][ +  - ]:      35068 :     if( !isHorizontalMirrored &&
           [ +  -  +  + ]
                 [ +  + ]
     352                 :      17534 :         !isVerticalMirrored &&
     353                 :            :         !nRotation &&
     354                 :      17534 :         aOutSizeInPixels == rBitmapSizePixels)
     355                 :            :     {
     356                 :            :         // simple copy thorugh
     357         [ +  - ]:       4327 :         aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
     358         [ +  - ]:       4327 :         aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
     359                 :       4327 :         bRet = true;
     360                 :            :     }
     361                 :            :     else
     362                 :            :     {
     363                 :            :         // mirror the image - this should not impact the picture dimenstions
     364 [ +  - ][ -  + ]:      13207 :         if( isHorizontalMirrored || isVerticalMirrored )
     365         [ #  # ]:          0 :             bRet = aBitmapEx.Mirror( rAttributes.GetMirrorFlags() );
     366                 :            : 
     367                 :            :         // prepare rotation if needed
     368         [ -  + ]:      13207 :         if (nRotation != 0)
     369                 :            :         {
     370 [ #  # ][ #  # ]:          0 :             Polygon aPoly( Rectangle( Point(), aUnrotatedSizeInPixels) );
     371         [ #  # ]:          0 :             aPoly.Rotate( Point(), nRotation );
     372         [ #  # ]:          0 :             Rectangle aNewBound( aPoly.GetBoundRect() );
     373                 :            : 
     374                 :            :             aCropRectangle = Rectangle (
     375                 :          0 :                                 aCropRectangle.Left()   + aNewBound.Left(),
     376                 :          0 :                                 aCropRectangle.Top()    + aNewBound.Top(),
     377                 :          0 :                                 aCropRectangle.Right()  + aNewBound.Left(),
     378 [ #  # ][ #  # ]:          0 :                                 aCropRectangle.Bottom() + aNewBound.Top() );
     379                 :            :         }
     380                 :            : 
     381                 :            :         // calculate scaling factors
     382                 :      13207 :         double fScaleX = aUnrotatedSizeInPixels.Width()  / (double) rBitmapSizePixels.Width();
     383                 :      13207 :         double fScaleY = aUnrotatedSizeInPixels.Height() / (double) rBitmapSizePixels.Height();
     384                 :            : 
     385         [ +  - ]:      13207 :         if( nFlags & GRFMGR_DRAW_SMOOTHSCALE )
     386                 :            :         {
     387         [ +  - ]:      13207 :             bRet = aBitmapEx.ScaleCropRotate( fScaleX, fScaleY, aCropRectangle, nRotation, COL_TRANSPARENT );
     388                 :            :         }
     389                 :            :         else
     390                 :            :         {
     391                 :            :             aCropRectangle = Rectangle (
     392                 :          0 :                                 aCropRectangle.Left()   / fScaleX,
     393                 :          0 :                                 aCropRectangle.Top()    / fScaleY,
     394                 :          0 :                                 aCropRectangle.Right()  / fScaleX,
     395         [ #  # ]:          0 :                                 aCropRectangle.Bottom() / fScaleY );
     396                 :            : 
     397         [ #  # ]:          0 :             bRet = aBitmapEx.Crop( aCropRectangle );
     398         [ #  # ]:          0 :             if ( bRet )
     399         [ #  # ]:      13207 :                 bRet = aBitmapEx.Scale( fScaleX, fScaleY );
     400                 :            :         }
     401                 :            :     }
     402                 :            : 
     403         [ +  - ]:      17534 :     if( bRet )
     404                 :            :     {
     405                 :            :         // attribute adjustment if neccessary
     406   [ +  -  +  -  :      52602 :         if(  rAttributes.IsSpecialDrawMode()
           -  + ][ -  + ]
     407                 :      17534 :           || rAttributes.IsAdjusted()
     408                 :      17534 :           || rAttributes.IsTransparent() )
     409                 :            :         {
     410         [ #  # ]:          0 :             ImplAdjust( aBitmapEx, rAttributes, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
     411                 :            :         }
     412                 :            : 
     413                 :            :         // OutDev adjustment if neccessary
     414 [ +  - ][ -  + ]:      35068 :         if(   pOutputDevice->GetOutDevType() != OUTDEV_PRINTER
         [ #  # ][ -  + ]
     415         [ +  - ]:      17534 :           &&  pOutputDevice->GetBitCount() <= 8
     416         [ #  # ]:          0 :           &&  aBitmapEx.GetBitCount() >= 8 )
     417                 :            :         {
     418         [ #  # ]:          0 :             aBitmapEx.Dither( BMP_DITHER_MATRIX );
     419                 :            :         }
     420                 :            :     }
     421                 :            : 
     422                 :            :     // create output
     423         [ +  - ]:      17534 :     if( bRet )
     424                 :            :     {
     425         [ +  - ]:      17534 :         if( pResultBitmapEx )
     426                 :            :         {
     427 [ +  - ][ +  - ]:      17534 :             if( !rAttributes.IsTransparent() && !aBitmapEx.IsAlpha() )
         [ +  + ][ +  + ]
     428 [ +  - ][ +  - ]:          6 :                 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aBitmapEx.GetMask() );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     429                 :            : 
     430         [ +  - ]:      17534 :             *pResultBitmapEx = aBitmapEx;
     431                 :            :         }
     432         [ +  - ]:      17534 :         pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aBitmapEx);
     433                 :            :     }
     434                 :            : 
     435         [ +  - ]:      17534 :     return bRet;
     436                 :            : }
     437                 :            : 
     438                 :            : // This function checks whether the bitmap is usable for skipping
     439                 :            : // mtf rendering by using just this one bitmap (i.e. in case the metafile
     440                 :            : // contains just this one pixmap that covers the entire metafile area).
     441                 :          0 : static BitmapEx checkMetadataBitmap( const BitmapEx& rBmpEx,
     442                 :            :                                      Point    rSrcPoint,
     443                 :            :                                      Size     rSrcSize,
     444                 :            :                                      const Point&    rDestPoint,
     445                 :            :                                      const Size&     rDestSize,
     446                 :            :                                      const Size&     rRefSize,
     447                 :            :                                      bool&           o_rbNonBitmapActionEncountered )
     448                 :            : {
     449                 :            : // NOTE: If you do changes in this function, change checkMetadataBitmap() in grfcache.cxx too.
     450                 :          0 :     BitmapEx aBmpEx;
     451         [ #  # ]:          0 :     if( rSrcSize == Size())
     452                 :          0 :         rSrcSize = rBmpEx.GetSizePixel();
     453                 :            : 
     454         [ #  # ]:          0 :     if( rDestPoint != Point( 0, 0 ))
     455                 :            :     {   // The pixmap in the metafile has an offset (and so would not cover)
     456                 :            :         // the entire result -> fall back to mtf rendering.
     457                 :          0 :         o_rbNonBitmapActionEncountered = true;
     458                 :          0 :         return aBmpEx;
     459                 :            :     }
     460         [ #  # ]:          0 :     if( rDestSize != rRefSize )
     461                 :            :     {   // The pixmap is not fullscale (does not cover the entire metafile area).
     462                 :            :         // HACK: The code here should refuse to use the bitmap directly
     463                 :            :         // and fall back to mtf rendering, but there seem to be metafiles
     464                 :            :         // that do not specify exactly their area (the Windows API requires apps
     465                 :            :         // the specify it manually, the rectangle is specified as topleft/bottomright
     466                 :            :         // rather than topleft/size [which may be confusing], and the docs
     467                 :            :         // on the exact meaning are somewhat confusing as well), so if it turns
     468                 :            :         // out this metafile really contains just one bitmap and no other painting,
     469                 :            :         // and if the sizes almost match, just use the pixmap (which will be scaled
     470                 :            :         // to fit exactly the requested size, so there should not be any actual problem
     471                 :            :         // caused by this small difference). This will allow caching of the resulting
     472                 :            :         // (scaled) pixmap, which can make a noticeable performance difference.
     473 [ #  # ][ #  #  :          0 :         if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
             #  #  #  # ]
                 [ #  # ]
     474                 :          0 :             && abs( rDestSize.Width() - rRefSize.Width()) < 5
     475                 :          0 :             && abs( rDestSize.Height() - rRefSize.Height()) < 5 )
     476                 :            :             ; // ok, assume it's close enough
     477                 :            :         else
     478                 :            :         {  // fall back to mtf rendering
     479                 :          0 :             o_rbNonBitmapActionEncountered = true;
     480                 :          0 :             return aBmpEx;
     481                 :            :         }
     482                 :            :     }
     483                 :            : 
     484         [ #  # ]:          0 :     aBmpEx = rBmpEx;
     485                 :            : 
     486         [ #  # ]:          0 :     if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
           [ #  #  #  # ]
                 [ #  # ]
     487                 :          0 :         rSrcSize != rBmpEx.GetSizePixel() )
     488                 :            :     {
     489                 :            :         // crop bitmap to given source rectangle (no
     490                 :            :         // need to copy and convert the whole bitmap)
     491                 :            :         const Rectangle aCropRect( rSrcPoint,
     492         [ #  # ]:          0 :                                    rSrcSize );
     493         [ #  # ]:          0 :         aBmpEx.Crop( aCropRect );
     494                 :            :     }
     495                 :            : 
     496                 :          0 :     return aBmpEx;
     497                 :            : }
     498                 :            : 
     499                 :          0 : sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
     500                 :            :                                        const Point& rPt, const Size& rSz,
     501                 :            :                                        const GDIMetaFile& rMtf, const GraphicAttr& rAttr,
     502                 :            :                                        const sal_uLong /*nFlags*/, GDIMetaFile& rOutMtf, BitmapEx& rOutBmpEx )
     503                 :            : {
     504                 :          0 :     const Size aNewSize( rMtf.GetPrefSize() );
     505                 :            : 
     506         [ #  # ]:          0 :     rOutMtf = rMtf;
     507                 :            : 
     508                 :            :     // Count bitmap actions, and flag actions that paint, but
     509                 :            :     // are no bitmaps.
     510                 :          0 :     sal_Int32   nNumBitmaps(0);
     511                 :          0 :     bool        bNonBitmapActionEncountered(false);
     512 [ #  # ][ #  # ]:          0 :     if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
         [ #  # ][ #  # ]
                 [ #  # ]
     513                 :            :     {
     514                 :          0 :         const double fGrfWH = (double) aNewSize.Width() / aNewSize.Height();
     515                 :          0 :         const double fOutWH = (double) rSz.Width() / rSz.Height();
     516                 :            : 
     517                 :          0 :         const double fScaleX = fOutWH / fGrfWH;
     518                 :          0 :         const double fScaleY = 1.0;
     519                 :            : 
     520         [ #  # ]:          0 :         const MapMode rPrefMapMode( rMtf.GetPrefMapMode() );
     521         [ #  # ]:          0 :         const Size rSizePix( pOut->LogicToPixel( aNewSize, rPrefMapMode ) );
     522                 :            : 
     523                 :            : // NOTE: If you do changes in this function, check GraphicDisplayCacheEntry::IsCacheableAsBitmap
     524                 :            : // in grfcache.cxx too.
     525                 :            : 
     526                 :            :         // Determine whether the metafile basically displays
     527                 :            :         // a single bitmap (in which case that bitmap is simply used directly
     528                 :            :         // instead of playing the metafile). Note that
     529                 :            :         // the solution, as implemented here, is quite suboptimal (the
     530                 :            :         // cases where a mtf consisting basically of a single bitmap,
     531                 :            :         // that fail to pass the test below, are probably frequent). A
     532                 :            :         // better solution would involve FSAA, but that's currently
     533                 :            :         // expensive, and might trigger bugs on display drivers, if
     534                 :            :         // VDevs get bigger than the actual screen.
     535                 :            :         sal_uInt32  nCurPos;
     536                 :            :         MetaAction* pAct;
     537 [ #  # ][ #  # ]:          0 :         for( nCurPos = 0, pAct = (MetaAction*)rOutMtf.FirstAction(); pAct;
                 [ #  # ]
     538                 :            :              pAct = (MetaAction*)rOutMtf.NextAction(), nCurPos++ )
     539                 :            :         {
     540                 :          0 :             MetaAction* pModAct = NULL;
     541   [ #  #  #  #  :          0 :             switch( pAct->GetType() )
          #  #  #  #  #  
                      # ]
     542                 :            :             {
     543                 :            :                 case META_FONT_ACTION:
     544                 :            :                 {
     545                 :            :                     // taking care of font width default if scaling metafile.
     546                 :          0 :                     MetaFontAction* pA = (MetaFontAction*)pAct;
     547         [ #  # ]:          0 :                     Font aFont( pA->GetFont() );
     548 [ #  # ][ #  # ]:          0 :                     if ( !aFont.GetWidth() )
     549                 :            :                     {
     550         [ #  # ]:          0 :                         FontMetric aFontMetric( pOut->GetFontMetric( aFont ) );
     551 [ #  # ][ #  # ]:          0 :                         aFont.SetWidth( aFontMetric.GetWidth() );
     552 [ #  # ][ #  # ]:          0 :                         pModAct = new MetaFontAction( aFont );
                 [ #  # ]
     553         [ #  # ]:          0 :                     }
     554                 :            :                 }
     555                 :            :                     // FALLTHROUGH intended
     556                 :            :                 case META_NULL_ACTION:
     557                 :            :                     // FALLTHROUGH intended
     558                 :            : 
     559                 :            :                     // OutDev state changes (which don't affect bitmap
     560                 :            :                     // output)
     561                 :            :                 case META_LINECOLOR_ACTION:
     562                 :            :                     // FALLTHROUGH intended
     563                 :            :                 case META_FILLCOLOR_ACTION:
     564                 :            :                     // FALLTHROUGH intended
     565                 :            :                 case META_TEXTCOLOR_ACTION:
     566                 :            :                     // FALLTHROUGH intended
     567                 :            :                 case META_TEXTFILLCOLOR_ACTION:
     568                 :            :                     // FALLTHROUGH intended
     569                 :            :                 case META_TEXTALIGN_ACTION:
     570                 :            :                     // FALLTHROUGH intended
     571                 :            :                 case META_TEXTLINECOLOR_ACTION:
     572                 :            :                     // FALLTHROUGH intended
     573                 :            :                 case META_TEXTLINE_ACTION:
     574                 :            :                     // FALLTHROUGH intended
     575                 :            :                 case META_PUSH_ACTION:
     576                 :            :                     // FALLTHROUGH intended
     577                 :            :                 case META_POP_ACTION:
     578                 :            :                     // FALLTHROUGH intended
     579                 :            :                 case META_LAYOUTMODE_ACTION:
     580                 :            :                     // FALLTHROUGH intended
     581                 :            :                 case META_TEXTLANGUAGE_ACTION:
     582                 :            :                     // FALLTHROUGH intended
     583                 :            :                 case META_COMMENT_ACTION:
     584                 :          0 :                     break;
     585                 :            : 
     586                 :            :                     // bitmap output methods
     587                 :            :                 case META_BMP_ACTION:
     588 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     589                 :            :                     {
     590                 :          0 :                         MetaBmpAction* pAction = (MetaBmpAction*)pAct;
     591                 :            : 
     592                 :            :                         rOutBmpEx = checkMetadataBitmap(
     593                 :          0 :                             BitmapEx( pAction->GetBitmap()),
     594                 :            :                             Point(), Size(),
     595                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     596                 :            :                                                 rPrefMapMode ),
     597                 :          0 :                             pAction->GetBitmap().GetSizePixel(),
     598                 :            :                             rSizePix,
     599 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     600                 :            :                     }
     601                 :          0 :                     ++nNumBitmaps;
     602                 :          0 :                     break;
     603                 :            : 
     604                 :            :                 case META_BMPSCALE_ACTION:
     605 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     606                 :            :                     {
     607                 :          0 :                         MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;
     608                 :            : 
     609                 :            :                         rOutBmpEx = checkMetadataBitmap(
     610                 :          0 :                             BitmapEx( pAction->GetBitmap()),
     611                 :            :                             Point(), Size(),
     612                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     613                 :            :                                                 rPrefMapMode ),
     614                 :          0 :                             pOut->LogicToPixel( pAction->GetSize(),
     615                 :            :                                                 rPrefMapMode ),
     616                 :            :                             rSizePix,
     617 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     618                 :            :                     }
     619                 :          0 :                     ++nNumBitmaps;
     620                 :          0 :                     break;
     621                 :            : 
     622                 :            :                 case META_BMPSCALEPART_ACTION:
     623 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     624                 :            :                     {
     625                 :          0 :                         MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;
     626                 :            : 
     627                 :            :                         rOutBmpEx = checkMetadataBitmap(
     628                 :          0 :                                                     BitmapEx( pAction->GetBitmap() ),
     629                 :          0 :                                                     pAction->GetSrcPoint(),
     630                 :          0 :                                                     pAction->GetSrcSize(),
     631                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestPoint(),
     632                 :            :                                                                         rPrefMapMode ),
     633                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestSize(),
     634                 :            :                                                                         rPrefMapMode ),
     635                 :            :                                                     rSizePix,
     636 [ #  # ][ #  # ]:          0 :                                                     bNonBitmapActionEncountered );
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
     637                 :            :                     }
     638                 :          0 :                     ++nNumBitmaps;
     639                 :          0 :                     break;
     640                 :            : 
     641                 :            :                 case META_BMPEX_ACTION:
     642 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     643                 :            :                     {
     644                 :          0 :                         MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;
     645                 :            : 
     646                 :            :                         rOutBmpEx = checkMetadataBitmap(
     647                 :          0 :                             pAction->GetBitmapEx(),
     648                 :            :                             Point(), Size(),
     649                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     650                 :            :                                                 rPrefMapMode ),
     651                 :          0 :                             pAction->GetBitmapEx().GetSizePixel(),
     652                 :            :                             rSizePix,
     653 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
         [ #  # ][ #  # ]
     654                 :            :                     }
     655                 :          0 :                     ++nNumBitmaps;
     656                 :          0 :                     break;
     657                 :            : 
     658                 :            :                 case META_BMPEXSCALE_ACTION:
     659 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     660                 :            :                     {
     661                 :          0 :                         MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;
     662                 :            : 
     663                 :            :                         rOutBmpEx = checkMetadataBitmap(
     664                 :          0 :                             pAction->GetBitmapEx(),
     665                 :            :                             Point(), Size(),
     666                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     667                 :            :                                                 rPrefMapMode ),
     668                 :          0 :                             pOut->LogicToPixel( pAction->GetSize(),
     669                 :            :                                                 rPrefMapMode ),
     670                 :            :                             rSizePix,
     671 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
                 [ #  # ]
           [ #  #  #  # ]
     672                 :            :                     }
     673                 :          0 :                     ++nNumBitmaps;
     674                 :          0 :                     break;
     675                 :            : 
     676                 :            :                 case META_BMPEXSCALEPART_ACTION:
     677 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     678                 :            :                     {
     679                 :          0 :                         MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;
     680                 :            : 
     681                 :          0 :                         rOutBmpEx = checkMetadataBitmap( pAction->GetBitmapEx(),
     682                 :          0 :                                                     pAction->GetSrcPoint(),
     683                 :          0 :                                                     pAction->GetSrcSize(),
     684                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestPoint(),
     685                 :            :                                                                         rPrefMapMode ),
     686                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestSize(),
     687                 :            :                                                                         rPrefMapMode ),
     688                 :            :                                                     rSizePix,
     689 [ #  # ][ #  # ]:          0 :                                                     bNonBitmapActionEncountered );
           [ #  #  #  #  
                   #  # ]
     690                 :            :                     }
     691                 :          0 :                     ++nNumBitmaps;
     692                 :          0 :                     break;
     693                 :            : 
     694                 :            :                     // these actions actually output something (that's
     695                 :            :                     // different from a bitmap)
     696                 :            :                 case META_RASTEROP_ACTION:
     697         [ #  # ]:          0 :                     if( ((MetaRasterOpAction*)pAct)->GetRasterOp() == ROP_OVERPAINT )
     698                 :          0 :                         break;
     699                 :            :                     // FALLTHROUGH intended
     700                 :            :                 case META_PIXEL_ACTION:
     701                 :            :                     // FALLTHROUGH intended
     702                 :            :                 case META_POINT_ACTION:
     703                 :            :                     // FALLTHROUGH intended
     704                 :            :                 case META_LINE_ACTION:
     705                 :            :                     // FALLTHROUGH intended
     706                 :            :                 case META_RECT_ACTION:
     707                 :            :                     // FALLTHROUGH intended
     708                 :            :                 case META_ROUNDRECT_ACTION:
     709                 :            :                     // FALLTHROUGH intended
     710                 :            :                 case META_ELLIPSE_ACTION:
     711                 :            :                     // FALLTHROUGH intended
     712                 :            :                 case META_ARC_ACTION:
     713                 :            :                     // FALLTHROUGH intended
     714                 :            :                 case META_PIE_ACTION:
     715                 :            :                     // FALLTHROUGH intended
     716                 :            :                 case META_CHORD_ACTION:
     717                 :            :                     // FALLTHROUGH intended
     718                 :            :                 case META_POLYLINE_ACTION:
     719                 :            :                     // FALLTHROUGH intended
     720                 :            :                 case META_POLYGON_ACTION:
     721                 :            :                     // FALLTHROUGH intended
     722                 :            :                 case META_POLYPOLYGON_ACTION:
     723                 :            :                     // FALLTHROUGH intended
     724                 :            : 
     725                 :            :                 case META_TEXT_ACTION:
     726                 :            :                     // FALLTHROUGH intended
     727                 :            :                 case META_TEXTARRAY_ACTION:
     728                 :            :                     // FALLTHROUGH intended
     729                 :            :                 case META_STRETCHTEXT_ACTION:
     730                 :            :                     // FALLTHROUGH intended
     731                 :            :                 case META_TEXTRECT_ACTION:
     732                 :            :                     // FALLTHROUGH intended
     733                 :            : 
     734                 :            :                 case META_MASK_ACTION:
     735                 :            :                     // FALLTHROUGH intended
     736                 :            :                 case META_MASKSCALE_ACTION:
     737                 :            :                     // FALLTHROUGH intended
     738                 :            :                 case META_MASKSCALEPART_ACTION:
     739                 :            :                     // FALLTHROUGH intended
     740                 :            : 
     741                 :            :                 case META_GRADIENT_ACTION:
     742                 :            :                     // FALLTHROUGH intended
     743                 :            :                 case META_HATCH_ACTION:
     744                 :            :                     // FALLTHROUGH intended
     745                 :            :                 case META_WALLPAPER_ACTION:
     746                 :            :                     // FALLTHROUGH intended
     747                 :            : 
     748                 :            :                 case META_TRANSPARENT_ACTION:
     749                 :            :                     // FALLTHROUGH intended
     750                 :            :                 case META_EPS_ACTION:
     751                 :            :                     // FALLTHROUGH intended
     752                 :            :                 case META_FLOATTRANSPARENT_ACTION:
     753                 :            :                     // FALLTHROUGH intended
     754                 :            :                 case META_GRADIENTEX_ACTION:
     755                 :            :                     // FALLTHROUGH intended
     756                 :            :                 case META_RENDERGRAPHIC_ACTION:
     757                 :            :                     // FALLTHROUGH intended
     758                 :            : 
     759                 :            :                     // OutDev state changes that _do_ affect bitmap
     760                 :            :                     // output
     761                 :            :                 case META_CLIPREGION_ACTION:
     762                 :            :                     // FALLTHROUGH intended
     763                 :            :                 case META_ISECTRECTCLIPREGION_ACTION:
     764                 :            :                     // FALLTHROUGH intended
     765                 :            :                 case META_ISECTREGIONCLIPREGION_ACTION:
     766                 :            :                     // FALLTHROUGH intended
     767                 :            :                 case META_MOVECLIPREGION_ACTION:
     768                 :            :                     // FALLTHROUGH intended
     769                 :            : 
     770                 :            :                 case META_MAPMODE_ACTION:
     771                 :            :                     // FALLTHROUGH intended
     772                 :            :                 case META_REFPOINT_ACTION:
     773                 :            :                     // FALLTHROUGH intended
     774                 :            :                 default:
     775                 :          0 :                     bNonBitmapActionEncountered = true;
     776                 :          0 :                     break;
     777                 :            :             }
     778         [ #  # ]:          0 :             if ( pModAct )
     779                 :            :             {
     780         [ #  # ]:          0 :                 rOutMtf.ReplaceAction( pModAct, nCurPos );
     781         [ #  # ]:          0 :                 pAct->Delete();
     782                 :            :             }
     783                 :            :             else
     784                 :            :             {
     785         [ #  # ]:          0 :                 if( pAct->GetRefCount() > 1 )
     786                 :            :                 {
     787 [ #  # ][ #  # ]:          0 :                     rOutMtf.ReplaceAction( pModAct = pAct->Clone(), nCurPos );
     788         [ #  # ]:          0 :                     pAct->Delete();
     789                 :            :                 }
     790                 :            :                 else
     791                 :          0 :                     pModAct = pAct;
     792                 :            :             }
     793         [ #  # ]:          0 :             pModAct->Scale( fScaleX, fScaleY );
     794                 :            :         }
     795                 :          0 :         rOutMtf.SetPrefSize( Size( FRound( aNewSize.Width() * fScaleX ),
     796         [ #  # ]:          0 :                                    FRound( aNewSize.Height() * fScaleY ) ) );
     797                 :            :     }
     798                 :            : 
     799 [ #  # ][ #  # ]:          0 :     if( nNumBitmaps != 1 || bNonBitmapActionEncountered )
     800                 :            :     {
     801 [ #  # ][ #  # ]:          0 :         if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsMirrored() || rAttr.IsRotated() || rAttr.IsTransparent() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     802         [ #  # ]:          0 :             ImplAdjust( rOutMtf, rAttr, ADJUSTMENT_ALL );
     803                 :            : 
     804         [ #  # ]:          0 :         ImplDraw( pOut, rPt, rSz, rOutMtf, rAttr );
     805 [ #  # ][ #  # ]:          0 :         rOutBmpEx = BitmapEx();
                 [ #  # ]
     806                 :            :     }
     807                 :            : 
     808                 :          0 :     return sal_True;
     809                 :            : }
     810                 :            : 
     811                 :          0 : void GraphicManager::ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
     812                 :            : {
     813                 :          0 :     GraphicAttr aAttr( rAttr );
     814                 :            : 
     815 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
                 [ #  # ]
     816                 :            :     {
     817   [ #  #  #  # ]:          0 :         switch( aAttr.GetDrawMode() )
     818                 :            :         {
     819                 :            :             case( GRAPHICDRAWMODE_MONO ):
     820         [ #  # ]:          0 :                 rBmpEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
     821                 :          0 :             break;
     822                 :            : 
     823                 :            :             case( GRAPHICDRAWMODE_GREYS ):
     824         [ #  # ]:          0 :                 rBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
     825                 :          0 :             break;
     826                 :            : 
     827                 :            :             case( GRAPHICDRAWMODE_WATERMARK ):
     828                 :            :             {
     829                 :          0 :                 aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
     830                 :          0 :                 aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
     831                 :            :             }
     832                 :          0 :             break;
     833                 :            : 
     834                 :            :             default:
     835                 :          0 :             break;
     836                 :            :         }
     837                 :            :     }
     838                 :            : 
     839 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
                 [ #  # ]
     840                 :            :     {
     841                 :          0 :         rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
     842                 :          0 :                        aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
     843         [ #  # ]:          0 :                        aAttr.GetGamma(), aAttr.IsInvert() );
     844                 :            :     }
     845                 :            : 
     846 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
                 [ #  # ]
     847                 :            :     {
     848         [ #  # ]:          0 :         rBmpEx.Mirror( aAttr.GetMirrorFlags() );
     849                 :            :     }
     850                 :            : 
     851 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
                 [ #  # ]
     852                 :            :     {
     853         [ #  # ]:          0 :         rBmpEx.Rotate( aAttr.GetRotation(), Color( COL_TRANSPARENT ) );
     854                 :            :     }
     855                 :            : 
     856 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
                 [ #  # ]
     857                 :            :     {
     858         [ #  # ]:          0 :         AlphaMask   aAlpha;
     859                 :          0 :         sal_uInt8       cTrans = aAttr.GetTransparency();
     860                 :            : 
     861 [ #  # ][ #  # ]:          0 :         if( !rBmpEx.IsTransparent() )
     862 [ #  # ][ #  # ]:          0 :             aAlpha = AlphaMask( rBmpEx.GetSizePixel(), &cTrans );
                 [ #  # ]
     863 [ #  # ][ #  # ]:          0 :         else if( !rBmpEx.IsAlpha() )
     864                 :            :         {
     865 [ #  # ][ #  # ]:          0 :             aAlpha = rBmpEx.GetMask();
                 [ #  # ]
     866         [ #  # ]:          0 :             aAlpha.Replace( 0, cTrans );
     867                 :            :         }
     868                 :            :         else
     869                 :            :         {
     870 [ #  # ][ #  # ]:          0 :             aAlpha = rBmpEx.GetAlpha();
                 [ #  # ]
     871         [ #  # ]:          0 :             BitmapWriteAccess* pA = aAlpha.AcquireWriteAccess();
     872                 :            : 
     873         [ #  # ]:          0 :             if( pA )
     874                 :            :             {
     875                 :          0 :                 sal_uLong       nTrans = cTrans, nNewTrans;
     876                 :          0 :                 const long  nWidth = pA->Width(), nHeight = pA->Height();
     877                 :            : 
     878         [ #  # ]:          0 :                 if( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     879                 :            :                 {
     880         [ #  # ]:          0 :                     for( long nY = 0; nY < nHeight; nY++ )
     881                 :            :                     {
     882                 :          0 :                         Scanline pAScan = pA->GetScanline( nY );
     883                 :            : 
     884         [ #  # ]:          0 :                         for( long nX = 0; nX < nWidth; nX++ )
     885                 :            :                         {
     886                 :          0 :                             nNewTrans = nTrans + *pAScan;
     887         [ #  # ]:          0 :                             *pAScan++ = (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
     888                 :            :                         }
     889                 :            :                     }
     890                 :            :                 }
     891                 :            :                 else
     892                 :            :                 {
     893                 :          0 :                     BitmapColor aAlphaValue( 0 );
     894                 :            : 
     895         [ #  # ]:          0 :                     for( long nY = 0; nY < nHeight; nY++ )
     896                 :            :                     {
     897         [ #  # ]:          0 :                         for( long nX = 0; nX < nWidth; nX++ )
     898                 :            :                         {
     899         [ #  # ]:          0 :                             nNewTrans = nTrans + pA->GetPixel( nY, nX ).GetIndex();
     900         [ #  # ]:          0 :                             aAlphaValue.SetIndex( (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
     901         [ #  # ]:          0 :                             pA->SetPixel( nY, nX, aAlphaValue );
     902                 :            :                         }
     903                 :          0 :                     }
     904                 :            :                 }
     905                 :            : 
     906         [ #  # ]:          0 :                 aAlpha.ReleaseAccess( pA );
     907                 :            :             }
     908                 :            :         }
     909                 :            : 
     910 [ #  # ][ #  # ]:          0 :         rBmpEx = BitmapEx( rBmpEx.GetBitmap(), aAlpha );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     911         [ #  # ]:          0 :     }
     912                 :          0 : }
     913                 :            : 
     914                 :          0 : void GraphicManager::ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
     915                 :            : {
     916                 :          0 :     GraphicAttr aAttr( rAttr );
     917                 :            : 
     918 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
                 [ #  # ]
     919                 :            :     {
     920   [ #  #  #  # ]:          0 :         switch( aAttr.GetDrawMode() )
     921                 :            :         {
     922                 :            :             case( GRAPHICDRAWMODE_MONO ):
     923         [ #  # ]:          0 :                 rMtf.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
     924                 :          0 :             break;
     925                 :            : 
     926                 :            :             case( GRAPHICDRAWMODE_GREYS ):
     927         [ #  # ]:          0 :                 rMtf.Convert( MTF_CONVERSION_8BIT_GREYS );
     928                 :          0 :             break;
     929                 :            : 
     930                 :            :             case( GRAPHICDRAWMODE_WATERMARK ):
     931                 :            :             {
     932                 :          0 :                 aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
     933                 :          0 :                 aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
     934                 :            :             }
     935                 :          0 :             break;
     936                 :            : 
     937                 :            :             default:
     938                 :          0 :             break;
     939                 :            :         }
     940                 :            :     }
     941                 :            : 
     942 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
                 [ #  # ]
     943                 :            :     {
     944                 :          0 :         rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
     945                 :          0 :                      aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
     946         [ #  # ]:          0 :                      aAttr.GetGamma(), aAttr.IsInvert() );
     947                 :            :     }
     948                 :            : 
     949 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
                 [ #  # ]
     950                 :            :     {
     951         [ #  # ]:          0 :         rMtf.Mirror( aAttr.GetMirrorFlags() );
     952                 :            :     }
     953                 :            : 
     954 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
                 [ #  # ]
     955                 :            :     {
     956         [ #  # ]:          0 :         rMtf.Rotate( aAttr.GetRotation() );
     957                 :            :     }
     958                 :            : 
     959 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
     960                 :            :     {
     961                 :            :         OSL_FAIL( "Missing implementation: Mtf-Transparency" );
     962         [ #  # ]:          0 :     }
     963                 :          0 : }
     964                 :            : 
     965                 :          0 : void GraphicManager::ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, sal_uLong nAdjustmentFlags )
     966                 :            : {
     967                 :          0 :     GraphicAttr aAttr( rAttr );
     968                 :            : 
     969 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
                 [ #  # ]
     970                 :            :     {
     971   [ #  #  #  # ]:          0 :         switch( aAttr.GetDrawMode() )
     972                 :            :         {
     973                 :            :             case( GRAPHICDRAWMODE_MONO ):
     974         [ #  # ]:          0 :                 rAnimation.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
     975                 :          0 :             break;
     976                 :            : 
     977                 :            :             case( GRAPHICDRAWMODE_GREYS ):
     978         [ #  # ]:          0 :                 rAnimation.Convert( BMP_CONVERSION_8BIT_GREYS );
     979                 :          0 :             break;
     980                 :            : 
     981                 :            :             case( GRAPHICDRAWMODE_WATERMARK ):
     982                 :            :             {
     983                 :          0 :                 aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
     984                 :          0 :                 aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
     985                 :            :             }
     986                 :          0 :             break;
     987                 :            : 
     988                 :            :             default:
     989                 :          0 :             break;
     990                 :            :         }
     991                 :            :     }
     992                 :            : 
     993 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
                 [ #  # ]
     994                 :            :     {
     995                 :          0 :         rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
     996                 :          0 :                            aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
     997         [ #  # ]:          0 :                            aAttr.GetGamma(), aAttr.IsInvert() );
     998                 :            :     }
     999                 :            : 
    1000 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
                 [ #  # ]
    1001                 :            :     {
    1002         [ #  # ]:          0 :         rAnimation.Mirror( aAttr.GetMirrorFlags() );
    1003                 :            :     }
    1004                 :            : 
    1005 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
    1006                 :            :     {
    1007                 :            :         OSL_FAIL( "Missing implementation: Animation-Rotation" );
    1008                 :            :     }
    1009                 :            : 
    1010 [ #  # ][ #  # ]:          0 :     if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
    1011                 :            :     {
    1012                 :            :         OSL_FAIL( "Missing implementation: Animation-Transparency" );
    1013         [ #  # ]:          0 :     }
    1014                 :          0 : }
    1015                 :            : 
    1016                 :          0 : void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1017                 :            :                                const GDIMetaFile& rMtf, const GraphicAttr& rAttr )
    1018                 :            : {
    1019                 :          0 :        sal_uInt16   nRot10 = rAttr.GetRotation() % 3600;
    1020                 :          0 :     Point   aOutPt( rPt );
    1021                 :          0 :     Size    aOutSz( rSz );
    1022                 :            : 
    1023         [ #  # ]:          0 :     if( nRot10 )
    1024                 :            :     {
    1025 [ #  # ][ #  # ]:          0 :         Polygon aPoly( Rectangle( aOutPt, aOutSz ) );
    1026                 :            : 
    1027         [ #  # ]:          0 :         aPoly.Rotate( aOutPt, nRot10 );
    1028         [ #  # ]:          0 :         const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
    1029                 :          0 :         aOutPt = aRotBoundRect.TopLeft();
    1030 [ #  # ][ #  # ]:          0 :         aOutSz = aRotBoundRect.GetSize();
    1031                 :            :     }
    1032                 :            : 
    1033         [ #  # ]:          0 :     pOut->Push( PUSH_CLIPREGION );
    1034 [ #  # ][ #  # ]:          0 :     pOut->IntersectClipRegion( Rectangle( aOutPt, aOutSz ) );
    1035                 :            : 
    1036         [ #  # ]:          0 :     ( (GDIMetaFile&) rMtf ).WindStart();
    1037         [ #  # ]:          0 :     ( (GDIMetaFile&) rMtf ).Play( pOut, aOutPt, aOutSz );
    1038         [ #  # ]:          0 :     ( (GDIMetaFile&) rMtf ).WindStart();
    1039                 :            : 
    1040         [ #  # ]:          0 :     pOut->Pop();
    1041                 :          0 : }
    1042                 :            : 
    1043                 :            : struct ImplTileInfo
    1044                 :            : {
    1045                 :          0 :     ImplTileInfo() : aTileTopLeft(), aNextTileTopLeft(), aTileSizePixel(), nTilesEmptyX(0), nTilesEmptyY(0) {}
    1046                 :            : 
    1047                 :            :     Point aTileTopLeft;     // top, left position of the rendered tile
    1048                 :            :     Point aNextTileTopLeft; // top, left position for next recursion
    1049                 :            :                             // level's tile
    1050                 :            :     Size  aTileSizePixel;   // size of the generated tile (might
    1051                 :            :                             // differ from
    1052                 :            :                             // aNextTileTopLeft-aTileTopLeft, because
    1053                 :            :                             // this is nExponent*prevTileSize. The
    1054                 :            :                             // generated tile is always nExponent
    1055                 :            :                             // times the previous tile, such that it
    1056                 :            :                             // can be used in the next stage. The
    1057                 :            :                             // required area coverage is often
    1058                 :            :                             // less. The extraneous area covered is
    1059                 :            :                             // later overwritten by the next stage)
    1060                 :            :     int   nTilesEmptyX;     // number of original tiles empty right of
    1061                 :            :                             // this tile. This counts from
    1062                 :            :                             // aNextTileTopLeft, i.e. the additional
    1063                 :            :                             // area covered by aTileSizePixel is not
    1064                 :            :                             // considered here. This is for
    1065                 :            :                             // unification purposes, as the iterative
    1066                 :            :                             // calculation of the next level's empty
    1067                 :            :                             // tiles has to be based on this value.
    1068                 :            :     int   nTilesEmptyY;     // as above, for Y
    1069                 :            : };
    1070                 :            : 
    1071                 :            : 
    1072                 :          0 : bool GraphicObject::ImplRenderTempTile( VirtualDevice& rVDev, int nExponent,
    1073                 :            :                                         int nNumTilesX, int nNumTilesY,
    1074                 :            :                                         const Size& rTileSizePixel,
    1075                 :            :                                         const GraphicAttr* pAttr, sal_uLong nFlags )
    1076                 :            : {
    1077         [ #  # ]:          0 :     if( nExponent <= 1 )
    1078                 :          0 :         return false;
    1079                 :            : 
    1080                 :            :     // determine MSB factor
    1081                 :          0 :     int nMSBFactor( 1 );
    1082 [ #  # ][ #  # ]:          0 :     while( nNumTilesX / nMSBFactor != 0 ||
                 [ #  # ]
    1083                 :            :            nNumTilesY / nMSBFactor != 0 )
    1084                 :            :     {
    1085                 :          0 :         nMSBFactor *= nExponent;
    1086                 :            :     }
    1087                 :            : 
    1088                 :            :     // one less
    1089                 :          0 :     nMSBFactor /= nExponent;
    1090                 :            : 
    1091                 :          0 :     ImplTileInfo aTileInfo;
    1092                 :            : 
    1093                 :            :     // #105229# Switch off mapping (converting to logic and back to
    1094                 :            :     // pixel might cause roundoff errors)
    1095                 :          0 :     sal_Bool bOldMap( rVDev.IsMapModeEnabled() );
    1096         [ #  # ]:          0 :     rVDev.EnableMapMode( sal_False );
    1097                 :            : 
    1098                 :            :     bool bRet( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor, nNumTilesX, nNumTilesY,
    1099         [ #  # ]:          0 :                                         nNumTilesX, nNumTilesY, rTileSizePixel, pAttr, nFlags, aTileInfo ) );
    1100                 :            : 
    1101         [ #  # ]:          0 :     rVDev.EnableMapMode( bOldMap );
    1102                 :            : 
    1103                 :          0 :     return bRet;
    1104                 :            : }
    1105                 :            : 
    1106                 :            : // define for debug drawings
    1107                 :            : //#define DBG_TEST
    1108                 :            : 
    1109                 :            : // see header comment. this works similar to base conversion of a
    1110                 :            : // number, i.e. if the exponent is 10, then the number for every tile
    1111                 :            : // size is given by the decimal place of the corresponding decimal
    1112                 :            : // representation.
    1113                 :          0 : bool GraphicObject::ImplRenderTileRecursive( VirtualDevice& rVDev, int nExponent, int nMSBFactor,
    1114                 :            :                                              int nNumOrigTilesX, int nNumOrigTilesY,
    1115                 :            :                                              int nRemainderTilesX, int nRemainderTilesY,
    1116                 :            :                                              const Size& rTileSizePixel, const GraphicAttr* pAttr,
    1117                 :            :                                              sal_uLong nFlags, ImplTileInfo& rTileInfo )
    1118                 :            : {
    1119                 :            :     // gets loaded with our tile bitmap
    1120         [ #  # ]:          0 :     GraphicObject aTmpGraphic;
    1121                 :            : 
    1122                 :            :     // stores a flag that renders the zero'th tile position
    1123                 :            :     // (i.e. (0,0)+rCurrPos) only if we're at the bottom of the
    1124                 :            :     // recursion stack. All other position already have that tile
    1125                 :            :     // rendered, because the lower levels painted their generated tile
    1126                 :            :     // there.
    1127                 :          0 :     bool bNoFirstTileDraw( false );
    1128                 :            : 
    1129                 :            :     // what's left when we're done with our tile size
    1130                 :          0 :     const int nNewRemainderX( nRemainderTilesX % nMSBFactor );
    1131                 :          0 :     const int nNewRemainderY( nRemainderTilesY % nMSBFactor );
    1132                 :            : 
    1133                 :            :     // gets filled out from the recursive call with info of what's
    1134                 :            :     // been generated
    1135                 :          0 :     ImplTileInfo aTileInfo;
    1136                 :            : 
    1137                 :            :     // current output position while drawing
    1138                 :          0 :     Point aCurrPos;
    1139                 :            :     int nX, nY;
    1140                 :            : 
    1141                 :            :     // check for recursion's end condition: LSB place reached?
    1142         [ #  # ]:          0 :     if( nMSBFactor == 1 )
    1143                 :            :     {
    1144         [ #  # ]:          0 :         aTmpGraphic = *this;
    1145                 :            : 
    1146                 :            :         // set initial tile size -> orig size
    1147                 :          0 :         aTileInfo.aTileSizePixel = rTileSizePixel;
    1148                 :          0 :         aTileInfo.nTilesEmptyX = nNumOrigTilesX;
    1149                 :          0 :         aTileInfo.nTilesEmptyY = nNumOrigTilesY;
    1150                 :            :     }
    1151 [ #  # ][ #  # ]:          0 :     else if( ImplRenderTileRecursive( rVDev, nExponent, nMSBFactor/nExponent,
    1152                 :            :                                       nNumOrigTilesX, nNumOrigTilesY,
    1153                 :            :                                       nNewRemainderX, nNewRemainderY,
    1154                 :          0 :                                       rTileSizePixel, pAttr, nFlags, aTileInfo ) )
    1155                 :            :     {
    1156                 :            :         // extract generated tile -> see comment on the first loop below
    1157 [ #  # ][ #  # ]:          0 :         BitmapEx aTileBitmap( rVDev.GetBitmap( aTileInfo.aTileTopLeft, aTileInfo.aTileSizePixel ) );
                 [ #  # ]
    1158                 :            : 
    1159 [ #  # ][ #  # ]:          0 :         aTmpGraphic = GraphicObject( aTileBitmap );
         [ #  # ][ #  # ]
                 [ #  # ]
    1160                 :            : 
    1161                 :            :         // fill stripes left over from upstream levels:
    1162                 :            :         //
    1163                 :            :         //  x0000
    1164                 :            :         //  0
    1165                 :            :         //  0
    1166                 :            :         //  0
    1167                 :            :         //  0
    1168                 :            :         //
    1169                 :            :         // where x denotes the place filled by our recursive predecessors
    1170                 :            : 
    1171                 :            :         // check whether we have to fill stripes here. Although not
    1172                 :            :         // obvious, there is one case where we can skip this step: if
    1173                 :            :         // the previous recursion level (the one who filled our
    1174                 :            :         // aTileInfo) had zero area to fill, then there are no white
    1175                 :            :         // stripes left, naturally. This happens if the digit
    1176                 :            :         // associated to that level has a zero, and can be checked via
    1177                 :            :         // aTileTopLeft==aNextTileTopLeft.
    1178         [ #  # ]:          0 :         if( aTileInfo.aTileTopLeft != aTileInfo.aNextTileTopLeft )
    1179                 :            :         {
    1180                 :            :             // now fill one row from aTileInfo.aNextTileTopLeft.X() all
    1181                 :            :             // the way to the right
    1182                 :          0 :             aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();
    1183                 :          0 :             aCurrPos.Y() = aTileInfo.aTileTopLeft.Y();
    1184         [ #  # ]:          0 :             for( nX=0; nX < aTileInfo.nTilesEmptyX; nX += nMSBFactor )
    1185                 :            :             {
    1186 [ #  # ][ #  # ]:          0 :                 if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
    1187                 :          0 :                     return false;
    1188                 :            : 
    1189                 :          0 :                 aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
    1190                 :            :             }
    1191                 :            : 
    1192                 :            : #ifdef DBG_TEST
    1193                 :            : //          rVDev.SetFillColor( COL_WHITE );
    1194                 :            :             rVDev.SetFillColor();
    1195                 :            :             rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
    1196                 :            :             rVDev.DrawEllipse( Rectangle(aTileInfo.aNextTileTopLeft.X(), aTileInfo.aTileTopLeft.Y(),
    1197                 :            :                                          aTileInfo.aNextTileTopLeft.X() - 1 + (aTileInfo.nTilesEmptyX/nMSBFactor)*aTileInfo.aTileSizePixel.Width(),
    1198                 :            :                                          aTileInfo.aTileTopLeft.Y() + aTileInfo.aTileSizePixel.Height() - 1) );
    1199                 :            : #endif
    1200                 :            : 
    1201                 :            :             // now fill one column from aTileInfo.aNextTileTopLeft.Y() all
    1202                 :            :             // the way to the bottom
    1203                 :          0 :             aCurrPos.X() = aTileInfo.aTileTopLeft.X();
    1204                 :          0 :             aCurrPos.Y() = aTileInfo.aNextTileTopLeft.Y();
    1205         [ #  # ]:          0 :             for( nY=0; nY < aTileInfo.nTilesEmptyY; nY += nMSBFactor )
    1206                 :            :             {
    1207 [ #  # ][ #  # ]:          0 :                 if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
    1208                 :          0 :                     return false;
    1209                 :            : 
    1210                 :          0 :                 aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
    1211                 :            :             }
    1212                 :            : 
    1213                 :            : #ifdef DBG_TEST
    1214                 :            :             rVDev.DrawEllipse( Rectangle(aTileInfo.aTileTopLeft.X(), aTileInfo.aNextTileTopLeft.Y(),
    1215                 :            :                                          aTileInfo.aTileTopLeft.X() + aTileInfo.aTileSizePixel.Width() - 1,
    1216                 :            :                                          aTileInfo.aNextTileTopLeft.Y() - 1 + (aTileInfo.nTilesEmptyY/nMSBFactor)*aTileInfo.aTileSizePixel.Height()) );
    1217                 :            : #endif
    1218                 :            :         }
    1219                 :            :         else
    1220                 :            :         {
    1221                 :            :             // Thought that aTileInfo.aNextTileTopLeft tile has always
    1222                 :            :             // been drawn already, but that's wrong: typically,
    1223                 :            :             // _parts_ of that tile have been drawn, since the
    1224                 :            :             // previous level generated the tile there. But when
    1225                 :            :             // aTileInfo.aNextTileTopLeft!=aTileInfo.aTileTopLeft, the
    1226                 :            :             // difference between these two values is missing in the
    1227                 :            :             // lower right corner of this first tile. So, can do that
    1228                 :            :             // only here.
    1229                 :          0 :             bNoFirstTileDraw = true;
    1230 [ #  # ][ #  # ]:          0 :         }
    1231                 :            :     }
    1232                 :            :     else
    1233                 :            :     {
    1234                 :          0 :         return false;
    1235                 :            :     }
    1236                 :            : 
    1237                 :            :     // calc number of original tiles in our drawing area without
    1238                 :            :     // remainder
    1239                 :          0 :     nRemainderTilesX -= nNewRemainderX;
    1240                 :          0 :     nRemainderTilesY -= nNewRemainderY;
    1241                 :            : 
    1242                 :            :     // fill tile info for calling method
    1243                 :          0 :     rTileInfo.aTileTopLeft     = aTileInfo.aNextTileTopLeft;
    1244                 :          0 :     rTileInfo.aNextTileTopLeft = Point( rTileInfo.aTileTopLeft.X() + rTileSizePixel.Width()*nRemainderTilesX,
    1245                 :          0 :                                         rTileInfo.aTileTopLeft.Y() + rTileSizePixel.Height()*nRemainderTilesY );
    1246                 :          0 :     rTileInfo.aTileSizePixel   = Size( rTileSizePixel.Width()*nMSBFactor*nExponent,
    1247                 :          0 :                                        rTileSizePixel.Height()*nMSBFactor*nExponent );
    1248                 :          0 :     rTileInfo.nTilesEmptyX     = aTileInfo.nTilesEmptyX - nRemainderTilesX;
    1249                 :          0 :     rTileInfo.nTilesEmptyY     = aTileInfo.nTilesEmptyY - nRemainderTilesY;
    1250                 :            : 
    1251                 :            :     // init output position
    1252                 :          0 :     aCurrPos = aTileInfo.aNextTileTopLeft;
    1253                 :            : 
    1254                 :            :     // fill our drawing area. Fill possibly more, to create the next
    1255                 :            :     // bigger tile size -> see bitmap extraction above. This does no
    1256                 :            :     // harm, since everything right or below our actual area is
    1257                 :            :     // overdrawn by our caller. Just in case we're in the last level,
    1258                 :            :     // we don't draw beyond the right or bottom border.
    1259 [ #  # ][ #  # ]:          0 :     for( nY=0; nY < aTileInfo.nTilesEmptyY && nY < nExponent*nMSBFactor; nY += nMSBFactor )
                 [ #  # ]
    1260                 :            :     {
    1261                 :          0 :         aCurrPos.X() = aTileInfo.aNextTileTopLeft.X();
    1262                 :            : 
    1263 [ #  # ][ #  # ]:          0 :         for( nX=0; nX < aTileInfo.nTilesEmptyX && nX < nExponent*nMSBFactor; nX += nMSBFactor )
                 [ #  # ]
    1264                 :            :         {
    1265         [ #  # ]:          0 :             if( bNoFirstTileDraw )
    1266                 :          0 :                 bNoFirstTileDraw = false; // don't draw first tile position
    1267 [ #  # ][ #  # ]:          0 :             else if( !aTmpGraphic.Draw( &rVDev, aCurrPos, aTileInfo.aTileSizePixel, pAttr, nFlags ) )
    1268                 :          0 :                 return false;
    1269                 :            : 
    1270                 :          0 :             aCurrPos.X() += aTileInfo.aTileSizePixel.Width();
    1271                 :            :         }
    1272                 :            : 
    1273                 :          0 :         aCurrPos.Y() += aTileInfo.aTileSizePixel.Height();
    1274                 :            :     }
    1275                 :            : 
    1276                 :            : #ifdef DBG_TEST
    1277                 :            : //  rVDev.SetFillColor( COL_WHITE );
    1278                 :            :     rVDev.SetFillColor();
    1279                 :            :     rVDev.SetLineColor( Color( 255 * nExponent / nMSBFactor, 255 - 255 * nExponent / nMSBFactor, 128 - 255 * nExponent / nMSBFactor ) );
    1280                 :            :     rVDev.DrawRect( Rectangle((rTileInfo.aTileTopLeft.X())*rTileSizePixel.Width(),
    1281                 :            :                               (rTileInfo.aTileTopLeft.Y())*rTileSizePixel.Height(),
    1282                 :            :                               (rTileInfo.aNextTileTopLeft.X())*rTileSizePixel.Width()-1,
    1283                 :            :                               (rTileInfo.aNextTileTopLeft.Y())*rTileSizePixel.Height()-1) );
    1284                 :            : #endif
    1285                 :            : 
    1286         [ #  # ]:          0 :     return true;
    1287                 :            : }
    1288                 :            : 
    1289                 :          0 : bool GraphicObject::ImplDrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSizePixel,
    1290                 :            :                                    const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D )
    1291                 :            : {
    1292                 :            :     // how many tiles to generate per recursion step
    1293                 :            :     enum{ SubdivisionExponent=2 };
    1294                 :            : 
    1295         [ #  # ]:          0 :     const MapMode   aOutMapMode( pOut->GetMapMode() );
    1296         [ #  # ]:          0 :     const MapMode   aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
    1297                 :          0 :     bool            bRet( false );
    1298                 :            : 
    1299                 :            :     // #i42643# Casting to Int64, to avoid integer overflow for
    1300                 :            :     // huge-DPI output devices
    1301 [ #  # ][ #  # ]:          0 :     if( GetGraphic().GetType() == GRAPHIC_BITMAP &&
           [ #  #  #  # ]
                 [ #  # ]
    1302                 :          0 :         static_cast<sal_Int64>(rSizePixel.Width()) * rSizePixel.Height() <
    1303                 :            :         static_cast<sal_Int64>(nTileCacheSize1D)*nTileCacheSize1D )
    1304                 :            :     {
    1305                 :            :         // First combine very small bitmaps into a larger tile
    1306                 :            :         // ===================================================
    1307                 :            : 
    1308         [ #  # ]:          0 :         VirtualDevice   aVDev;
    1309                 :          0 :         const int       nNumTilesInCacheX( (nTileCacheSize1D + rSizePixel.Width()-1) / rSizePixel.Width() );
    1310                 :          0 :         const int       nNumTilesInCacheY( (nTileCacheSize1D + rSizePixel.Height()-1) / rSizePixel.Height() );
    1311                 :            : 
    1312                 :          0 :         aVDev.SetOutputSizePixel( Size( nNumTilesInCacheX*rSizePixel.Width(),
    1313         [ #  # ]:          0 :                                         nNumTilesInCacheY*rSizePixel.Height() ) );
    1314         [ #  # ]:          0 :         aVDev.SetMapMode( aMapMode );
    1315                 :            : 
    1316                 :            :         // draw bitmap content
    1317 [ #  # ][ #  # ]:          0 :         if( ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
    1318                 :            :                                 nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
    1319                 :            :         {
    1320 [ #  # ][ #  # ]:          0 :             BitmapEx aTileBitmap( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) );
         [ #  # ][ #  # ]
    1321                 :            : 
    1322                 :            :             // draw alpha content, if any
    1323         [ #  # ]:          0 :             if( IsTransparent() )
    1324                 :            :             {
    1325         [ #  # ]:          0 :                 GraphicObject aAlphaGraphic;
    1326                 :            : 
    1327 [ #  # ][ #  # ]:          0 :                 if( GetGraphic().IsAlpha() )
                 [ #  # ]
    1328 [ #  # ][ #  # ]:          0 :                     aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetAlpha().GetBitmap() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1329                 :            :                 else
    1330 [ #  # ][ #  # ]:          0 :                     aAlphaGraphic.SetGraphic( GetGraphic().GetBitmapEx().GetMask() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1331                 :            : 
    1332 [ #  # ][ #  # ]:          0 :                 if( aAlphaGraphic.ImplRenderTempTile( aVDev, SubdivisionExponent, nNumTilesInCacheX,
    1333                 :            :                                                       nNumTilesInCacheY, rSizePixel, pAttr, nFlags ) )
    1334                 :            :                 {
    1335                 :            :                     // Combine bitmap and alpha/mask
    1336 [ #  # ][ #  # ]:          0 :                     if( GetGraphic().IsAlpha() )
                 [ #  # ]
    1337                 :            :                         aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
    1338 [ #  # ][ #  # ]:          0 :                                                 AlphaMask( aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ) ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1339                 :            :                     else
    1340                 :            :                         aTileBitmap = BitmapEx( aTileBitmap.GetBitmap(),
    1341 [ #  # ][ #  # ]:          0 :                                                 aVDev.GetBitmap( Point(0,0), aVDev.GetOutputSize() ).CreateMask( Color(COL_WHITE) ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1342         [ #  # ]:          0 :                 }
    1343                 :            :             }
    1344                 :            : 
    1345                 :            :             // paint generated tile
    1346 [ #  # ][ #  # ]:          0 :             GraphicObject aTmpGraphic( aTileBitmap );
                 [ #  # ]
    1347                 :            :             bRet = aTmpGraphic.ImplDrawTiled( pOut, rArea,
    1348                 :          0 :                                               aTileBitmap.GetSizePixel(),
    1349 [ #  # ][ #  # ]:          0 :                                               rOffset, pAttr, nFlags, nTileCacheSize1D );
                 [ #  # ]
    1350         [ #  # ]:          0 :         }
    1351                 :            :     }
    1352                 :            :     else
    1353                 :            :     {
    1354         [ #  # ]:          0 :         const Size      aOutOffset( pOut->LogicToPixel( rOffset, aOutMapMode ) );
    1355         [ #  # ]:          0 :         const Rectangle aOutArea( pOut->LogicToPixel( rArea, aOutMapMode ) );
    1356                 :            : 
    1357                 :            :         // number of invisible (because out-of-area) tiles
    1358                 :            :         int nInvisibleTilesX;
    1359                 :            :         int nInvisibleTilesY;
    1360                 :            : 
    1361                 :            :         // round towards -infty for negative offset
    1362         [ #  # ]:          0 :         if( aOutOffset.Width() < 0 )
    1363                 :          0 :             nInvisibleTilesX = (aOutOffset.Width() - rSizePixel.Width() + 1) / rSizePixel.Width();
    1364                 :            :         else
    1365                 :          0 :             nInvisibleTilesX = aOutOffset.Width() / rSizePixel.Width();
    1366                 :            : 
    1367                 :            :         // round towards -infty for negative offset
    1368         [ #  # ]:          0 :         if( aOutOffset.Height() < 0 )
    1369                 :          0 :             nInvisibleTilesY = (aOutOffset.Height() - rSizePixel.Height() + 1) / rSizePixel.Height();
    1370                 :            :         else
    1371                 :          0 :             nInvisibleTilesY = aOutOffset.Height() / rSizePixel.Height();
    1372                 :            : 
    1373                 :            :         // origin from where to 'virtually' start drawing in pixel
    1374                 :          0 :         const Point aOutOrigin( pOut->LogicToPixel( Point( rArea.Left() - rOffset.Width(),
    1375         [ #  # ]:          0 :                                                            rArea.Top() - rOffset.Height() ) ) );
    1376                 :            :         // position in pixel from where to really start output
    1377                 :          0 :         const Point aOutStart( aOutOrigin.X() + nInvisibleTilesX*rSizePixel.Width(),
    1378                 :          0 :                                aOutOrigin.Y() + nInvisibleTilesY*rSizePixel.Height() );
    1379                 :            : 
    1380         [ #  # ]:          0 :         pOut->Push( PUSH_CLIPREGION );
    1381         [ #  # ]:          0 :         pOut->IntersectClipRegion( rArea );
    1382                 :            : 
    1383                 :            :         // Paint all tiles
    1384                 :            :         // ===============
    1385                 :            : 
    1386                 :            :         bRet = ImplDrawTiled( *pOut, aOutStart,
    1387         [ #  # ]:          0 :                               (aOutArea.GetWidth() + aOutArea.Left() - aOutStart.X() + rSizePixel.Width() - 1) / rSizePixel.Width(),
    1388         [ #  # ]:          0 :                               (aOutArea.GetHeight() + aOutArea.Top() - aOutStart.Y() + rSizePixel.Height() - 1) / rSizePixel.Height(),
    1389         [ #  # ]:          0 :                               rSizePixel, pAttr, nFlags );
    1390                 :            : 
    1391         [ #  # ]:          0 :         pOut->Pop();
    1392                 :            :     }
    1393                 :            : 
    1394 [ #  # ][ #  # ]:          0 :     return bRet;
    1395                 :            : }
    1396                 :            : 
    1397                 :          0 : bool GraphicObject::ImplDrawTiled( OutputDevice& rOut, const Point& rPosPixel,
    1398                 :            :                                    int nNumTilesX, int nNumTilesY,
    1399                 :            :                                    const Size& rTileSizePixel, const GraphicAttr* pAttr, sal_uLong nFlags )
    1400                 :            : {
    1401                 :          0 :     Point   aCurrPos( rPosPixel );
    1402         [ #  # ]:          0 :     Size    aTileSizeLogic( rOut.PixelToLogic( rTileSizePixel ) );
    1403                 :            :     int     nX, nY;
    1404                 :            : 
    1405                 :            :     // #107607# Use logical coordinates for metafile playing, too
    1406 [ #  # ][ #  # ]:          0 :     bool    bDrawInPixel( rOut.GetConnectMetaFile() == NULL && GRAPHIC_BITMAP == GetType() );
    1407                 :          0 :     bool    bRet = false;
    1408                 :            : 
    1409                 :            :     // #105229# Switch off mapping (converting to logic and back to
    1410                 :            :     // pixel might cause roundoff errors)
    1411                 :          0 :     bool bOldMap( rOut.IsMapModeEnabled() );
    1412                 :            : 
    1413         [ #  # ]:          0 :     if( bDrawInPixel )
    1414         [ #  # ]:          0 :         rOut.EnableMapMode( sal_False );
    1415                 :            : 
    1416         [ #  # ]:          0 :     for( nY=0; nY < nNumTilesY; ++nY )
    1417                 :            :     {
    1418                 :          0 :         aCurrPos.X() = rPosPixel.X();
    1419                 :            : 
    1420         [ #  # ]:          0 :         for( nX=0; nX < nNumTilesX; ++nX )
    1421                 :            :         {
    1422                 :            :             // #105229# work with pixel coordinates here, mapping is disabled!
    1423                 :            :             // #104004# don't disable mapping for metafile recordings
    1424                 :            :             // #108412# don't quit the loop if one draw fails
    1425                 :            : 
    1426                 :            :             // update return value. This method should return true, if
    1427                 :            :             // at least one of the looped Draws succeeded.
    1428                 :            :             bRet |= Draw( &rOut,
    1429                 :            :                           bDrawInPixel ? aCurrPos : rOut.PixelToLogic( aCurrPos ),
    1430                 :            :                           bDrawInPixel ? rTileSizePixel : aTileSizeLogic,
    1431 [ #  # ][ #  # ]:          0 :                           pAttr, nFlags );
         [ #  # ][ #  # ]
    1432                 :            : 
    1433                 :          0 :             aCurrPos.X() += rTileSizePixel.Width();
    1434                 :            :         }
    1435                 :            : 
    1436                 :          0 :         aCurrPos.Y() += rTileSizePixel.Height();
    1437                 :            :     }
    1438                 :            : 
    1439         [ #  # ]:          0 :     if( bDrawInPixel )
    1440         [ #  # ]:          0 :         rOut.EnableMapMode( bOldMap );
    1441                 :            : 
    1442                 :          0 :     return bRet;
    1443                 :            : }
    1444                 :            : 
    1445                 :          0 : void GraphicObject::ImplTransformBitmap( BitmapEx&          rBmpEx,
    1446                 :            :                                          const GraphicAttr& rAttr,
    1447                 :            :                                          const Size&        rCropLeftTop,
    1448                 :            :                                          const Size&        rCropRightBottom,
    1449                 :            :                                          const Rectangle&   rCropRect,
    1450                 :            :                                          const Size&        rDstSize,
    1451                 :            :                                          sal_Bool               bEnlarge ) const
    1452                 :            : {
    1453                 :            :     // #107947# Extracted from svdograf.cxx
    1454                 :            : 
    1455                 :            :     // #104115# Crop the bitmap
    1456         [ #  # ]:          0 :     if( rAttr.IsCropped() )
    1457                 :            :     {
    1458         [ #  # ]:          0 :         rBmpEx.Crop( rCropRect );
    1459                 :            : 
    1460                 :            :         // #104115# Negative crop sizes mean: enlarge bitmap and pad
    1461   [ #  #  #  #  :          0 :         if( bEnlarge && (
          #  #  #  #  #  
              # ][ #  # ]
    1462                 :          0 :             rCropLeftTop.Width() < 0 ||
    1463                 :          0 :             rCropLeftTop.Height() < 0 ||
    1464                 :          0 :             rCropRightBottom.Width() < 0 ||
    1465                 :          0 :             rCropRightBottom.Height() < 0 ) )
    1466                 :            :         {
    1467                 :          0 :             Size aBmpSize( rBmpEx.GetSizePixel() );
    1468         [ #  # ]:          0 :             sal_Int32 nPadLeft( rCropLeftTop.Width() < 0 ? -rCropLeftTop.Width() : 0 );
    1469         [ #  # ]:          0 :             sal_Int32 nPadTop( rCropLeftTop.Height() < 0 ? -rCropLeftTop.Height() : 0 );
    1470         [ #  # ]:          0 :             sal_Int32 nPadTotalWidth( aBmpSize.Width() + nPadLeft + (rCropRightBottom.Width() < 0 ? -rCropRightBottom.Width() : 0) );
    1471         [ #  # ]:          0 :             sal_Int32 nPadTotalHeight( aBmpSize.Height() + nPadTop + (rCropRightBottom.Height() < 0 ? -rCropRightBottom.Height() : 0) );
    1472                 :            : 
    1473         [ #  # ]:          0 :             BitmapEx aBmpEx2;
    1474                 :            : 
    1475 [ #  # ][ #  # ]:          0 :             if( rBmpEx.IsTransparent() )
    1476                 :            :             {
    1477 [ #  # ][ #  # ]:          0 :                 if( rBmpEx.IsAlpha() )
    1478 [ #  # ][ #  # ]:          0 :                     aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetAlpha() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1479                 :            :                 else
    1480 [ #  # ][ #  # ]:          0 :                     aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), rBmpEx.GetMask() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1481                 :            :             }
    1482                 :            :             else
    1483                 :            :             {
    1484                 :            :                 // #104115# Generate mask bitmap and init to zero
    1485         [ #  # ]:          0 :                 Bitmap aMask( aBmpSize, 1 );
    1486         [ #  # ]:          0 :                 aMask.Erase( Color(0,0,0) );
    1487                 :            : 
    1488                 :            :                 // #104115# Always generate transparent bitmap, we need the border transparent
    1489 [ #  # ][ #  # ]:          0 :                 aBmpEx2 = BitmapEx( rBmpEx.GetBitmap(), aMask );
         [ #  # ][ #  # ]
                 [ #  # ]
    1490                 :            : 
    1491                 :            :                 // #104115# Add opaque mask to source bitmap, otherwise the destination remains transparent
    1492 [ #  # ][ #  # ]:          0 :                 rBmpEx = aBmpEx2;
    1493                 :            :             }
    1494                 :            : 
    1495         [ #  # ]:          0 :             aBmpEx2.SetSizePixel( Size(nPadTotalWidth, nPadTotalHeight) );
    1496         [ #  # ]:          0 :             aBmpEx2.Erase( Color(0xFF,0,0,0) );
    1497 [ #  # ][ #  # ]:          0 :             aBmpEx2.CopyPixel( Rectangle( Point(nPadLeft, nPadTop), aBmpSize ), Rectangle( Point(0, 0), aBmpSize ), &rBmpEx );
                 [ #  # ]
    1498 [ #  # ][ #  # ]:          0 :             rBmpEx = aBmpEx2;
    1499                 :            :         }
    1500                 :            :     }
    1501                 :            : 
    1502                 :          0 :     const Size  aSizePixel( rBmpEx.GetSizePixel() );
    1503                 :            : 
    1504 [ #  # ][ #  # ]:          0 :     if( rAttr.GetRotation() != 0 && !IsAnimated() )
                 [ #  # ]
    1505                 :            :     {
    1506 [ #  # ][ #  # ]:          0 :         if( aSizePixel.Width() && aSizePixel.Height() && rDstSize.Width() && rDstSize.Height() )
         [ #  # ][ #  # ]
                 [ #  # ]
    1507                 :            :         {
    1508                 :          0 :             double fSrcWH = (double) aSizePixel.Width() / aSizePixel.Height();
    1509                 :          0 :             double fDstWH = (double) rDstSize.Width() / rDstSize.Height();
    1510                 :          0 :             double fScaleX = 1.0, fScaleY = 1.0;
    1511                 :            : 
    1512                 :            :             // always choose scaling to shrink bitmap
    1513         [ #  # ]:          0 :             if( fSrcWH < fDstWH )
    1514                 :          0 :                 fScaleY = aSizePixel.Width() / ( fDstWH * aSizePixel.Height() );
    1515                 :            :             else
    1516                 :          0 :                 fScaleX = fDstWH * aSizePixel.Height() / aSizePixel.Width();
    1517                 :            : 
    1518         [ #  # ]:          0 :             rBmpEx.Scale( fScaleX, fScaleY );
    1519                 :            :         }
    1520                 :            :     }
    1521                 :          0 : }
    1522                 :            : 
    1523                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10